origen_sim 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +5 -5
  2. data/config/application.rb +17 -2
  3. data/config/shared_commands.rb +7 -0
  4. data/config/version.rb +1 -1
  5. data/ext/bridge.c +13 -3
  6. data/lib/origen_sim.rb +10 -0
  7. data/lib/origen_sim/artifacts.rb +101 -0
  8. data/lib/origen_sim/commands/build.rb +41 -9
  9. data/lib/origen_sim/heartbeat.rb +13 -1
  10. data/lib/origen_sim/origen_testers/api.rb +90 -7
  11. data/lib/origen_sim/simulation.rb +49 -4
  12. data/lib/origen_sim/simulator.rb +171 -19
  13. data/lib/origen_sim/stderr_reader.rb +19 -13
  14. data/lib/origen_sim/stdout_reader.rb +22 -16
  15. data/lib/origen_sim/tester.rb +110 -1
  16. data/lib/origen_sim_dev/dut.rb +5 -0
  17. data/pattern/test.rb +143 -0
  18. data/templates/empty.gtkw +19 -1
  19. data/templates/empty.rc +86 -0
  20. data/templates/empty.svcf +79 -9
  21. data/templates/empty.tcl +37 -9
  22. data/templates/origen_guides/simulation/app.md.erb +131 -0
  23. data/templates/origen_guides/simulation/artifacts.md.erb +115 -0
  24. data/templates/origen_guides/simulation/compiling.md.erb +190 -0
  25. data/templates/origen_guides/simulation/debugging.md.erb +135 -0
  26. data/templates/origen_guides/simulation/environment.md.erb +217 -0
  27. data/templates/origen_guides/simulation/flows.md.erb +69 -0
  28. data/templates/origen_guides/simulation/howitworks.md.erb +64 -0
  29. data/templates/origen_guides/simulation/introduction.md.erb +35 -0
  30. data/templates/origen_guides/simulation/log.md.erb +118 -0
  31. data/templates/origen_guides/simulation/patterns.md.erb +193 -0
  32. data/templates/probe.tcl.erb +3 -0
  33. data/templates/rtl_v/origen.v.erb +19 -3
  34. data/templates/web/layouts/_guides.html.erb +15 -0
  35. metadata +18 -5
