Module: Origen::Tester::Timing
- Included in:
- Origen::Tester
- Defined in:
- lib/origen/tester/timing.rb
Defined Under Namespace
Classes: Timeset
Instance Method Summary (collapse)
- - (Object) before_timeset_change(_options = {})
- - (Object) called_timesets
-
- (Object) count(options = {})
This function can be used to generate a clock or some other repeating function that spans accross a range of vectors.
- - (Object) current_period_in_ns (also: #current_period, #period)
- - (Object) current_timeset (also: #timeset)
-
- (Object) cycles_to_ms(cycles)
:nodoc:.
-
- (Object) cycles_to_time(cycles)
Convert the supplied number of cycles to a time, based on the SoC defined cycle period.
-
- (Object) cycles_to_ts(cycles)
Cycles to tenths of a second.
-
- (Object) cycles_to_us(cycles)
:nodoc:.
-
- (Object) delay(cycles, options = {})
private
This should not be called directly, call via tester#wait.
- - (Object) max_repeat_loop
-
- (Object) ms_to_cycles(time)
:nodoc:.
-
- (Object) ns_to_cycles(time)
:nodoc:.
-
- (Object) s_to_cycles(time)
:nodoc:.
-
- (Object) set_timeset(timeset, period_in_ns = nil)
Set the timeset for the next vectors, this will remain in place until the next time this is called.
- - (Object) timeset_changed(timeset)
-
- (Object) us_to_cycles(time)
:nodoc:.
-
- (Object) wait(options = {})
Cause the pattern to wait.
Instance Method Details
- (Object) before_timeset_change(_options = {})
77 78 |
# File 'lib/origen/tester/timing.rb', line 77 def before_timeset_change( = {}) end |
- (Object) called_timesets
189 190 191 |
# File 'lib/origen/tester/timing.rb', line 189 def called_timesets @called_timesets ||= [] end |
- (Object) count(options = {})
This function can be used to generate a clock or some other repeating function that spans accross a range of vectors. The period of each cycle and the duration of the sequence are supplied via the following options:
-
:period_in_cycles
-
:period_in_ns
-
:period_in_us
-
:period_in_ms
-
:duration_in_cycles
-
:duration_in_ns
-
:duration_in_us
-
:duration_in_ms
If multiple definitions for either option are supplied then they will be added together.
Example
# Supply a clock pulse on :pinA for 100ms
$tester.count(:period_in_cycles => 10, :duration_in_ms => 100) do
$top.pin(:pinA).drive!(1)
$top.pin(:pinA).drive!(0)
end
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/origen/tester/timing.rb', line 233 def count( = {}) = { period_in_cycles: 0, period_in_ms: 0, period_in_us: 0, period_in_ns: 0, duration_in_cycles: 0, duration_in_ms: 0, duration_in_us: 0, duration_in_ns: 0 }.merge() period_cycles = [:period_in_cycles] + ms_to_cycles([:period_in_ms]) + us_to_cycles([:period_in_us]) + ns_to_cycles([:period_in_ns]) duration_cycles = [:duration_in_cycles] + ms_to_cycles([:duration_in_ms]) + us_to_cycles([:duration_in_us]) + ns_to_cycles([:duration_in_ns]) total = 0 while total < duration_cycles wait(time_in_cycles: period_cycles) yield # Return control back to caller total += period_cycles end end |
- (Object) current_period_in_ns Also known as: current_period, period
193 194 195 196 197 198 199 |
# File 'lib/origen/tester/timing.rb', line 193 def current_period_in_ns if @timeset @timeset.period_in_ns else fail 'No timeset has been specified yet!' end end |
- (Object) current_timeset Also known as: timeset
203 204 205 |
# File 'lib/origen/tester/timing.rb', line 203 def current_timeset @timeset end |
- (Object) cycles_to_ms(cycles)
:nodoc:
180 181 182 |
# File 'lib/origen/tester/timing.rb', line 180 def cycles_to_ms(cycles) # :nodoc: ((cycles.to_f * current_period_in_ns) / (1000 * 1000)).ceil end |
- (Object) cycles_to_time(cycles)
Convert the supplied number of cycles to a time, based on the SoC defined cycle period
209 210 211 |
# File 'lib/origen/tester/timing.rb', line 209 def cycles_to_time(cycles) # :nodoc: (cycles * current_period_in_ns).to_f / 1_000_000_000 end |
- (Object) cycles_to_ts(cycles)
Cycles to tenths of a second
185 186 187 |
# File 'lib/origen/tester/timing.rb', line 185 def cycles_to_ts(cycles) # :nodoc: ((cycles.to_f * current_period_in_ns) / (1000 * 1000 * 100)).ceil end |
- (Object) cycles_to_us(cycles)
:nodoc:
176 177 178 |
# File 'lib/origen/tester/timing.rb', line 176 def cycles_to_us(cycles) # :nodoc: ((cycles.to_f * current_period_in_ns) / (1000)).ceil end |
- (Object) delay(cycles, options = {})
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This should not be called directly, call via tester#wait
141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/origen/tester/timing.rb', line 141 def delay(cycles, = {}) (cycles / max_repeat_loop).times do if block_given? yield .merge(repeat: max_repeat_loop) else cycle(.merge(repeat: max_repeat_loop)) end end if block_given? yield .merge(repeat: (cycles % max_repeat_loop)) else cycle(.merge(repeat: (cycles % max_repeat_loop))) end end |
- (Object) max_repeat_loop
156 157 158 |
# File 'lib/origen/tester/timing.rb', line 156 def max_repeat_loop @max_repeat_loop || 65_535 end |
- (Object) ms_to_cycles(time)
:nodoc:
164 165 166 |
# File 'lib/origen/tester/timing.rb', line 164 def ms_to_cycles(time) # :nodoc: ((time.to_f) * 1000 * 1000 / current_period_in_ns).to_int end |
- (Object) ns_to_cycles(time)
:nodoc:
172 173 174 |
# File 'lib/origen/tester/timing.rb', line 172 def ns_to_cycles(time) # :nodoc: (time.to_f / current_period_in_ns).to_int end |
- (Object) s_to_cycles(time)
:nodoc:
160 161 162 |
# File 'lib/origen/tester/timing.rb', line 160 def s_to_cycles(time) # :nodoc: ((time.to_f) * 1000 * 1000 * 1000 / current_period_in_ns).to_int end |
- (Object) set_timeset(timeset, period_in_ns = nil)
Set the timeset for the next vectors, this will remain in place until the next time this is called.
$tester.set_timeset("bist_25mhz", 40)
This method also accepts a block in which case the contained vectors will generate with the supplied timeset and subsequent vectors will return to the previous timeset automatically.
$tester.set_timeset("bist_25mhz", 40) do
$tester.cycle
end
The arguments can also be supplied as a single array, or not at all. In the latter case the existing timeset will simply be preserved. This is useful if you have timesets that can be conditionally set based on the target.
# Target 1
$soc.readout_timeset = ["readout", 120]
# Target 2
$soc.readout_timeset = false
# This code is compatible with both targets, in the first case the timeset will switch
# over, in the second case the existing timeset will be preserved.
$tester.set_timeset($soc.readout_timeset) do
$tester.cycle
end
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/origen/tester/timing.rb', line 41 def set_timeset(timeset, period_in_ns = nil) if timeset.is_a?(Array) timeset, period_in_ns = timeset[0], timeset[1] end timeset ||= @timeset unless timeset.is_a?(Timeset) fail 'You must supply a period_in_ns argument to set_timeset' unless period_in_ns timeset = Timeset.new(name: timeset.to_s.chomp, period_in_ns: period_in_ns) end called_timesets << timeset unless called_timesets.map(&:name).include?(timeset.name) if block_given? original = @timeset timeset_changed(timeset) @timeset = timeset yield timeset_changed(original) @timeset = original else timeset_changed(timeset) @timeset = timeset end end |
- (Object) timeset_changed(timeset)
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/origen/tester/timing.rb', line 64 def timeset_changed(timeset) if last_vector && last_vector.timeset != timeset change = { old: last_vector.timeset, new: timeset } # Suppress any duplicate calls if !@_last_timeset_change || (@_last_timeset_change[:new] != change[:new] && @_last_timeset_change[:old] != change[:old]) before_timeset_change(change) end @_last_timeset_change = change end end |
- (Object) us_to_cycles(time)
:nodoc:
168 169 170 |
# File 'lib/origen/tester/timing.rb', line 168 def us_to_cycles(time) # :nodoc: ((time.to_f * 1000) / current_period_in_ns).to_int end |
- (Object) wait(options = {})
Cause the pattern to wait. The following options are available to help you specify the time to wait:
-
:cycles - delays specified in raw cycles, the test model is responsible for translating this into a sequence of valid repeat statements
-
:time_in_ns - time specified in nano-seconds
-
:time_in_us - time specified in micro-seconds
-
:time_in_ms - time specified in milli-seconds
-
:time_in_s - time specified in seconds
If more than one option is supplied they will get added together to give a final delay time expressed in cycles.
Examples
$tester.wait(:cycles => 100, :time_in_ns => 200) # Wait for 100 cycles + 200ns
This method can also be used to trigger a match loop in which case the supplied time becomes the time out for the match. See the J750#match method for full details of the available options.
$tester.wait(:match => true, :state => :high, :pin => $top.pin(:done), :time_in_ms => 500)
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/origen/tester/timing.rb', line 95 def wait( = {}) = { cycles: 0, time_in_cycles: 0, time_in_us: 0, time_in_ns: 0, time_in_ms: 0, time_in_s: 0, match: false, # Set to true to invoke a match loop where the supplied delay # will become the timeout duration }.merge() cycles = 0 cycles += [:cycles] + [:time_in_cycles] cycles += s_to_cycles([:time_in_s]) cycles += ms_to_cycles([:time_in_ms]) cycles += us_to_cycles([:time_in_us]) cycles += ns_to_cycles([:time_in_ns]) time = cycles * current_period_in_ns # Total delay in ns case when time < 1000 # When less than 1us cc "Wait for #{'a maximum of ' if [:match]}#{time}ns" when time < 1_000_000 # When less than 1ms cc "Wait for #{'a maximum of ' if [:match]}#{(time.to_f / 1000).round(1)}us" # Display delay in us when time < 1_000_000_000 # When less than 1s cc "Wait for #{'a maximum of ' if [:match]}#{(time.to_f / 1_000_000).round(1)}ms" else cc "Wait for #{'a maximum of ' if [:match]}%.2fs" % (time.to_f / 1_000_000_000) end if cycles > 0 # Allow this function to be called with 0 in which case it will just return if [:match] if block_given? match_block(cycles, ) { yield } else match([:pin], [:state], cycles, ) end else delay(cycles) end end end |