Module: OrigenTesters::API

Defined in:
lib/origen_sim/origen_testers/api.rb

Instance Method Summary collapse

Instance Method Details

#_origen_testers_cycleObject



105
# File 'lib/origen_sim/origen_testers/api.rb', line 105

alias_method :_origen_testers_cycle, :cycle

#apply_captured_dataObject



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/origen_sim/origen_testers/api.rb', line 134

def apply_captured_data
  if @apply_captured_data_cycles && @apply_captured_data_cycles > 1
    @apply_captured_data_cycles -= 1
  else
    @org_file.read_line do |operations, cycles|
      @apply_captured_data_cycles = cycles
      operations.each do |object, operation, *args|
        object.send(operation, *args)
      end
    end
  end
end

#cycle(options = {}) ⇒ Object



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
# File 'lib/origen_sim/origen_testers/api.rb', line 106

def cycle(options = {})
  if @sim_capture
    # Need to un-roll all repeats to be sure we observe the true data, can't
    # really assume that it will be constant for all cycles covered by the repeat
    cycles = options.delete(:repeat) || 1
    cycles.times do
      if @update_capture
        _origen_testers_cycle(options)
        @sim_capture.each do |pin, net|
          pin.assert(simulator.peek(net))
          # Remove the assertion since it is for the previous cycle in terms of the current simulation,
          # this won't be captured to the org file
          pin.dont_care
        end
        Origen::OrgFile.cycle
      else
        unless @org_file.exist?
          fail "The simulation capture \"#{@sim_capture_id}\" has not been simulated yet, re-run this pattern with a simulation target first!"
        end
        apply_captured_data
        _origen_testers_cycle(options)
      end
    end
  else
    _origen_testers_cycle(options)
  end
end

#marker=(val) ⇒ Object

Set a marker in the OrigenSim testbench



16
17
18
# File 'lib/origen_sim/origen_testers/api.rb', line 16

def marker=(val)
  simulator.marker = val if sim?
end

#read_register(reg_or_val, options = {}) ⇒ Object



11
12
13
# File 'lib/origen_sim/origen_testers/api.rb', line 11

def read_register(reg_or_val, options = {})
  yield
end

#sim?Boolean Also known as: simulator?

Returns true if the tester is an instance of OrigenSim::Tester, otherwise returns false

Returns:

  • (Boolean)


6
7
8
# File 'lib/origen_sim/origen_testers/api.rb', line 6

def sim?
  is_a?(OrigenSim::Tester)
end

#sim_capture(id, *pins) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/origen_sim/origen_testers/api.rb', line 84

def sim_capture(id, *pins)
  if @sim_capture || @sim_delay
    fail 'Nesting of sim_capture and/or sim_delay blocks is not yet supported!'
  end
  @sim_capture_id = id
  options = pins.last.is_a?(Hash) ? pins.pop : {}
  pins = pins.map { |p| p.is_a?(String) || p.is_a?(Symbol) ? dut.pin(p) : p }
  pins.each(&:save)
  @sim_capture = pins.map { |p| [p, "origen.dut.#{p.rtl_name}"] }
  Origen::OrgFile.open(id, path: OrigenSim.capture_dir) do |org_file|
    @org_file = org_file
    @update_capture = update_capture?
    if @update_capture
      @sim_capture.each { |pin, net| pin.record_to_org_file(only: :assert) }
    end
    yield
  end
  pins.each(&:restore)
  @sim_capture = nil
end

#sim_delay(id, options = {}, &block) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/origen_sim/origen_testers/api.rb', line 20

def sim_delay(id, options = {}, &block)
  if sim? && dut_version <= '0.12.0'
    OrigenSim.error "Use of sim_delay requires a DUT model compiled with OrigenSim version > 0.12.0, the current dut was compiled with #{dut_version}"
  end
  orig_id = id
  id = "delay_#{id}".to_sym  # Just to make sure it is unique from the sim_capture IDs
  if @sim_capture || @sim_delay
    fail 'Nesting of sim_capture and/or sim_delay blocks is not yet supported!'
  end
  Origen::OrgFile.open(id, path: OrigenSim.capture_dir) do |org_file|
    @org_file = org_file
    if update_capture?
      @sim_delay = true
      # This enables errors to be captured in a separate variable so that they don't affect
      # the overall simulation result
      start_cycle = cycle_count
      delay = 0
      simulator.match_loop do
        if options[:resolution]
          if options[:resolution].is_a?(Hash)
            resolution_in_cycles = time_to_cycles(options[:resolution])
          else
            resolution_in_cycles = options[:resolution]
          end
        end
        timeout_in_cycles = time_to_cycles(options)
        e = -1
        until (e == simulator.match_errors) || (timeout_in_cycles > 0 ? delay > timeout_in_cycles : false)
          delay = cycle_count - start_cycle
          e = simulator.match_errors
          pre_block_cycle = cycle_count
          block.call
          if resolution_in_cycles
            remaining = resolution_in_cycles - (cycle_count - pre_block_cycle)
            remaining.cycles if remaining > 0
          else
            # Make sure time is advancing, the block does not necessarily have to advance time
            1.cycle if pre_block_cycle == cycle_count
          end
        end
      end
      Origen.log.debug "sim_delay #{orig_id} resolved after #{delay} cycles"
      # We now know how long it took before the block could pass, now record that information
      # to the org file for next time
      org_file.record('tester', 'cycle')
      org_file.file  # Need to call this since we are bypassing the regular capture API here
      Origen::OrgFile.cycle(delay)
    else
      unless org_file.exist?
        fail "The simulation delay \"#{orig_id}\" has not been simulated yet, re-run this pattern with a simulation target first!"
      end
      org_file.read_line do |operations, cycles|
        cycles.cycles
      end
    end
  end
  # Finally execute the block after waiting
  if options[:padding]
    time_to_cycles(options[:padding]).cycles
  end
  block.call
  @sim_delay = nil
end

#time_to_cycles(options) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/origen_sim/origen_testers/api.rb', line 151

def time_to_cycles(options)
  options = {
    cycles:         0,
    time_in_cycles: 0,
    time_in_us:     0,
    time_in_ns:     0,
    time_in_ms:     0,
    time_in_s:      0
  }.merge(options)
  cycles = 0
  cycles += options[:cycles] + options[:time_in_cycles]
  cycles += s_to_cycles(options[:time_in_s])
  cycles += ms_to_cycles(options[:time_in_ms])
  cycles += us_to_cycles(options[:time_in_us])
  cycles += ns_to_cycles(options[:time_in_ns])
  cycles
end

#update_capture?Boolean

Returns:

  • (Boolean)


147
148
149
# File 'lib/origen_sim/origen_testers/api.rb', line 147

def update_capture?
  sim? && (!@org_file.exist? || Origen.app!.update_sim_captures)
end