@@ -0,0 +1,35 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ <img src="https://user-images.githubusercontent.com/158364/36662666-6b49d096-1adf-11e8-997e-889caba391b2.png" alt="origen_sim" style="
4
+ width: 100%;
5
+ ">
6
+
7
+ OrigenSim is a plugin that enables semiconductor test patterns (and flows) written in Origen/Ruby to be run
8
+ in a dynamic Verilog simulation, similar to what is commonly known as a _Virtual Test_ simulation in other workflows.
9
+
10
+ It provides a simulation tester driver (which can be used as a direct replacement for Origen's
11
+ conventional ATE tester drivers) which will
12
+ pass requests to drive or expect pin values onto a simulator instead of rendering them to an ASCII file. Since
13
+ the application-level Origen code is the same in both cases, it guarantees that what happens in the simulation
14
+ and in the final pattern are the same and that ultimately they will work first time on silicon.
15
+
16
+ For debugging, OrigenSim supports the injection of regular Ruby debugger breakpoints anywhere in the pattern
17
+ source code. This will halt the simulation at the given point in time, allowing it to be interactively
18
+ debugged at the Origen-source-code level.
19
+
20
+ Similarly, an Origen interactive session (`origen i`) can be launched with an OrigenSim driver,
21
+ allowing designers and test engineers to use Origen APIs to interactively manipulate a live simulation of their
22
+ DUT while viewing the response in real time in a wave viewer.
23
+
24
+ #### Adding OrigenSim To Your Application
25
+
26
+ To enable your application to use OrigenSim, simply add the plugin to your Gemfile:
27
+
28
+ ~~~ruby
29
+ gem "origen_sim"
30
+ ~~~
31
+
32
+ and then [create a simulation environment setup](<%= path "guides/simulation/environment" %>).
33
+
34
+
35
+ % end
@@ -0,0 +1,118 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ Log output from simulations is often very verbose, which can make it hard to distinguish between messages
4
+ that are important and those that can be safely ignored.
5
+
6
+ By default, OrigenSim will automatically suppress all simulator log output except for any lines that
7
+ contain the text _WARNING_ or _ERROR_ (case insensitive); both of these will be logged to the console and any occurrences of
8
+ the latter will also make the result of the simulation be classed as a FAIL.
9
+
10
+ All log output can be shown in the console by running with the `-d` or `--debug` switches, and the log files will
11
+ always contain everything that was output by the simulator.
12
+
13
+ OrigenSim will also consider any output from the simulator to STDERR as a sign that something has gone wrong
14
+ and this will also cause the simulation result to be classed as a FAIL.
15
+
16
+ If your simulation produces STDERR output which you don't care about (and which you don't want to make your
17
+ simulation FAIL), then you can configure OrigenSim to ignore all STDERR messages via:
18
+
19
+ ~~~ruby
20
+ OrigenSim.fail_on_stderr = false
21
+ ~~~
22
+
23
+ Alternatively, a safer solution is to declare which specific messages on STDERR should be ignored.
24
+ For example, say that in an early design build the ADC is not configured correctly and this results
25
+ in a message about this being output to STDERR.
26
+ However, since this problem does not affect the particular IP that we are testing we do
27
+ not want our simulations to FAIL because of it.
28
+
29
+ In such a case you can add strings to the `stderr_string_exceptions` array and any STDERR lines which contain
30
+ the given text will be ignored:
31
+
32
+ ~~~ruby
33
+ OrigenSim.stderr_string_exceptions << 'invalid adc config' # Case in-sensitive match
34
+ ~~~
35
+
36
+ **Note that in all of these cases the given text is considered to be case-insensitive when considering if
37
+ it matches a log line.**
38
+
39
+ If you need case-sensitivity (or more generally need more control of exactly what is considered to be a match), you can
40
+ supply a regular expression instead of a string for all of the cases discussed here:
41
+
42
+ ~~~ruby
43
+ OrigenSim.stderr_string_exceptions << /invalid adc config/ # Case sensitive match
44
+ ~~~
45
+
46
+ Similarly, if you find that the default of matching for _ERROR_ in STDOUT messages is being overly aggressive,
47
+ exceptions can be added in a similar way:
48
+
49
+ ~~~ruby
50
+ OrigenSim.error_string_exceptions << 'uninitialized value in ROM at'
51
+ ~~~
52
+
53
+ This means that a log line resembling <code>ERROR uninitialized value in ROM at 0x1000</code> will not fail the simulation,
54
+ but the line `ERROR uninitialized value in RAM at 0x2000` will fail.
55
+
56
+ On the other hand, if you find that simply matching for _ERROR_ is not catching some cases which you would
57
+ like to cause a FAIL, you can add additional strings to watch out for like this:
58
+
59
+ ~~~ruby
60
+ OrigenSim.error_strings << 'FAILED'
61
+ ~~~
62
+
63
+ If you want to remove 'ERROR' from the list of error strings (in there by default), you can assign a new array
64
+ instance:
65
+
66
+ ~~~ruby
67
+ OrigenSim.error_strings << 'FAILED'
68
+
69
+ OrigenSim.error_strings # => ['ERROR', 'FAILED']
70
+
71
+ OrigenSim.error_strings = ['FAILED']
72
+
73
+ OrigenSim.error_strings # => ['FAILED']
74
+ ~~~
75
+
76
+ Similar variables exist to configure what you want to catch as a warning:
77
+
78
+ ~~~ruby
79
+ OrigenSim.warning_strings # => ['WARNING']
80
+
81
+ OrigenSim.warning_string_exceptions # => []
82
+ ~~~
83
+
84
+ and also to match any output lines that you simply want to be shown in the console by default:
85
+
86
+ ~~~ruby
87
+ OrigenSim.log_string # => []
88
+ ~~~
89
+
90
+ It is conventional to do all such configuration like this with `environment/sim.rb`, where you can decide
91
+ to make it global (applies to all targets), target-specific, or a combination of both:
92
+
93
+ ~~~ruby
94
+ # environment/sim.rb
95
+
96
+ # Will apply to all targets
97
+ OrigenSim.error_strings << 'FAILED'
98
+
99
+ case Origen.target.name
100
+
101
+ when "my_dut1"
102
+ OrigenSim.cadence do |sim|
103
+ # Configuration of Cadence simulator to be used for DUT1 here
104
+ end
105
+
106
+ # Known problem with this specific DUT only
107
+ OrigenSim.error_string_exceptions << 'uninitialized value in ROM at'
108
+
109
+ when "my_dut2"
110
+ OrigenSim.synopsys do |sim|
111
+ # Configuration of Synopsys simulator to be used for DUT2 here
112
+ end
113
+
114
+ # ...
115
+ ~~~
116
+
117
+
118
+ % end
@@ -0,0 +1,193 @@
1
+ % render "layouts/guides.html" do
2
+
3
+ Patterns are simulated by simply generating the pattern with
4
+ a [simulation environment](<%= path "guides/simulation/environment" %>)
5
+ selected:
6
+
7
+ ~~~text
8
+ origen g my_pattern -e environment/sim.rb
9
+ ~~~
10
+
11
+ Most of the [common pattern API](<%= path "guides/pattern/common" %>) is supported
12
+ by OrigenSim and therefore you should expect to find the simulation environment
13
+ a drop-in replacement for your conventional ATE environment driver.
14
+
15
+ If you come across an API that OrigenSim does not support but you think that
16
+ it should, please raise a ticket here describing what you
17
+ tried to do <https://github.com/Origen-SDK/origen_sim/issues>.
18
+
19
+
20
+ #### Waiting For Events
21
+
22
+ When your pattern invokes some DUT action and you need to wait for it to complete, you
23
+ normally have two options:
24
+
25
+ * Calculate how long it should take and wait for a fixed delay
26
+ * Implement a match loop to dynamically wait for an expected response to occur
27
+
28
+ Both of these are fully supported by OrigenSim, see the
29
+ [Timing and Waiting guide](<%= path "guides/pattern/timing" %>) for more information on these APIs.
30
+
31
+ However, if your pattern generation flow is going to be supported by simulation, then you also have
32
+ a third option - to derive the required wait time from the simulation itself.
33
+
34
+ OrigenSim makes this very easy via the following API:
35
+
36
+ ~~~ruby
37
+ cc "Wait for the program command to complete"
38
+
39
+ tester.sim_delay :program_command do
40
+ dut.pin(:done).assert!(1)
41
+ end
42
+ dut.pin(:done).dont_care # Any pin assertions/reads created within the block will persist beyond it, so
43
+ # remember to clear any assertions that you don't want to carryover afterwards
44
+ ~~~
45
+
46
+ The `sim_delay` method provides the convenience of a match loop for the purposes of
47
+ delay calculation but will still generate a static pattern for the ATE. It will automatically calculate how
48
+ long the given block takes to pass and then insert that delay when later generating the pattern for an ATE.
49
+
50
+ An ID must be given to each delay, `:program_command` in this example, and if the same ID is used in multiple
51
+ calls to `sim_delay` then it means that the same delay will be used for each occurrence.
52
+
53
+ When simulating a pattern that contains `sim_delay` block(s) for the first time, the delay will
54
+ be calculated from the simulation and stored in an Org file (Origen native pattern format) within your
55
+ application's pattern directory. These files should be committed to your revision control system and considered
56
+ as part of your application.
57
+
58
+ The next time that you simulate it, the previously calculated delay will be inserted into the
59
+ pattern and therefore the simulation will be verifying that the delay is correct.
60
+
61
+ If you want to re-calculate the delays during a simulation then run with the `--sim_capture` switch:
62
+
63
+ ~~~text
64
+ origen g my_pattern -e environment/sim.rb --sim_capture
65
+ ~~~
66
+
67
+ Additional padding can be added to the calculated delay like this (all the usual `time_in_us:` style
68
+ of time options are supported):
69
+
70
+ ~~~ruby
71
+ tester.sim_delay :program_command, padding: { time_in_cycles: 10 } do
72
+ dut.pin(:done).assert!(1)
73
+ end
74
+ dut.pin(:done).dont_care # Any pin assertions/reads created within the block will persist beyond it, so
75
+ # remember to clear any assertions that you don't want to carryover afterwards
76
+ ~~~
77
+
78
+ By default, the block will be evaluated constantly until it passes when calculating the delay from
79
+ the simulation.
80
+
81
+ If the time is long and this is making your simulation run too slow, you can use lower resolution
82
+ by supplying a `:resolution` option, either as a number of cycles:
83
+
84
+
85
+ ~~~ruby
86
+ tester.sim_delay :program_command, resolution: 10 do
87
+ dut.pin(:done).assert!(1)
88
+ end
89
+ dut.pin(:done).dont_care # Any pin assertions/reads created within the block will persist beyond it, so
90
+ # remember to clear any assertions that you don't want to carryover afterwards
91
+ ~~~
92
+
93
+ or by supplying a hash filled with the usual time options:
94
+
95
+ ~~~ruby
96
+ tester.sim_delay :program_command, resolution: { time_in_ns: 50 } do
97
+ dut.pin(:done).assert!(1)
98
+ end
99
+ dut.pin(:done).dont_care # Any pin assertions/reads created within the block will persist beyond it, so
100
+ # remember to clear any assertions that you don't want to carryover afterwards
101
+ ~~~
102
+
103
+ #### Capturing Responses from the Simulation
104
+
105
+ Sometimes the response from your DUT maybe hard to predict and/or complicated to model in Origen, think about a digital data
106
+ stream response from a pin when testing a communications protocol.
107
+
108
+ OrigenSim provides an API for such a case which allows pin output values for a subset of pins/vectors
109
+ to be sampled during a simulation. The response is then captured and converted into the corresponding
110
+ expect data when the same pattern is later generated for the ATE.
111
+
112
+ Capturing is really easy, just wrap the operation you want to capture in your pattern source code like this:
113
+
114
+ ~~~ruby
115
+ tester.sim_capture :cmd55, :dout, :test_bus, :tdo do
116
+ dut.pins(:din_port).drive!(0x1234_5678)
117
+ dut.cmd.write!(0x55)
118
+ 60.cycles
119
+ end
120
+ ~~~
121
+
122
+ The first argument is an ID for the capture, this can be anything but the user must assign it.
123
+ Then supply a list of pin/pin_group IDs (or pin objects) that you want to capture.
124
+
125
+ If you use the same ID more than once it means that the same captured data will be used in multiple places.
126
+
127
+ When you add this to the pattern an error will be raised if you try to generate an ATE pattern, this will
128
+ advise that the data has not been captured yet and it must be run in a simulation first.
129
+
130
+ When you run it in a simulation for the first time, the data will be captured and stored to your application
131
+ in the `pattern/sim_capture` directory. These files should be checked into your application as if they were regular patterns.
132
+
133
+ On subsequent simulation runs, the data will not be captured but instead will be re-played from the simulation
134
+ - i.e. the pattern will assert that the DUT output matches what is in the capture file.
135
+ In other words, by adding this and then simulating twice using the same command, you are both capturing and
136
+ then verifying the captured data.
137
+
138
+ Add this switch to update the captures during a subsequent simulation run:
139
+
140
+ ~~~text
141
+ origen g my_pattern --sim_capture
142
+ ~~~
143
+
144
+ To use the captured data in an ATE pattern, simply switch to an ATE target and generate as normal.
145
+
146
+ A known limitation of this feature is that the pin state data is currently captured at the end of a cycle, not
147
+ at the point during the cycle where it will be read by the pattern.
148
+ However, if this were to be a problem in a particular application, you would see it fail when re-playing the
149
+ captured data in simulation.
150
+
151
+ #### Creating Simulation-Only Assertions
152
+
153
+ Users are of course encouraged to write patterns that test the DUT via its pin interface since such
154
+ patterns will work in physical environments like the ATE.
155
+
156
+ However, it can be useful to supplement your patterns with simulation-only assertions which peek inside
157
+ the DUT to check that it is behaving as expected. Such assertions can report useful failure information
158
+ back to the user which may help when debugging a failed pattern simulation.
159
+
160
+ ~~~ruby
161
+ # This code must be skipped when the pattern is generating for an ATE target environment
162
+ if tester.sim?
163
+ value = tester.simulator.peek("origen.dut.path.to.net").to_i[7..4]
164
+ if value != 0xA
165
+ OrigenSim.error "The internal node was #{value.to_hex} instead of 0xA!"
166
+ end
167
+ end
168
+ ~~~
169
+
170
+ Note the use of `OrigenSim.error` to report the error message, this will cause the simulation result
171
+ to be reported as a FAIL, even if all pin level assertions otherwise pass.
172
+
173
+ Also note that the value returned from the `peek` method is converted into an integer. This is because
174
+ `peek` returns an instance of [Origen::Value](<%= path "api/Origen/Value.html" %>) which can also handle
175
+ `X` or `Z` values.
176
+
177
+ So for example, if you actually wanted a given bit to be `Z` you could write your assertion as:
178
+
179
+ ~~~ruby
180
+ unless tester.simulator.peek("origen.dut.path.to.net")[4].z?
181
+ OrigenSim.error "Bit 4 of some net was not in hi-Z mode!"
182
+ end
183
+ ~~~
184
+
185
+ It is also possible to force nets within the DUT via a corresponding `poke` method:
186
+
187
+ ~~~ruby
188
+ if tester.sim?
189
+ test.simulator.poke "path.to.some.net[15:8]", 0x51
190
+ end
191
+ ~~~
192
+
193
+ % end
@@ -1,6 +1,9 @@
1
1
  database -open waves -into <%= options[:dir] %>/<%= options[:wave_file] %> -default -event
