Origen-SDK / origen_sim

Plugin to enable Origen patterns to be run in a dynamic Verilog simulation
MIT License
1 stars 4 forks source link

Match loop support and other improvements #19

Closed ginty closed 6 years ago

ginty commented 6 years ago

This PR adds support for match loops and fixed delay capture from simulation, it requires the DUT object to be re-compiled with this version of OrigenSim to support it.

The following has been added:

tester.wait match: true, time_in_cycles: 2000, pin: dut.pin(:done), state: :high

tester.wait match: true, time_in_cycles: 2000, pin: dut.pin(:tdo),   state: :low,
                                              pin2: dut.pin(:done), state2: :high

tester.wait match: true, time_in_cycles: 2000 do
  dut.pin(:done).assert!(1)
end

It currently checks for the match case to be fulfilled every 10% of the timeout. Options could be added in future to offer higher resolution, but it is not envisaged to be needed for the vast majority of use cases.

Multiple block conditions supplied as described in the Origen guides like this are not supported yet:

tester.wait match: true, time_in_s: 2 do |conditions, fail|
  conditions.add do
    pin(:done).assert!(1)
  end
  conditions.add do
    pin(:fail).assert!(1)
  end
end

The reason is that it doesn't look to me like OrigenTesters actually supports it either and it will need updates to enable this downstream in simulation. Some placeholders for it are included in this update.

tester.sim_delay :delay1 do
  dut.pin(:done).assert!(1)
end

This works the same as sim_capture in that the same ID used in multiple places means that the same delay will be used, while adding the --sim_capture option to an OrigenSim run means that the delay will be captured, otherwise it will be replayed.

Also the delays are stored in Org files in the pattern directory, these should be committed to your revision control system.

By default it will sample the block every cycle, but if it is expected to be long you can help by providing a timeout similar to a match loop:

tester.sim_delay :delay1, time_in_cycles: 2000 do
  dut.pin(:done).assert!(1)
end

In that case the block will be checked for a pass every 10% of the timeout and it will fail if it has not passed within the timeout period, the same as a match loop.

Additional padding can be added to the calculated delay like this (for the timeout and the padding all the usual time_in_us: style of options are supported):

tester.sim_delay :delay1, time_in_cycles: 2000, padding: { time_in_cycles: 500 } do
  dut.pin(:done).assert!(1)
end

Other minor updates:

ginty commented 6 years ago

I decided that if you were to use the sim_delay method you would probably want to the resolved delay to be pretty accurate, so I removed the code to check for resolution every 10% of a given timeout.

Instead, it will now check every cycle by default, or the user can make it use lower resolution (and therefore simulate a bit faster) by supplying a :resolution option, either as a number of cycles:

tester.sim_delay :delay1, time_in_cycles: 2000, resolution: 10 do
  dut.pin(:done).assert!(1)
end

or by supplying a hash filled with the usual time options:

tester.sim_delay :delay1, time_in_cycles: 2000, resolution: { time_in_ns: 50 } do
  dut.pin(:done).assert!(1)
end