origen 0.31.0 → 0.32.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/version.rb +1 -1
- data/lib/origen/application/runner.rb +1 -0
- data/lib/origen/clocks/clock.rb +63 -44
- data/lib/origen/commands/web.rb +5 -1
- data/lib/origen/file_handler.rb +3 -2
- data/lib/origen/generator/pattern.rb +16 -5
- data/lib/origen/limits/limit.rb +126 -0
- data/lib/origen/limits/limit_set.rb +120 -0
- data/lib/origen/limits.rb +37 -0
- data/lib/origen/model/exporter.rb +36 -22
- data/lib/origen/model.rb +6 -0
- data/lib/origen/parameters.rb +12 -0
- data/lib/origen/registers/bit_collection.rb +16 -3
- data/lib/origen/remote_manager.rb +48 -5
- data/lib/origen/revision_control/base.rb +9 -0
- data/lib/origen/revision_control/perforce.rb +110 -0
- data/lib/origen/revision_control.rb +3 -0
- data/lib/origen/specs/checkers.rb +0 -3
- data/lib/origen/sub_blocks.rb +3 -1
- data/lib/origen/tests/test.rb +3 -0
- data/lib/origen.rb +2 -0
- data/templates/git/gitignore.erb +3 -0
- data/vendor/lib/models/origen/export1/block1.rb +1 -1
- data/vendor/lib/models/origen/export1.rb +3 -1
- metadata +27 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b636bd97c227eecf2344ccbdc17e29712953325
|
4
|
+
data.tar.gz: cd69d451f85313509d2a2c4a31887cbf81fb57c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e104a65bd531b7e52ec7f9f74d002b822d004fb0c46556e412392c3b874101a8be06c27fd83bb05e35acad5fa3b2c62251d9ba729a5de08dc472004ffd11b57
|
7
|
+
data.tar.gz: dc29b4f3a4567780af525fc9b023bae374af3d71ed96f241e294ae35aba9d241009f4496d4c7f25c112dca0a8d3978b3f6223b378488b8dc967bbabff6501af6
|
data/config/version.rb
CHANGED
@@ -79,6 +79,7 @@ module Origen
|
|
79
79
|
else
|
80
80
|
if options[:action] == :program
|
81
81
|
Origen.generator.generate_program(expand_lists_and_directories(options[:files], options), options)
|
82
|
+
Origen.app.listeners_for(:program_generated).each(&:program_generated)
|
82
83
|
else
|
83
84
|
temporary_plugin_from_options = options[:current_plugin]
|
84
85
|
expand_lists_and_directories(options[:files], options).each do |file|
|
data/lib/origen/clocks/clock.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
module Origen
|
2
2
|
module Clocks
|
3
3
|
class Clock
|
4
|
-
attr_accessor :id, :owner, :users, :
|
4
|
+
attr_accessor :id, :owner, :users, :freq_target, :freq_range, :setpoint, :instantiate_users
|
5
5
|
|
6
6
|
def initialize(id, owner, options = {}, &block)
|
7
7
|
@id = id
|
8
8
|
@owner = owner
|
9
9
|
@id = @id.symbolize unless id.is_a? Symbol
|
10
|
+
@instantiate_users = true
|
10
11
|
options.each { |k, v| instance_variable_set("@#{k}", v) }
|
11
12
|
(block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
|
12
13
|
@users = [@users] unless @users.is_a? Array
|
13
|
-
instantiate_users
|
14
|
+
add_users_sub_blocks if @instantiate_users
|
15
|
+
@setpoint = @freq_target
|
14
16
|
end
|
15
17
|
|
16
18
|
def name
|
@@ -21,29 +23,30 @@ module Origen
|
|
21
23
|
def users
|
22
24
|
@users
|
23
25
|
end
|
24
|
-
alias_method :ips, :users
|
25
|
-
alias_method :sub_blocks, :users
|
26
26
|
|
27
27
|
def setpoint=(val)
|
28
|
-
|
29
|
-
|
28
|
+
if val == :gated || val == 'gated'
|
29
|
+
@setpoint = :gated
|
30
|
+
else
|
31
|
+
setpoint_ok?(val) # This just warns if the clock is set out of range
|
32
|
+
@setpoint = val
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
def setpoint_ok?(val = nil)
|
33
|
-
|
34
|
-
if freq_range == :fixed
|
35
|
-
if val
|
37
|
+
val = @setpoint if val.nil?
|
38
|
+
if @freq_range == :fixed
|
39
|
+
if val == @freq_target
|
36
40
|
return true
|
37
41
|
else
|
38
|
-
Origen.log.warn("Clock '#{id}' is a fixed clock with a
|
42
|
+
Origen.log.warn("Clock '#{id}' is a fixed clock with a target frequency of #{@freq_target.as_Hz}")
|
39
43
|
return false
|
40
44
|
end
|
41
45
|
else
|
42
|
-
|
43
|
-
if freq_range.include?(val)
|
46
|
+
if @freq_range.include?(val)
|
44
47
|
return true
|
45
48
|
else
|
46
|
-
Origen.log.warn("Setpoint (#{setpoint_string(val)}) for clock '#{id}' is not within the frequency range (#{freq_range_string})
|
49
|
+
Origen.log.warn("Setpoint (#{setpoint_string(val)}) for clock '#{id}' is not within the frequency range (#{freq_range_string})")
|
47
50
|
return false
|
48
51
|
end
|
49
52
|
end
|
@@ -51,17 +54,10 @@ module Origen
|
|
51
54
|
alias_method :value_ok?, :setpoint_ok?
|
52
55
|
alias_method :val_ok?, :setpoint_ok?
|
53
56
|
|
54
|
-
# Set the clock to the
|
55
|
-
def
|
56
|
-
@setpoint =
|
57
|
-
end
|
58
|
-
|
59
|
-
# Nominal frequency
|
60
|
-
def nominal_frequency
|
61
|
-
@nominal_frequency
|
57
|
+
# Set the clock to the target frequency
|
58
|
+
def setpoint_to_target
|
59
|
+
@setpoint = @freq_target
|
62
60
|
end
|
63
|
-
alias_method :nominal, :nominal_frequency
|
64
|
-
alias_method :nom, :nominal_frequency
|
65
61
|
|
66
62
|
# Current setpoint, defaults top nil on init
|
67
63
|
def setpoint
|
@@ -71,11 +67,34 @@ module Origen
|
|
71
67
|
alias_method :value, :setpoint
|
72
68
|
|
73
69
|
# Acceptable frequency range
|
74
|
-
def
|
75
|
-
@
|
70
|
+
def freq_range
|
71
|
+
@freq_range
|
72
|
+
end
|
73
|
+
alias_method :range, :freq_range
|
74
|
+
|
75
|
+
# Acceptable frequency range
|
76
|
+
def freq_target
|
77
|
+
@freq_target
|
78
|
+
end
|
79
|
+
alias_method :target, :freq_target
|
80
|
+
|
81
|
+
# min method
|
82
|
+
def min
|
83
|
+
if @freq_range == :fixed
|
84
|
+
@freq_target
|
85
|
+
else
|
86
|
+
@freq_range.first
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# max method
|
91
|
+
def max
|
92
|
+
if @freq_range == :fixed
|
93
|
+
@freq_target
|
94
|
+
else
|
95
|
+
@freq_range.last
|
96
|
+
end
|
76
97
|
end
|
77
|
-
alias_method :freq_range, :frequency_range
|
78
|
-
alias_method :range, :frequency_range
|
79
98
|
|
80
99
|
# Check if the clock users are defined anywhere in the DUT
|
81
100
|
def users_defined?
|
@@ -108,12 +127,12 @@ module Origen
|
|
108
127
|
private
|
109
128
|
|
110
129
|
# Instantiate and IP/users that use/access the clock
|
111
|
-
def
|
112
|
-
users.each do |ip|
|
113
|
-
if owner.respond_to? ip
|
130
|
+
def add_users_sub_blocks
|
131
|
+
@users.each do |ip|
|
132
|
+
if @owner.respond_to? ip
|
114
133
|
next
|
115
134
|
else
|
116
|
-
owner.sub_block ip
|
135
|
+
@owner.sub_block ip
|
117
136
|
end
|
118
137
|
end
|
119
138
|
end
|
@@ -130,20 +149,20 @@ module Origen
|
|
130
149
|
end
|
131
150
|
|
132
151
|
def frequencies_ok?
|
133
|
-
if
|
152
|
+
if @freq_target.nil?
|
134
153
|
false
|
135
|
-
elsif
|
154
|
+
elsif @freq_range.nil?
|
136
155
|
Origen.log.error("Missing frequency range for clock '#{name}'!")
|
137
156
|
false
|
138
|
-
elsif
|
139
|
-
if
|
157
|
+
elsif freq_range.is_a? Range
|
158
|
+
if freq_range.include?(@freq_target)
|
140
159
|
true
|
141
160
|
else
|
142
|
-
Origen.log.error("PPEKit:
|
161
|
+
Origen.log.error("PPEKit: Frequency target #{@freq_target} is not inbetween the frequency range #{freq_range} for clock '#{name}'!")
|
143
162
|
false
|
144
163
|
end
|
145
164
|
else
|
146
|
-
Origen.log.error("Clock attribute '
|
165
|
+
Origen.log.error("Clock attribute 'freq_range' must be a Range!")
|
147
166
|
return_value = false
|
148
167
|
end
|
149
168
|
end
|
@@ -157,24 +176,24 @@ module Origen
|
|
157
176
|
end
|
158
177
|
|
159
178
|
def freq_range_string
|
160
|
-
start_freq = freq_range.first
|
161
|
-
end_freq = freq_range.last
|
179
|
+
start_freq = @freq_range.first
|
180
|
+
end_freq = @freq_range.last
|
162
181
|
"#{start_freq.as_Hz}\.\.#{end_freq.as_Hz}"
|
163
182
|
end
|
164
183
|
|
165
184
|
def clock_freqs_ok?
|
166
|
-
if
|
185
|
+
if @freq_target.nil?
|
167
186
|
false
|
168
|
-
elsif freq_range == :fixed
|
187
|
+
elsif @freq_range == :fixed
|
169
188
|
true
|
170
189
|
else
|
171
|
-
if freq_range.nil?
|
190
|
+
if @freq_range.nil?
|
172
191
|
Origen.log.error("PPEKit: Missing frequency target or range for clock '#{id}'!")
|
173
192
|
false
|
174
|
-
elsif freq_range.include?(
|
193
|
+
elsif @freq_range.include?(@freq_target)
|
175
194
|
true
|
176
195
|
else
|
177
|
-
Origen.log.error("PPEKit: Frequency target #{
|
196
|
+
Origen.log.error("PPEKit: Frequency target #{@freq_target} is not inbetween the freq range #{@freq_range} for clock '#{id}'!")
|
178
197
|
false
|
179
198
|
end
|
180
199
|
end
|
data/lib/origen/commands/web.rb
CHANGED
@@ -92,7 +92,11 @@ The following options are available:
|
|
92
92
|
server.close
|
93
93
|
# Start the server
|
94
94
|
puts ''
|
95
|
-
|
95
|
+
if host.include? domain
|
96
|
+
puts "Point your browser to this address: http://#{host}:#{port}"
|
97
|
+
else
|
98
|
+
puts "Point your browser to this address: http://#{host}#{domain.empty? ? '' : '.' + domain}:#{port}"
|
99
|
+
end
|
96
100
|
puts ''
|
97
101
|
puts 'To shut down the server use CTRL-C'
|
98
102
|
puts ''
|
data/lib/origen/file_handler.rb
CHANGED
@@ -210,9 +210,10 @@ module Origen
|
|
210
210
|
file = inject_import_path(file, type: :template)
|
211
211
|
file = add_underscore_to(file)
|
212
212
|
file = add_extension_to(file)
|
213
|
+
web_file = file =~ /\.(html|md)(\.|$)/
|
213
214
|
begin
|
214
215
|
# Allow relative references to templates/web when compiling a web template
|
215
|
-
if Origen.lsf.current_command == 'web'
|
216
|
+
if Origen.lsf.current_command == 'web' || web_file
|
216
217
|
clean_path_to(file, load_paths: "#{Origen.root}/templates/web")
|
217
218
|
else
|
218
219
|
clean_path_to(file)
|
@@ -220,7 +221,7 @@ module Origen
|
|
220
221
|
rescue
|
221
222
|
# Try again without .erb
|
222
223
|
file = file.gsub('.erb', '')
|
223
|
-
if Origen.lsf.current_command == 'web'
|
224
|
+
if Origen.lsf.current_command == 'web' || web_file
|
224
225
|
clean_path_to(file, load_paths: "#{Origen.root}/templates/web")
|
225
226
|
else
|
226
227
|
clean_path_to(file)
|
@@ -349,10 +349,21 @@ module Origen
|
|
349
349
|
|
350
350
|
unless options[:inhibit] || !Origen.tester.generate? || job.test?
|
351
351
|
stats.collect_for_pattern(job.output_pattern) do
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
352
|
+
# If the tester is going to deal with writing out the final pattern. The use case for this is when
|
353
|
+
# the pattern is comprised of multiple files instead of the more conventional case here which each
|
354
|
+
# pattern is one file.
|
355
|
+
if tester.respond_to?(:open_and_write_pattern)
|
356
|
+
tester.open_and_write_pattern(job.output_pattern) do
|
357
|
+
[:header, :body, :footer].each do |section|
|
358
|
+
Origen.tester.format(stage.bank(section), section)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
else
|
362
|
+
File.open(job.output_pattern, 'w') do |f|
|
363
|
+
[:header, :body, :footer].each do |section|
|
364
|
+
Origen.tester.format(stage.bank(section), section) do |line|
|
365
|
+
f.puts line
|
366
|
+
end
|
356
367
|
end
|
357
368
|
end
|
358
369
|
end
|
@@ -362,7 +373,7 @@ module Origen
|
|
362
373
|
log.info "Pattern vectors: #{stats.number_of_vectors_for(job.output_pattern).to_s.ljust(10)}"
|
363
374
|
log.info 'Execution time'.ljust(15) + ': %.6f' % stats.execution_time_for(job.output_pattern)
|
364
375
|
log.info '----------------------------------------------------------------------'
|
365
|
-
check_for_changes(job.output_pattern, job.reference_pattern)
|
376
|
+
check_for_changes(job.output_pattern, job.reference_pattern) unless tester.try(:disable_pattern_diffs)
|
366
377
|
stats.record_pattern_completion(job.output_pattern)
|
367
378
|
end
|
368
379
|
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Origen
|
2
|
+
module Limits
|
3
|
+
class Limit
|
4
|
+
attr_accessor :expr, :value, :owner, :type
|
5
|
+
|
6
|
+
def initialize(expr, type, owner, options = {})
|
7
|
+
@expr = expr
|
8
|
+
@owner = owner
|
9
|
+
@type = type
|
10
|
+
@value = evaluate_expr
|
11
|
+
end
|
12
|
+
|
13
|
+
# If the value is still a String then it could be
|
14
|
+
# due to referencing another LimitSet that is
|
15
|
+
# yet to be defined
|
16
|
+
def value
|
17
|
+
if @value.is_a?(String)
|
18
|
+
evaluate_expr
|
19
|
+
else
|
20
|
+
@value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Backwards compatibility
|
25
|
+
def exp
|
26
|
+
@expr
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def fetch_reference_value(ref)
|
32
|
+
ref = ref.to_sym unless ref.is_a?(Symbol)
|
33
|
+
# Check if the reference is to another limit set
|
34
|
+
if owner.limits.include? ref
|
35
|
+
return owner.limits(ref).send(type).value
|
36
|
+
# Check if the reference is to a power domain
|
37
|
+
end
|
38
|
+
if Origen.top_level.respond_to? :power_domains
|
39
|
+
if Origen.top_level.power_domains.include? ref
|
40
|
+
# Need to check the limit type and retrieve the appropriate value
|
41
|
+
case @type.to_s
|
42
|
+
when /target|typ/
|
43
|
+
return Origen.top_level.power_domains(ref).nominal_voltage
|
44
|
+
else
|
45
|
+
return Origen.top_level.power_domains(ref).send(@type)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# Check if the reference is to a clock
|
50
|
+
if Origen.top_level.respond_to? :clocks
|
51
|
+
if Origen.top_level.clocks.include? ref
|
52
|
+
# Need to check the limit type and retrieve the appropriate value
|
53
|
+
case @type.to_s
|
54
|
+
when /target|typ/
|
55
|
+
return Origen.top_level.clocks(ref).freq_target
|
56
|
+
else
|
57
|
+
return Origen.top_level.clocks(ref).send(@type)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def evaluate_expr
|
64
|
+
return @expr if @expr.is_a?(Numeric)
|
65
|
+
return nil if @expr.nil?
|
66
|
+
if @expr.is_a? Symbol
|
67
|
+
@expr = ':' + @expr.to_s
|
68
|
+
else
|
69
|
+
@expr.gsub!("\n", ' ')
|
70
|
+
@expr.scrub!
|
71
|
+
end
|
72
|
+
result = false
|
73
|
+
if @expr.match(/\:\S+/)
|
74
|
+
limit_items = @expr.split(/\:|\s+/).reject(&:empty?)
|
75
|
+
if limit_items.size == 1
|
76
|
+
return fetch_reference_value(limit_items.first)
|
77
|
+
else
|
78
|
+
references = @expr.split(/\:|\s+/).select { |var| var.match(/^[a-zA-Z]\S+$/) }
|
79
|
+
new_limit_items = [].tap do |limit_ary|
|
80
|
+
limit_items.each do |item|
|
81
|
+
if references.include? item
|
82
|
+
limit_ary << fetch_reference_value(item)
|
83
|
+
next
|
84
|
+
else
|
85
|
+
limit_ary << item
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
new_limit = new_limit_items.join(' ')
|
90
|
+
new_limit_references = new_limit.split(/\:|\s+/).select { |var| var.match(/^[a-zA-Z]\S+$/) }
|
91
|
+
if new_limit_references.empty?
|
92
|
+
result = eval(new_limit).round(4)
|
93
|
+
else
|
94
|
+
return @expr
|
95
|
+
end
|
96
|
+
end
|
97
|
+
elsif !!(@expr.match(/^\d+\.\d+$/)) || !!(@expr.match(/^-\d+\.\d+$/))
|
98
|
+
result = Float(@expr).round(4) rescue false # rubocop:disable Style/RescueModifier
|
99
|
+
elsif !!(@expr.match(/\d+\.\d+\s+\d+\.\d+/))
|
100
|
+
Origen.log.debug "Found two numbers without an operator in the @expr string '#{@expr}', choosing the first..."
|
101
|
+
first_number = @expr.match(/(\d+\.\d+)\s+\d+\.\d+/).captures.first
|
102
|
+
result = Float(first_number).round(4) rescue false # rubocop:disable Style/RescueModifier
|
103
|
+
else
|
104
|
+
result = Integer(@expr) rescue false # rubocop:disable Style/RescueModifier
|
105
|
+
end
|
106
|
+
if result == false
|
107
|
+
# Attempt to eval the @expr because users could write a @expr like "3.3 + 50.mV"
|
108
|
+
# which would not work with the code above but should eval to a number 3.35
|
109
|
+
begin
|
110
|
+
result = eval(@expr)
|
111
|
+
return result.round(4) if result.is_a? Numeric
|
112
|
+
rescue ::SyntaxError, ::NameError, ::TypeError
|
113
|
+
Origen.log.debug "Limit '#{@expr}' had to be rescued, storing it as a #{@expr.class}"
|
114
|
+
if @expr.is_a? Symbol
|
115
|
+
return @expr
|
116
|
+
else
|
117
|
+
return "#{@expr}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
else
|
121
|
+
return result
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative './limit'
|
2
|
+
module Origen
|
3
|
+
module Limits
|
4
|
+
class LimitSet
|
5
|
+
attr_accessor :id, :min, :typ, :max, :target, :description, :static, :owner, :type
|
6
|
+
|
7
|
+
def initialize(id, owner, options)
|
8
|
+
@id = id
|
9
|
+
@description = options[:description]
|
10
|
+
@owner = owner
|
11
|
+
@min = Limit.new(options[:min], :min, @owner) unless options[:min].nil?
|
12
|
+
@typ = Limit.new(options[:typ], :typ, @owner) unless options[:typ].nil?
|
13
|
+
@max = Limit.new(options[:max], :max, @owner) unless options[:max].nil?
|
14
|
+
@target = Limit.new(options[:target], :target, @owner) unless options[:target].nil?
|
15
|
+
unless options[:static].nil?
|
16
|
+
unless [true, false].include? options[:static]
|
17
|
+
Origen.log.error("Static option must be set to 'true' or 'false'!")
|
18
|
+
fail
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@static = options[:static].nil? ? false : options[:static]
|
22
|
+
fail unless limits_ok?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Common alias
|
26
|
+
def name
|
27
|
+
@id
|
28
|
+
end
|
29
|
+
|
30
|
+
def frozen?
|
31
|
+
@static
|
32
|
+
end
|
33
|
+
|
34
|
+
def min=(val)
|
35
|
+
if frozen?
|
36
|
+
Origen.log.warn('Cannot change a frozen limit set!')
|
37
|
+
else
|
38
|
+
@min = Limit.new(val, :min, @owner)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def max=(val)
|
43
|
+
if frozen?
|
44
|
+
Origen.log.warn('Cannot change a frozen limit set!')
|
45
|
+
else
|
46
|
+
@max = Limit.new(val, :max, @owner)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def typ=(val)
|
51
|
+
if frozen?
|
52
|
+
Origen.log.warn('Cannot change a frozen limit set!')
|
53
|
+
else
|
54
|
+
@typ = Limit.new(val, :typ, @owner)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def target=(val)
|
59
|
+
if frozen?
|
60
|
+
Origen.log.warn('Cannot change a frozen limit set!')
|
61
|
+
else
|
62
|
+
@target = Limit.new(val, :target, @owner)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Check that min, max are not mixed with typ. If a user wants
|
69
|
+
# a baseline value for a spec use target as it will not be
|
70
|
+
# checked against pass/fail
|
71
|
+
def limits_ok?
|
72
|
+
status = true
|
73
|
+
# Must have at least one of the limit types defined
|
74
|
+
if @min.nil? && @max.nil? && @typ.nil? && @target.nil?
|
75
|
+
Origen.log.error("Limit set #{@id} does not have any limits defined!")
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
if @min.nil? ^ @max.nil?
|
79
|
+
@type = :single_sided
|
80
|
+
unless @typ.nil?
|
81
|
+
status = false
|
82
|
+
Origen.log.error "Limit set #{@id} has a typical limit defined with either min or max. They are mutually exclusive, use 'target' when using min or max"
|
83
|
+
end
|
84
|
+
# Check if the target is OK
|
85
|
+
unless @target.nil?
|
86
|
+
if @min.nil?
|
87
|
+
unless @target < @max
|
88
|
+
status = false
|
89
|
+
Origen.log.error("Limit set #{@id} has the target value #{@target} set greater than the max value #{@max}!")
|
90
|
+
end
|
91
|
+
else
|
92
|
+
unless @target > @min
|
93
|
+
status = false
|
94
|
+
Origen.log.error("Limit set #{@id} has the target value #{@target} set less than the min value #{@min}!")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
elsif @min.expr && @max.expr
|
99
|
+
@type = :double_sided
|
100
|
+
# Both min and max must be numerical to compare them
|
101
|
+
if @min.value.is_a?(Numeric) && @max.value.is_a?(Numeric)
|
102
|
+
# Check that min and max make sense
|
103
|
+
if @max.value <= @min.value || @min.value >= @max.value
|
104
|
+
status = false
|
105
|
+
Origen.log.error "Limit set #{@id} has min (#{@min.value}) and max (#{@max.value}) reversed"
|
106
|
+
end
|
107
|
+
# Check that target is OK
|
108
|
+
unless @target.nil?
|
109
|
+
if @target.value <= @min.value || @target.value >= @max.value
|
110
|
+
status = false
|
111
|
+
Origen.log.error "Limit set #{@id} has a target (#{@target.value}) that is not within the min (#{@min.value}) and max #{@max.value}) values"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
status
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative './limits/limit'
|
2
|
+
require_relative './limits/limit_set'
|
3
|
+
module Origen
|
4
|
+
module Limits
|
5
|
+
TYPES = [:min, :typ, :max, :target]
|
6
|
+
|
7
|
+
def add_limits(set, options)
|
8
|
+
@_limits ||= {}
|
9
|
+
options.ids.each do |limit_type|
|
10
|
+
unless TYPES.include? limit_type
|
11
|
+
Origen.log.error("Limit type '#{limit_type}' not supported, choose from #{TYPES}!")
|
12
|
+
fail
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if @_limits.include? set
|
16
|
+
# Limit set already exists, modify it unless it is frozen
|
17
|
+
unless @_limits[set].frozen?
|
18
|
+
options.each do |limit_type, limit_expr|
|
19
|
+
@_limits[set].send("#{limit_type}=", limit_expr)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
else
|
23
|
+
# Create a default limit set
|
24
|
+
@_limits[set] = LimitSet.new(set, self, options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def limits(set = nil)
|
29
|
+
@_limits ||= {}
|
30
|
+
if set.nil?
|
31
|
+
@_limits
|
32
|
+
else
|
33
|
+
@_limits[set]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -11,16 +11,13 @@ module Origen
|
|
11
11
|
}.merge(options)
|
12
12
|
# file_path is for internal use, don't pass it from the application, use the :dir option if you
|
13
13
|
# want to change where the exported files are
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
FileUtils.rm_rf(file.to_s) if File.exist?(file.to_s)
|
22
|
-
FileUtils.mkdir_p(file.dirname)
|
23
|
-
File.open(file, 'w') do |f|
|
14
|
+
file = options[:file_path] || export_path(name, options)
|
15
|
+
dir = options[:dir_path] || export_dir(options)
|
16
|
+
path_to_file = Pathname.new(File.join(dir, file))
|
17
|
+
FileUtils.rm_rf(path_to_file.sub_ext('').to_s) if File.exist?(path_to_file.sub_ext('').to_s)
|
18
|
+
FileUtils.rm_rf(path_to_file.to_s) if File.exist?(path_to_file.to_s)
|
19
|
+
FileUtils.mkdir_p(path_to_file.dirname)
|
20
|
+
File.open(path_to_file, 'w') do |f|
|
24
21
|
export_wrap_with_namespaces(f, options) do |indent|
|
25
22
|
f.puts((' ' * indent) + 'def self.extended(model)')
|
26
23
|
indent += 2
|
@@ -51,12 +48,15 @@ module Origen
|
|
51
48
|
ground_pin_groups.each do |id, pins|
|
52
49
|
f.puts export_pin_group(id, pins, indent: indent, method: :add_ground_pin_group)
|
53
50
|
end
|
51
|
+
virtual_pins.each do |id, pin|
|
52
|
+
f.puts export_pin(id, pin, indent: indent, method: :add_virtual_pin)
|
53
|
+
end
|
54
54
|
f.puts
|
55
55
|
end
|
56
56
|
end
|
57
57
|
if options[:include_sub_blocks]
|
58
58
|
sub_blocks.each do |name, block|
|
59
|
-
f.puts export_sub_block(name, block, options.merge(indent: indent, file_path: file))
|
59
|
+
f.puts export_sub_block(name, block, options.merge(indent: indent, file_path: file, dir_path: dir))
|
60
60
|
end
|
61
61
|
f.puts unless sub_blocks.empty?
|
62
62
|
end
|
@@ -74,10 +74,18 @@ module Origen
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def import(name, options = {})
|
77
|
-
path = export_path(name, options)
|
77
|
+
path = File.join(export_dir(options), export_path(name, options))
|
78
78
|
if File.exist?(path)
|
79
79
|
require path
|
80
|
-
|
80
|
+
if options.key?(:namespace) && !options[:namespace]
|
81
|
+
extend name.to_s.gsub('.', '_').camelcase.constantize
|
82
|
+
else
|
83
|
+
if options[:namespace]
|
84
|
+
extend "#{options[:namespace].to_s.gsub('.', '_').camelcase}::#{name.to_s.gsub('.', '_').camelcase}".constantize
|
85
|
+
else
|
86
|
+
extend "#{Origen.app.namespace}::#{name.to_s.gsub('.', '_').camelcase}".constantize
|
87
|
+
end
|
88
|
+
end
|
81
89
|
true
|
82
90
|
else
|
83
91
|
if options[:allow_missing]
|
@@ -143,16 +151,16 @@ module Origen
|
|
143
151
|
if n == ''
|
144
152
|
nil
|
145
153
|
else
|
146
|
-
n.camelcase
|
154
|
+
n.to_s.gsub('.', '_').camelcase
|
147
155
|
end
|
148
156
|
end.compact
|
149
157
|
end
|
150
158
|
|
151
159
|
def export_path(name, options = {})
|
152
160
|
if options.key?(:namespace) && !options[:namespace]
|
153
|
-
|
161
|
+
"#{name.to_s.underscore}.rb"
|
154
162
|
else
|
155
|
-
File.join(
|
163
|
+
File.join((options[:namespace] || Origen.app.namespace).to_s.underscore, "#{name.to_s.underscore}.rb")
|
156
164
|
end
|
157
165
|
end
|
158
166
|
|
@@ -173,8 +181,11 @@ module Origen
|
|
173
181
|
line << ", #{pkg_meta}" unless pkg_meta == ''
|
174
182
|
Array(options[:attributes]).each do |attr|
|
175
183
|
unless (v = pin.send(attr)).nil?
|
176
|
-
|
184
|
+
case v
|
185
|
+
when Numeric, Array, Hash
|
177
186
|
line << ", #{attr}: #{v}"
|
187
|
+
when Symbol
|
188
|
+
line << ", #{attr}: :#{v}"
|
178
189
|
else
|
179
190
|
line << ", #{attr}: '#{v}'"
|
180
191
|
end
|
@@ -183,8 +194,11 @@ module Origen
|
|
183
194
|
unless pin.meta.empty?
|
184
195
|
line << ', meta: { '
|
185
196
|
line << pin.meta.map do |k, v|
|
186
|
-
|
197
|
+
case v
|
198
|
+
when Numeric, Array, Hash
|
187
199
|
"#{k}: #{v}"
|
200
|
+
when Symbol
|
201
|
+
"#{k}: :#{v}"
|
188
202
|
else
|
189
203
|
"#{k}: '#{v}'"
|
190
204
|
end
|
@@ -208,9 +222,9 @@ module Origen
|
|
208
222
|
|
209
223
|
def export_sub_block(id, block, options = {})
|
210
224
|
indent = ' ' * (options[:indent] || 0)
|
211
|
-
|
212
|
-
|
213
|
-
line = indent + "model.sub_block :#{id}, file: '#{
|
225
|
+
file_path = File.join(Pathname.new(options[:file_path]).sub_ext(''), "#{id}.rb")
|
226
|
+
dir_path = options[:dir_path]
|
227
|
+
line = indent + "model.sub_block :#{id}, file: '#{file_path}', dir: '#{dir_path}', lazy: true"
|
214
228
|
unless block.base_address == 0
|
215
229
|
line << ", base_address: #{block.base_address.to_hex}"
|
216
230
|
end
|
@@ -223,7 +237,7 @@ module Origen
|
|
223
237
|
line << ", #{key}: #{value}"
|
224
238
|
end
|
225
239
|
end
|
226
|
-
block.export(id, options.merge(file_path:
|
240
|
+
block.export(id, options.merge(file_path: file_path, dir_path: dir_path))
|
227
241
|
line
|
228
242
|
end
|
229
243
|
|
data/lib/origen/model.rb
CHANGED
@@ -34,6 +34,7 @@ module Origen
|
|
34
34
|
include Origen::Clocks
|
35
35
|
include Origen::Model::Exporter
|
36
36
|
include Origen::Component
|
37
|
+
include Origen::Limits
|
37
38
|
end
|
38
39
|
|
39
40
|
module ClassMethods
|
@@ -205,6 +206,7 @@ module Origen
|
|
205
206
|
unless top_level?
|
206
207
|
# Need to do this in case a class besides SubBlock includes Origen::Model
|
207
208
|
obj_above_self = parent.nil? ? Origen.top_level : parent
|
209
|
+
return nil if obj_above_self.nil?
|
208
210
|
if obj_above_self.current_mode
|
209
211
|
_modes[obj_above_self.current_mode.id] if _modes.include? obj_above_self.current_mode.id
|
210
212
|
end
|
@@ -216,6 +218,10 @@ module Origen
|
|
216
218
|
# Set the current mode configuration of the current model
|
217
219
|
def current_mode=(id)
|
218
220
|
@current_mode = id.is_a?(ChipMode) ? id.id : id
|
221
|
+
Origen.app.listeners_for(:on_mode_changed).each do |listener|
|
222
|
+
listener.on_mode_changed(mode: @current_mode)
|
223
|
+
end
|
224
|
+
@current_mode
|
219
225
|
end
|
220
226
|
alias_method :mode=, :current_mode=
|
221
227
|
|
data/lib/origen/parameters.rb
CHANGED
@@ -69,6 +69,18 @@ module Origen
|
|
69
69
|
_parameter_sets.empty? ? false : true
|
70
70
|
end
|
71
71
|
|
72
|
+
# Return value of param if it exists, nil otherwise.
|
73
|
+
def param?(name)
|
74
|
+
_param = name.to_s =~ /^params./ ? name.to_s : 'params.' + name.to_s
|
75
|
+
begin
|
76
|
+
val = eval("self.#{_param}")
|
77
|
+
rescue
|
78
|
+
nil
|
79
|
+
else
|
80
|
+
val
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
72
84
|
# @api private
|
73
85
|
def _parameter_current
|
74
86
|
if path = self.class.parameters_context
|
@@ -109,9 +109,22 @@ module Origen
|
|
109
109
|
v = tester.capture do
|
110
110
|
store!(sync: true)
|
111
111
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
112
|
+
if v.first
|
113
|
+
# Serial shift
|
114
|
+
if v.size == 1
|
115
|
+
reverse_shift_out_with_index do |bit, i|
|
116
|
+
bit.instance_variable_set('@updated_post_reset', true)
|
117
|
+
bit.instance_variable_set('@data', v.first[i])
|
118
|
+
end
|
119
|
+
# Parallel shift
|
120
|
+
else
|
121
|
+
reverse_shift_out_with_index do |bit, i|
|
122
|
+
bit.instance_variable_set('@updated_post_reset', true)
|
123
|
+
bit.instance_variable_set('@data', v[i].to_i)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
else
|
127
|
+
Origen.log.warning "No data was captured when attempting to sync register #{owner.name}, this is probably because the current read_register driver method does not implement store requests"
|
115
128
|
end
|
116
129
|
end
|
117
130
|
if size
|
@@ -119,8 +119,47 @@ module Origen
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
+
# Fetches any defined remotes, regardless of whether they are dirty or not
|
123
|
+
def resolve_remotes!
|
124
|
+
resolve_remotes
|
125
|
+
process_remotes
|
126
|
+
end
|
127
|
+
|
122
128
|
private
|
123
129
|
|
130
|
+
# Process each remote
|
131
|
+
def process_remotes
|
132
|
+
remotes.each do |_name, remote|
|
133
|
+
dir = workspace_of(remote)
|
134
|
+
rc_url = remote[:rc_url] || remote[:vault]
|
135
|
+
tag = remote[:tag].nil? ? Origen::VersionString.new(remote[:version]) : Origen::VersionString.new(remote[:tag])
|
136
|
+
version_file = dir.to_s + '/.current_version'
|
137
|
+
begin
|
138
|
+
if File.exist?("#{dir}/.initial_populate_successful")
|
139
|
+
FileUtils.rm_f(version_file) if File.exist?(version_file)
|
140
|
+
rc = RevisionControl.new remote: rc_url, local: dir
|
141
|
+
rc.send rc.remotes_method, version: prefix_tag(tag), force: true
|
142
|
+
File.open(version_file, 'w') do |f|
|
143
|
+
f.write tag
|
144
|
+
end
|
145
|
+
else
|
146
|
+
rc = RevisionControl.new remote: rc_url, local: dir
|
147
|
+
rc.send rc.remotes_method, version: prefix_tag(tag), force: true
|
148
|
+
FileUtils.touch "#{dir}/.initial_populate_successful"
|
149
|
+
File.open(version_file, 'w') do |f|
|
150
|
+
f.write tag
|
151
|
+
end
|
152
|
+
end
|
153
|
+
rescue Origen::GitError, Origen::DesignSyncError, Origen::PerforceError => e
|
154
|
+
# If Git failed in the remote, its usually easy to see what the problem is, but now *where* it is.
|
155
|
+
# This will prepend the failing remote along with the error from the revision control system,
|
156
|
+
# then rethrow the error
|
157
|
+
e.message.prepend "When updating remotes for #{remote[:importer].name}: "
|
158
|
+
raise e
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
124
163
|
# Returns the name of the given import (a lower cased symbol)
|
125
164
|
def name_of(remote)
|
126
165
|
dir_defined?(remote)
|
@@ -243,6 +282,11 @@ module Origen
|
|
243
282
|
# * If multiple versions of the same remote are found the most
|
244
283
|
# recent one wins.
|
245
284
|
def add_remote(new)
|
285
|
+
# Cannot have both a tag and a version defined for a remote
|
286
|
+
if ([:tag, :version] - new.keys).empty?
|
287
|
+
Origen.log.error('Cannot define both a tag and a version for a remote!')
|
288
|
+
fail
|
289
|
+
end
|
246
290
|
name = name_of(new)
|
247
291
|
# If the current remote has been imported by one of it's dev dependencies
|
248
292
|
# then always use the local workspace
|
@@ -289,28 +333,27 @@ module Origen
|
|
289
333
|
end
|
290
334
|
if remote[:path]
|
291
335
|
create_symlink(remote[:path], dir)
|
292
|
-
|
293
336
|
else
|
294
337
|
rc_url = remote[:rc_url] || remote[:vault]
|
295
|
-
tag = Origen::VersionString.new(remote[:version])
|
338
|
+
tag = remote[:tag].nil? ? Origen::VersionString.new(remote[:version]) : Origen::VersionString.new(remote[:tag])
|
296
339
|
version_file = dir.to_s + '/.current_version'
|
297
340
|
begin
|
298
341
|
if File.exist?("#{dir}/.initial_populate_successful")
|
299
342
|
FileUtils.rm_f(version_file) if File.exist?(version_file)
|
300
343
|
rc = RevisionControl.new remote: rc_url, local: dir
|
301
|
-
rc.
|
344
|
+
rc.send rc.remotes_method, version: prefix_tag(tag), force: true
|
302
345
|
File.open(version_file, 'w') do |f|
|
303
346
|
f.write tag
|
304
347
|
end
|
305
348
|
else
|
306
349
|
rc = RevisionControl.new remote: rc_url, local: dir
|
307
|
-
rc.
|
350
|
+
rc.send rc.remotes_method, version: prefix_tag(tag), force: true
|
308
351
|
FileUtils.touch "#{dir}/.initial_populate_successful"
|
309
352
|
File.open(version_file, 'w') do |f|
|
310
353
|
f.write tag
|
311
354
|
end
|
312
355
|
end
|
313
|
-
rescue Origen::GitError, Origen::DesignSyncError => e
|
356
|
+
rescue Origen::GitError, Origen::DesignSyncError, Origen::PerforceError => e
|
314
357
|
# If Git failed in the remote, its usually easy to see what the problem is, but now *where* it is.
|
315
358
|
# This will prepend the failing remote along with the error from the revision control system,
|
316
359
|
# then rethrow the error
|
@@ -16,6 +16,8 @@ module Origen
|
|
16
16
|
attr_reader :remote
|
17
17
|
# Returns a pointer to the local location (a Pathname object)
|
18
18
|
attr_reader :local
|
19
|
+
# Method to use by Origen::RemoteManager to handle fetching a remote file
|
20
|
+
attr_reader :remotes_method
|
19
21
|
|
20
22
|
# rubocop:disable Lint/UnusedMethodArgument
|
21
23
|
|
@@ -27,6 +29,7 @@ module Origen
|
|
27
29
|
end
|
28
30
|
@remote = Pathname.new(options[:remote])
|
29
31
|
@local = Pathname.new(options[:local]).expand_path
|
32
|
+
@remotes_method = :checkout
|
30
33
|
initialize_local_dir(options)
|
31
34
|
end
|
32
35
|
|
@@ -192,6 +195,12 @@ module Origen
|
|
192
195
|
is_a?(Git) # :-)
|
193
196
|
end
|
194
197
|
|
198
|
+
# Returns true if the revision controller object uses Perforce
|
199
|
+
def p4?
|
200
|
+
is_a?(Perforce)
|
201
|
+
end
|
202
|
+
alias_method :perforce?, :p4?
|
203
|
+
|
195
204
|
# Returns true if the revision controller object uses Subversion
|
196
205
|
def svn?
|
197
206
|
is_a?(Subversion) # :-)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'P4'
|
2
|
+
module Origen
|
3
|
+
module RevisionControl
|
4
|
+
class Perforce < Base
|
5
|
+
# P4 session
|
6
|
+
attr_reader :p4
|
7
|
+
|
8
|
+
# e.g. myfile.txt
|
9
|
+
attr_accessor :remote_file
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
super
|
13
|
+
@remotes_method = :print
|
14
|
+
@p4 = P4.new
|
15
|
+
@p4.maxresults = 1
|
16
|
+
parse_remote
|
17
|
+
@p4.connect
|
18
|
+
unless @p4.connected?
|
19
|
+
Origen.log.error("Could not connect to port #{@p4.port} on client #{@p4.client}!")
|
20
|
+
fail
|
21
|
+
end
|
22
|
+
@p4.run_login
|
23
|
+
end
|
24
|
+
|
25
|
+
# Downloads a file to a local directory, no workspace/client is created. Perfect
|
26
|
+
# for read-only access like an application remote
|
27
|
+
def print(options = {})
|
28
|
+
options = {
|
29
|
+
verbose: true,
|
30
|
+
version: 'Latest'
|
31
|
+
}.merge(options)
|
32
|
+
cmd = [__method__.to_s, '-o', "#{@local}/#{@remote_file.to_s.split('/')[-1]}", @remote_file.to_s]
|
33
|
+
run cmd
|
34
|
+
end
|
35
|
+
|
36
|
+
def checkout(path = nil, options = {})
|
37
|
+
not_yet_supported(__method__)
|
38
|
+
end
|
39
|
+
|
40
|
+
def root
|
41
|
+
not_yet_supported(__method__)
|
42
|
+
end
|
43
|
+
|
44
|
+
def current_branch
|
45
|
+
not_yet_supported(__method__)
|
46
|
+
end
|
47
|
+
|
48
|
+
def diff_cmd
|
49
|
+
not_yet_supported(__method__)
|
50
|
+
end
|
51
|
+
|
52
|
+
def unmanaged
|
53
|
+
not_yet_supported(__method__)
|
54
|
+
end
|
55
|
+
|
56
|
+
def local_modifications
|
57
|
+
not_yet_supported(__method__)
|
58
|
+
end
|
59
|
+
|
60
|
+
def changes
|
61
|
+
not_yet_supported(__method__)
|
62
|
+
end
|
63
|
+
|
64
|
+
def checkin
|
65
|
+
not_yet_supported(__method__)
|
66
|
+
end
|
67
|
+
|
68
|
+
def build
|
69
|
+
not_yet_supported(__method__)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Needs to be in the form of an Array with command, as a Sting, as the first argument
|
75
|
+
# e.g. ["print", "-o", "pins/myfile.txt", "//depot/myprod/main/doc/pinout/myfile.txt"]
|
76
|
+
def run(cmd)
|
77
|
+
p4.run cmd
|
78
|
+
end
|
79
|
+
|
80
|
+
def not_yet_supported(m)
|
81
|
+
Origen.log.warn("The method #{m} is not currently supported by the Perforce API")
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def parse_remote
|
86
|
+
(@p4.port, @remote_file) = @remote.to_s.match(/^p4\:\/\/(\S+\:\d+)(.*)/).captures unless @remote.nil?
|
87
|
+
end
|
88
|
+
|
89
|
+
def configure_client(options)
|
90
|
+
unless options.include? :local
|
91
|
+
Origen.log.error('Need options[:local] to know how to configure the Perforce client!')
|
92
|
+
fail
|
93
|
+
end
|
94
|
+
client_name = "#{Origen.app.name}_#{User.current.id}_#{Time.now.to_i}"
|
95
|
+
begin
|
96
|
+
client_spec = @p4.fetch_client
|
97
|
+
client_spec['Root'] = options[:local].to_s
|
98
|
+
client_spec['Client'] = client_name
|
99
|
+
client_spec['View'] = ["#{@remote_file} //#{client_name}/#{@remote_file.split('/')[-1]}"]
|
100
|
+
client_spec['Host'] = nil
|
101
|
+
@p4.save_client(client_spec)
|
102
|
+
@p4.client = client_name
|
103
|
+
rescue P4Exception
|
104
|
+
@p4.errors.each { |e| Origen.log.error e }
|
105
|
+
raise
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -4,6 +4,7 @@ module Origen
|
|
4
4
|
autoload :DesignSync, 'origen/revision_control/design_sync'
|
5
5
|
autoload :Git, 'origen/revision_control/git'
|
6
6
|
autoload :Subversion, 'origen/revision_control/subversion'
|
7
|
+
autoload :Perforce, 'origen/revision_control/perforce'
|
7
8
|
|
8
9
|
IGNORE_DIRS = %w(
|
9
10
|
.ws .lsf log output web coverage .ref .yardoc .collection .bin
|
@@ -36,6 +37,8 @@ module Origen
|
|
36
37
|
DesignSync.new(options)
|
37
38
|
when options[:remote] =~ /git/
|
38
39
|
Git.new(options)
|
40
|
+
when options[:remote] =~ /^p4/
|
41
|
+
Perforce.new(options)
|
39
42
|
else
|
40
43
|
fail "Could not work out the revision control system for: #{options[:remote]}"
|
41
44
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Origen
|
2
2
|
module Specs
|
3
3
|
module Checkers
|
4
|
-
require 'nokogiri'
|
5
|
-
|
6
4
|
# rubocop:disable Style/RescueModifier:
|
7
5
|
def name_audit(name)
|
8
6
|
return name if name.nil?
|
@@ -74,7 +72,6 @@ module Origen
|
|
74
72
|
def evaluate_limit(limit)
|
75
73
|
return limit if limit.is_a?(Numeric)
|
76
74
|
return nil if limit.nil?
|
77
|
-
limit = limit.to_s if [Nokogiri::XML::NodeSet, Nokogiri::XML::Text, Nokogiri::XML::Element].include? limit.class
|
78
75
|
if limit.is_a? Symbol
|
79
76
|
limit = ':' + limit.to_s
|
80
77
|
else
|
data/lib/origen/sub_blocks.rb
CHANGED
@@ -364,11 +364,13 @@ module Origen
|
|
364
364
|
|
365
365
|
def materialize
|
366
366
|
file = attributes.delete(:file)
|
367
|
+
dir = attributes.delete(:dir) || owner.send(:export_dir)
|
367
368
|
block = owner.send(:instantiate_sub_block, name, klass, attributes)
|
368
369
|
if file
|
369
|
-
require File.join(
|
370
|
+
require File.join(dir, file)
|
370
371
|
block.extend owner.send(:export_module_names_from_path, file).join('::').constantize
|
371
372
|
end
|
373
|
+
block.owner = owner
|
372
374
|
block
|
373
375
|
end
|
374
376
|
|
data/lib/origen/tests/test.rb
CHANGED
data/lib/origen.rb
CHANGED
@@ -68,6 +68,7 @@ unless defined? RGen::ORIGENTRANSITION
|
|
68
68
|
autoload :Clocks, 'origen/clocks'
|
69
69
|
autoload :Value, 'origen/value'
|
70
70
|
autoload :OrgFile, 'origen/org_file'
|
71
|
+
autoload :Limits, 'origen/limits'
|
71
72
|
|
72
73
|
attr_reader :switch_user
|
73
74
|
|
@@ -79,6 +80,7 @@ unless defined? RGen::ORIGENTRANSITION
|
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
83
|
+
class PerforceError < OrigenError; status_code(11); end
|
82
84
|
class GitError < OrigenError; status_code(11); end
|
83
85
|
class DesignSyncError < OrigenError; status_code(12); end
|
84
86
|
class RevisionControlUninitializedError < OrigenError; status_code(13); end
|
data/templates/git/gitignore.erb
CHANGED
@@ -4,7 +4,7 @@ module Origen
|
|
4
4
|
module Export1
|
5
5
|
module Block1
|
6
6
|
def self.extended(model)
|
7
|
-
model.sub_block :x, file: 'origen/export1/block1/x.rb', lazy: true, base_address: 0x40000000
|
7
|
+
model.sub_block :x, file: 'origen/export1/block1/x.rb', dir: '/home/stephen/Code/github/origen/vendor/lib/models', lazy: true, base_address: 0x40000000
|
8
8
|
|
9
9
|
end
|
10
10
|
end
|
@@ -66,8 +66,10 @@ module Origen
|
|
66
66
|
model.add_ground_pin :gnd2
|
67
67
|
model.add_ground_pin :gnd3
|
68
68
|
model.add_ground_pin_group :gnd, :gnd1, :gnd2, :gnd3
|
69
|
+
model.add_virtual_pin :relay1
|
70
|
+
model.add_virtual_pin :relay2, packages: { bga: {} }
|
69
71
|
|
70
|
-
model.sub_block :block1, file: 'origen/export1/block1.rb', lazy: true
|
72
|
+
model.sub_block :block1, file: 'origen/export1/block1.rb', dir: '/home/stephen/Code/github/origen/vendor/lib/models', lazy: true
|
71
73
|
|
72
74
|
end
|
73
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.32.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,20 +80,6 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.7'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: nokogiri
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '='
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 1.7.2
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - '='
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 1.7.2
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rspec
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -366,6 +352,26 @@ dependencies:
|
|
366
352
|
- - "~>"
|
367
353
|
- !ruby/object:Gem::Version
|
368
354
|
version: 0.8.1
|
355
|
+
- !ruby/object:Gem::Dependency
|
356
|
+
name: p4ruby
|
357
|
+
requirement: !ruby/object:Gem::Requirement
|
358
|
+
requirements:
|
359
|
+
- - "~>"
|
360
|
+
- !ruby/object:Gem::Version
|
361
|
+
version: '2015.2'
|
362
|
+
- - ">="
|
363
|
+
- !ruby/object:Gem::Version
|
364
|
+
version: 2015.2.1313860
|
365
|
+
type: :runtime
|
366
|
+
prerelease: false
|
367
|
+
version_requirements: !ruby/object:Gem::Requirement
|
368
|
+
requirements:
|
369
|
+
- - "~>"
|
370
|
+
- !ruby/object:Gem::Version
|
371
|
+
version: '2015.2'
|
372
|
+
- - ">="
|
373
|
+
- !ruby/object:Gem::Version
|
374
|
+
version: 2015.2.1313860
|
369
375
|
description:
|
370
376
|
email:
|
371
377
|
- stephen.f.mcginty@gmail.com
|
@@ -494,6 +500,9 @@ files:
|
|
494
500
|
- lib/origen/generator/stage.rb
|
495
501
|
- lib/origen/global_app.rb
|
496
502
|
- lib/origen/global_methods.rb
|
503
|
+
- lib/origen/limits.rb
|
504
|
+
- lib/origen/limits/limit.rb
|
505
|
+
- lib/origen/limits/limit_set.rb
|
497
506
|
- lib/origen/location.rb
|
498
507
|
- lib/origen/location/base.rb
|
499
508
|
- lib/origen/location/map.rb
|
@@ -553,6 +562,7 @@ files:
|
|
553
562
|
- lib/origen/revision_control/base.rb
|
554
563
|
- lib/origen/revision_control/design_sync.rb
|
555
564
|
- lib/origen/revision_control/git.rb
|
565
|
+
- lib/origen/revision_control/perforce.rb
|
556
566
|
- lib/origen/revision_control/subversion.rb
|
557
567
|
- lib/origen/ruby_version_check.rb
|
558
568
|
- lib/origen/site_config.rb
|
@@ -640,7 +650,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
640
650
|
version: 1.8.11
|
641
651
|
requirements: []
|
642
652
|
rubyforge_project:
|
643
|
-
rubygems_version: 2.6.
|
653
|
+
rubygems_version: 2.6.8
|
644
654
|
signing_key:
|
645
655
|
specification_version: 4
|
646
656
|
summary: The Semiconductor Developer's Kit
|