2
2
  probe -create -shm origen -depth <%= options[:depth] %> -database waves
3
3
  #probe -create -assertions -transaction origen -depth all -database waves
4
+ % Array(options[:tcl_inputs]).each do |line|
5
+ <%= line %>
6
+ % end
4
7
 
5
8
  % Hash(options[:force]).each do |net, value|
6
9
  % net = net.to_s.strip.sub(/^(origen\.|origen\.dut\.|\.)/, '')
@@ -75,6 +75,8 @@ module pin_drivers(errors, <%= dut.rtl_pins.map { |n, p, o| "#{p.id}_o" }.join('
75
75
 
76
76
  output reg [31:0] errors = 0;
77
77
  reg sync = 0;
78
+ reg [31:0] match_errors = 0;
79
+ reg match_loop = 0;
78
80
 
79
81
  always @(
80
82
 
@@ -86,7 +88,10 @@ module pin_drivers(errors, <%= dut.rtl_pins.map { |n, p, o| "#{p.id}_o" }.join('
86
88
  % end
87
89
  % end
88
90
  ) begin
89
- errors[31:0] = errors[31:0] + 1;
91
+ if (match_loop == 1)
92
+ match_errors[31:0] = match_errors[31:0] + 1;
93
+ else
94
+ errors[31:0] = errors[31:0] + 1;
90
95
  end
91
96
 
92
97
  % dut.rtl_pins.each do |name, pin, options|
@@ -101,7 +106,9 @@ module debug(errors);
101
106
  input [31:0] errors;
102
107
 
103
108
  reg [1023:0] pattern = 0;
104
- reg [1023:0] comments = 0;
109
+ % OrigenSim::NUMBER_OF_COMMENT_LINES.times do |i|
110
+ reg [1023:0] comments<%= i %> = 'h20; // Contain a space by default
111
+ % end
105
112
 
106
113
  reg handshake;
107
114
 
@@ -170,7 +177,16 @@ module origen;
170
177
  $vcdplusmemon;
171
178
  end
172
179
  `endif
173
-
180
+
181
+ `ifdef ORIGEN_FSDB
182
+ initial
183
+ begin
184
+ $fsdbDumpfile("origen.fsdb");
185
+ $fsdbDumpvars(0, "+all");
186
+ end
187
+ `endif
188
+
189
+
174
190
  always @(posedge finish) begin
175
191
  //$display("********************************");
176
192
  //$display("Finishing simulation...");
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Origen - Guides
3
+ ---
4
+ <%= render "templates/web/partials/navbar.html" %>
5
+
6
+ %# Add/edit sections here, the code below will expand this with the correct markup,
7
+ %# pass in the topic you want selected via the :tab option.
8
+ % i = OrigenDocHelpers::GuideIndex.new
9
+ % Origen.app.config.shared[:origen_guides_index].call(i)
10
+
11
+ % render "doc_helpers/searchable.html", options.merge(index: i, root: "", prompt: "Search the guides...") do
12
+
13
+ <%= yield %>
14
+
15
+ % end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_sim
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.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-06-28 00:00:00.000000000 Z
11
+ date: 2018-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.33.3
19
+ version: 0.35.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.33.3
26
+ version: 0.35.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: origen_testers
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -75,6 +75,7 @@ files:
75
75
  - ext/origen.h
76
76
  - ext/vpi_user.h
77
77
  - lib/origen_sim.rb
78
+ - lib/origen_sim/artifacts.rb
78
79
  - lib/origen_sim/commands/build.rb
79
80
  - lib/origen_sim/commands/ci.rb
80
81
  - lib/origen_sim/commands/co.rb
@@ -98,12 +99,24 @@ files:
98
99
  - program/p1.rb
99
100
  - program/p2.rb
100
101
  - templates/empty.gtkw
102
+ - templates/empty.rc
101
103
  - templates/empty.svcf
102
104
  - templates/empty.tcl
105
+ - templates/origen_guides/simulation/app.md.erb
106
+ - templates/origen_guides/simulation/artifacts.md.erb
107
+ - templates/origen_guides/simulation/compiling.md.erb
108
+ - templates/origen_guides/simulation/debugging.md.erb
109
+ - templates/origen_guides/simulation/environment.md.erb
110
+ - templates/origen_guides/simulation/flows.md.erb
111
+ - templates/origen_guides/simulation/howitworks.md.erb
112
+ - templates/origen_guides/simulation/introduction.md.erb
113
+ - templates/origen_guides/simulation/log.md.erb
114
+ - templates/origen_guides/simulation/patterns.md.erb
103
115
  - templates/probe.tcl.erb
104
116
  - templates/rtl_v/origen.v.erb
105
117
  - templates/web/index.md.erb
106
118
  - templates/web/layouts/_basic.html.erb
119
+ - templates/web/layouts/_guides.html.erb
107
120
  - templates/web/partials/_navbar.html.erb
108
121
  - templates/web/release_notes.md.erb
109
122
  homepage:
@@ -125,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
138
  version: 1.8.11
126
139
  requirements: []
127
140
  rubyforge_project:
128
- rubygems_version: 2.6.14.1
141
+ rubygems_version: 2.7.7
129
142
  signing_key:
130
143
  specification_version: 4
131
144
  summary: Plugin that provides a testbench environment to simulate Origen test patterns