Module: OrigenTesters::Timing::TimingAPI
- Included in:
- OrigenTesters::Timing
- Defined in:
- lib/origen_testers/timing/timing_api.rb
Instance Method Summary collapse
- #before_timeset_change(options = {}) ⇒ Object
-
#called_timesets ⇒ Array
(also: #called_timesets_by_instance)
Returns any timesets that have been called during this execution.
-
#called_timesets_by_name ⇒ Array
Similar to #called_timesets, but returns the name of the timesets instead.
-
#count(options = {}) ⇒ Object
This function can be used to generate a clock or some other repeating function that spans accross a range of vectors.
- #current_period_in_ns ⇒ Object (also: #current_period, #period)
- #current_timeset ⇒ Object (also: #timeset)
-
#cycles_to_time(cycles) ⇒ Object
Convert the supplied number of cycles to a time, based on the SoC defined cycle period.
-
#delay(cycles, options = {}) ⇒ Object
private
This should not be called directly, call via tester#wait.
- #max_repeat_loop ⇒ Object
-
#min_period_timeset ⇒ Object
Returns the timeset (a Timeset object) with the shortest period that has been encountered so far in the course of generating the current pattern.
- #min_repeat_loop ⇒ Object
-
#period_in_ns ⇒ Object
Returns the current period in ns, or nil, if no timeset has been set.
- #period_in_secs ⇒ Object (also: #period_in_seconds)
-
#set_timeset(timeset, period_in_ns = nil, &block) ⇒ Object
(also: #with_timeset)
Set the timeset for the next vectors, this will remain in place until the next time this is called.
- #timeset?(t) ⇒ Boolean
- #timesets ⇒ Object
-
#timing_toggled_pins ⇒ Object
When period levelling is enabled, vectors will be expanded like this: $tester.set_timeset(“fast”, 40) 2.cycles # fast 1 0 0 1 0 # fast 1 0 0 1 0 # Without levelling enabled $tester.set_timeset(“slow”, 80) 2.cycles # slow 1 0 0 1 0 # slow 1 0 0 1 0 # With levelling enabled $tester.set_timeset(“slow”, 80) 2.cycles # fast 1 0 0 1 0 # fast 1 0 0 1 0 # fast 1 0 0 1 0 # fast 1 0 0 1 0.
-
#wait(options = {}) ⇒ Object
Cause the pattern to wait.
Instance Method Details
#before_timeset_change(options = {}) ⇒ Object
109 110 |
# File 'lib/origen_testers/timing/timing_api.rb', line 109 def before_timeset_change( = {}) end |
#called_timesets ⇒ Array Also known as: called_timesets_by_instance
Returns any timesets that have been called during this execution.
209 210 211 |
# File 'lib/origen_testers/timing/timing_api.rb', line 209 def called_timesets OrigenTesters::Timing.called_timesets end |
#called_timesets_by_name ⇒ Array
Similar to #called_timesets, but returns the name of the timesets instead.
216 217 218 |
# File 'lib/origen_testers/timing/timing_api.rb', line 216 def called_timesets_by_name OrigenTesters::Timing.called_timesets_by_name end |
#count(options = {}) ⇒ Object
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
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/origen_testers/timing/timing_api.rb', line 256 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 |
#current_period_in_ns ⇒ Object Also known as: current_period, period
220 221 222 |
# File 'lib/origen_testers/timing/timing_api.rb', line 220 def current_period_in_ns OrigenTesters::Timing.current_period_in_ns end |
#current_timeset ⇒ Object Also known as: timeset
226 227 228 |
# File 'lib/origen_testers/timing/timing_api.rb', line 226 def current_timeset OrigenTesters::Timing.current_timeset end |
#cycles_to_time(cycles) ⇒ Object
Convert the supplied number of cycles to a time, based on the SoC defined cycle period
232 233 234 |
# File 'lib/origen_testers/timing/timing_api.rb', line 232 def cycles_to_time(cycles) # :nodoc: (cycles * current_period_in_ns).to_f / 1_000_000_000 end |
#delay(cycles, options = {}) ⇒ Object
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
184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/origen_testers/timing/timing_api.rb', line 184 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 |
#max_repeat_loop ⇒ Object
199 200 201 |
# File 'lib/origen_testers/timing/timing_api.rb', line 199 def max_repeat_loop @max_repeat_loop || 65_535 end |
#min_period_timeset ⇒ Object
Returns the timeset (a Timeset object) with the shortest period that has been encountered so far in the course of generating the current pattern.
A tester object is re-instantiated at the start of every pattern which will reset this variable.
105 106 107 |
# File 'lib/origen_testers/timing/timing_api.rb', line 105 def min_period_timeset OrigenTesters::Timing.min_period_timeset end |
#min_repeat_loop ⇒ Object
203 204 205 |
# File 'lib/origen_testers/timing/timing_api.rb', line 203 def min_repeat_loop @min_repeat_loop end |
#period_in_ns ⇒ Object
Returns the current period in ns, or nil, if no timeset has been set.
113 114 115 |
# File 'lib/origen_testers/timing/timing_api.rb', line 113 def period_in_ns OrigenTesters::Timing.period_in_ns end |
#period_in_secs ⇒ Object Also known as: period_in_seconds
117 118 119 |
# File 'lib/origen_testers/timing/timing_api.rb', line 117 def period_in_secs OrigenTesters::Timing.period_in_ns end |
#set_timeset(timeset, period_in_ns = nil, &block) ⇒ Object Also known as: with_timeset
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
87 88 89 |
# File 'lib/origen_testers/timing/timing_api.rb', line 87 def set_timeset(timeset, period_in_ns = nil, &block) OrigenTesters::Timing.set_timeset(timeset, period_in_ns, &block) end |
#timeset?(t) ⇒ Boolean
96 97 98 |
# File 'lib/origen_testers/timing/timing_api.rb', line 96 def timeset?(t) OrigenTesters::Timing.timeset?(t) end |
#timesets ⇒ Object
92 93 94 |
# File 'lib/origen_testers/timing/timing_api.rb', line 92 def timesets OrigenTesters::Timing.timesets end |
#timing_toggled_pins ⇒ Object
When period levelling is enabled, vectors will be expanded like this:
$tester.set_timeset("fast", 40)
2.cycles # fast 1 0 0 1 0
# fast 1 0 0 1 0
# Without levelling enabled
$tester.set_timeset("slow", 80)
2.cycles # slow 1 0 0 1 0
# slow 1 0 0 1 0
# With levelling enabled
$tester.set_timeset("slow", 80)
2.cycles # fast 1 0 0 1 0
# fast 1 0 0 1 0
# fast 1 0 0 1 0
# fast 1 0 0 1 0
The overall time of the levelled/expanded vectors matches that of the unlevelled case. i.e. 4 cycles at fast speed (4 * 40ns = 160ns) is equivalent to 2 cycles at slow speed (2 * 80ns = 160ns).
However, what if pin 1 in the example above was a clk pin where the 1 -> 0 transition was handled by the timing setup for that pin. In that case the levelled code is no longer functionally correct since it contains 4 clock pulses while the unlevelled code only has 2.
Such pins can be specified via this attribute and the levelling logic will then automatically adjust the drive state to keep the number of pulses correct. It would automatically adjust to the alternative logic state where 0 means 'on' and 1 means 'off' if applicable.
$tester.timing_toggled_pins << $dut.pin(:tclk) # This is pin 1
$tester.set_timeset("fast", 40)
2.cycles # fast 1 0 0 1 0
# fast 1 0 0 1 0
# Without levelling enabled
$tester.set_timeset("slow", 80)
2.cycles # slow 1 0 0 1 0
# slow 1 0 0 1 0
# With levelling enabled
$tester.set_timeset("slow", 80)
2.cycles # fast 1 0 0 1 0
# fast 0 0 0 1 0
# fast 1 0 0 1 0
# fast 0 0 0 1 0
Multiple pins an be specified like this:
$tester.timing_toggled_pins = [$dut.pin(:tclk), $dut.pin(:clk)] # Overrides any pins added elsewhere
$tester.timing_toggled_pins << [$dut.pin(:tclk), $dut.pin(:clk)] # In addition to any pins added elsewhere
54 55 56 57 58 |
# File 'lib/origen_testers/timing/timing_api.rb', line 54 def timing_toggled_pins @timing_toggled_pins ||= [] @timing_toggled_pins.flatten! @timing_toggled_pins end |
#wait(options = {}) ⇒ Object
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: $dut.pin(:done), time_in_ms: 500)
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/origen_testers/timing/timing_api.rb', line 137 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 |