origen_sim 0.16.1 → 0.20.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.
- checksums.yaml +4 -4
- data/config/application.rb +2 -0
- data/config/commands.rb +29 -20
- data/config/version.rb +2 -2
- data/ext/bridge.c +72 -14
- data/ext/origen.c +29 -17
- data/ext/origen.h +6 -0
- data/ext/origen_tasks.tab +2 -0
- data/lib/origen_sim/commands/build.rb +90 -59
- data/lib/origen_sim/origen/pins/pin.rb +38 -0
- data/lib/origen_sim/origen/top_level.rb +8 -3
- data/lib/origen_sim/simulation.rb +1 -1
- data/lib/origen_sim/simulator/user_details.rb +0 -1
- data/lib/origen_sim/simulator.rb +70 -70
- data/lib/origen_sim/tester.rb +53 -10
- data/lib/origen_sim_dev/dut.rb +66 -46
- data/lib/origen_sim_dev/ip.rb +15 -8
- data/pattern/concurrent_ip.rb +17 -0
- data/pattern/test.rb +122 -10
- data/templates/empty.rc +16 -26
- data/templates/origen_guides/simulation/ams.md.erb +141 -0
- data/templates/origen_guides/simulation/compiling.md.erb +52 -7
- data/templates/origen_guides/simulation/debugging.md.erb +1 -1
- data/templates/origen_guides/simulation/direct.md.erb +112 -0
- data/templates/origen_guides/simulation/environment.md.erb +6 -3
- data/templates/origen_guides/simulation/patterns.md.erb +2 -7
- data/templates/rtl_v/origen.v.erb +114 -12
- metadata +13 -9
data/pattern/test.rb
CHANGED
@@ -2,6 +2,30 @@ Pattern.create do
|
|
2
2
|
IDCODE = 0b0010
|
3
3
|
DEBUG = 0b1000
|
4
4
|
|
5
|
+
# Peeks the given net and will fail if the returned value does not equal the expected
|
6
|
+
def peek(net, expected)
|
7
|
+
if expected.is_a?(Integer)
|
8
|
+
actual = tester.peek(net)
|
9
|
+
else
|
10
|
+
actual = tester.peek_real(net)
|
11
|
+
end
|
12
|
+
if actual
|
13
|
+
if expected.is_a?(Integer)
|
14
|
+
actual = actual.to_i
|
15
|
+
actual_str = actual.try(:to_hex) || 'nil'
|
16
|
+
expected_str = expected.to_hex
|
17
|
+
else
|
18
|
+
actual_str = actual ? actual.to_s : 'nil'
|
19
|
+
expected_str = expected.to_s
|
20
|
+
end
|
21
|
+
unless actual == expected
|
22
|
+
OrigenSim.error "Expected to peek #{expected_str} from #{net}, got #{actual_str}!"
|
23
|
+
end
|
24
|
+
else
|
25
|
+
OrigenSim.error "Nothing returned from peek of #{net}!"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
5
29
|
ss "Some basic shift operations to verify functionality"
|
6
30
|
dut.jtag.write_ir(0x0, size: 4)
|
7
31
|
dut.jtag.read_ir(0x0, size: 4)
|
@@ -39,26 +63,111 @@ Pattern.create do
|
|
39
63
|
dut.cmd.read!(0x1234_5678)
|
40
64
|
|
41
65
|
if tester.sim?
|
66
|
+
ss "Test poking a register value"
|
42
67
|
tester.simulator.poke("dut.cmd", 0x1122_3344)
|
43
68
|
dut.cmd.read!(0x1122_3344)
|
69
|
+
|
70
|
+
ss "Test peeking a register value"
|
71
|
+
peek("dut.cmd", 0x1122_3344)
|
72
|
+
|
73
|
+
ss "Test forcing a value"
|
74
|
+
tester.force("dut.cmd", 0x2222_3333)
|
75
|
+
dut.cmd.read!(0x2222_3333)
|
76
|
+
peek("dut.cmd", 0x2222_3333)
|
77
|
+
dut.cmd.write!(0x1234_5678)
|
78
|
+
dut.cmd.read!(0x2222_3333)
|
79
|
+
|
80
|
+
ss "Test releasing a forced value"
|
81
|
+
tester.release("dut.cmd")
|
82
|
+
dut.cmd.write!(0x1234_5678)
|
83
|
+
dut.cmd.read!(0x1234_5678)
|
84
|
+
|
85
|
+
ss "Test poking a real value"
|
86
|
+
tester.poke("dut.real_val", 1.25)
|
87
|
+
10.cycles
|
88
|
+
|
89
|
+
ss "Verify that the memory can be accessed"
|
90
|
+
dut.mem(0x1000_0000).write!(0x1234_5678)
|
91
|
+
dut.mem(0x1000_0000).read!(0x1234_5678)
|
92
|
+
|
93
|
+
ss "Test poking a memory"
|
94
|
+
tester.poke("dut.mem[1]", 0x1111_2222)
|
95
|
+
dut.mem(0x1000_0004).read!(0x1111_2222)
|
96
|
+
|
97
|
+
ss "Test peeking a memory"
|
98
|
+
tester.poke("dut.mem[2]", 0x1111_2222)
|
99
|
+
peek("dut.mem[2]", 0x1111_2222)
|
100
|
+
|
101
|
+
ss "Test peeking and poking a wide memory"
|
102
|
+
tester.poke("dut.wide_mem[2]", 0x1FF_1111_2222_3333_4444_5555_6666_7777_8888)
|
103
|
+
peek("dut.wide_mem[2]", 0x1FF_1111_2222_3333_4444_5555_6666_7777_8888)
|
104
|
+
|
105
|
+
# Peek (or force?) a real value not working on Icarus, can't get it to work but not
|
106
|
+
# spending much time on it since this is mainly useful in a WREAL simulation and other
|
107
|
+
# things don't work that are blocking that anyway
|
108
|
+
unless tester.simulator.config[:vendor] == :icarus
|
109
|
+
ss "Test peeking a real value"
|
110
|
+
peek("dut.real_val", 1.25)
|
111
|
+
10.cycles
|
112
|
+
|
113
|
+
ss "Test forcing a real value"
|
114
|
+
tester.force("dut.real_val", 2.25)
|
115
|
+
10.cycles
|
116
|
+
peek("dut.real_val", 2.25)
|
117
|
+
|
118
|
+
ss "Test releasing a forced real value"
|
119
|
+
tester.poke("dut.real_val", 1.25)
|
120
|
+
10.cycles
|
121
|
+
peek("dut.real_val", 2.25)
|
122
|
+
tester.release("dut.real_val")
|
123
|
+
10.cycles
|
124
|
+
peek("dut.real_val", 2.25)
|
125
|
+
tester.poke("dut.real_val", 1.25)
|
126
|
+
10.cycles
|
127
|
+
peek("dut.real_val", 1.25)
|
128
|
+
end
|
129
|
+
|
130
|
+
if tester.simulator.wreal?
|
131
|
+
ss "Test analog pin API by ramping dut.vdd"
|
132
|
+
v = 0
|
133
|
+
dut.power_pin(:vdd).drive!(v)
|
134
|
+
dut.ana_test.vdd_valid.read!(0)
|
135
|
+
until v >= 1.25
|
136
|
+
v += 0.05
|
137
|
+
dut.power_pin(:vdd).drive!(v)
|
138
|
+
end
|
139
|
+
dut.ana_test.vdd_valid.read!(1)
|
140
|
+
100.cycles
|
141
|
+
|
142
|
+
ss "Test analog pin measure API"
|
143
|
+
dut.ana_test.vdd_div4.write!(1)
|
144
|
+
measured = dut.pin(:ana).measure
|
145
|
+
if measured != 0.3125
|
146
|
+
OrigenSim.error "Expected to measure 0.3125V from the ana pin, got #{measured}V!"
|
147
|
+
end
|
148
|
+
|
149
|
+
ss "Test the different analog mux functions"
|
150
|
+
dut.ana_test.write(0)
|
151
|
+
dut.ana_test.vdd_div4.write!(1)
|
152
|
+
1000.cycles
|
153
|
+
dut.ana_test.write(0)
|
154
|
+
dut.ana_test.bgap_out.write!(1)
|
155
|
+
1000.cycles
|
156
|
+
dut.ana_test.write(0)
|
157
|
+
dut.ana_test.osc_out.write!(1)
|
158
|
+
1000.cycles
|
159
|
+
end
|
44
160
|
end
|
45
161
|
|
46
162
|
ss "Test storing a register"
|
47
163
|
dut.cmd.write!(0x2244_6688)
|
48
164
|
Origen.log.info "Should be within 'Test storing a register'"
|
49
165
|
dut.cmd.store!
|
50
|
-
|
51
166
|
if tester.sim?
|
52
|
-
|
53
|
-
|
54
|
-
unless capture_value == 0x11662244 # 0x2244_6688 reversed
|
55
|
-
if capture_value
|
56
|
-
OrigenSim.error "Captured #{capture_value.to_hex} instead of 0x11662244!"
|
57
|
-
else
|
58
|
-
OrigenSim.error "Nothing captured instead of 0x11662244!"
|
59
|
-
end
|
60
|
-
end
|
167
|
+
peek("origen.pins.tdo.memory", 0x11662244) # 0x2244_6688 reversed
|
168
|
+
end
|
61
169
|
|
170
|
+
if tester.sim?
|
62
171
|
ss "Test sync of a register"
|
63
172
|
dut.cmd.write(0) # Make Origen forget the actual value
|
64
173
|
dut.cmd.sync
|
@@ -75,6 +184,9 @@ Pattern.create do
|
|
75
184
|
unless dut.parallel_read.data == 0x7707_7077
|
76
185
|
OrigenSim.error "PARALLEL_READ register did not sync from simulation"
|
77
186
|
end
|
187
|
+
|
188
|
+
#ss "Test reading an X register value"
|
189
|
+
#dut.x_reg.read!(0)
|
78
190
|
end
|
79
191
|
|
80
192
|
ss "Do some operations with the counter, just for fun"
|
data/templates/empty.rc
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
Magic 271485
|
2
|
-
Revision
|
2
|
+
Revision Verdi_O-2018.09-SP2-1
|
3
3
|
|
4
4
|
; Window Layout <x> <y> <width> <height> <signalwidth> <valuewidth>
|
5
|
-
viewPort 0 28 1450 327 288 65
|
6
5
|
|
7
6
|
; File list:
|
8
7
|
; openDirFile [-d delimiter] [-s time_offset] [-rf auto_bus_rule_file] path_name file_name
|
9
|
-
openDirFile -d / "" ""
|
10
8
|
|
11
9
|
; file time scale:
|
12
10
|
; fileTimeScale ### s|ms|us|ns|ps
|
@@ -18,16 +16,11 @@ signalSpacing 5
|
|
18
16
|
windowTimeUnit 1ns
|
19
17
|
|
20
18
|
; waveform viewport range
|
21
|
-
zoom 0.000000 4013756.949425 1n
|
22
|
-
cursor 10096.000000
|
23
|
-
marker 0.000000
|
24
19
|
|
25
20
|
; user define markers
|
26
21
|
; userMarker time_pos marker_name color linestyle
|
27
22
|
; visible top row signal index
|
28
|
-
top 0
|
29
23
|
; marker line index
|
30
|
-
markerPos 6
|
31
24
|
|
32
25
|
; event list
|
33
26
|
; addEvent event_name event_expression
|
@@ -47,37 +40,34 @@ COMPLEX_EVENT_END
|
|
47
40
|
curSTATUS ByChange
|
48
41
|
|
49
42
|
|
50
|
-
activeDirFile "" ""
|
51
43
|
addGroup "Debug"
|
52
|
-
addSignal -h 15
|
44
|
+
addSignal -h 15 /origen/debug/marker[15:0]
|
45
|
+
addSignal -h 15 -holdScope handshake
|
53
46
|
addSignal -h 15 -UNSIGNED -ASC -holdScope pattern[1023:0]
|
54
|
-
|
55
|
-
addSignal -h 15 -UNSIGNED -ASC /origen/debug/
|
56
|
-
addSignal -h 15 -UNSIGNED -ASC
|
57
|
-
addSignal -h 15 -UNSIGNED -ASC
|
58
|
-
addSignal -h 15 -UNSIGNED -ASC
|
59
|
-
addSignal -h 15 -UNSIGNED -ASC
|
60
|
-
addSignal -h 15 -UNSIGNED -ASC
|
61
|
-
addSignal -h 15 -UNSIGNED -ASC
|
62
|
-
addSignal -h 15 -UNSIGNED -ASC
|
63
|
-
addSignal -h 15 -UNSIGNED -ASC
|
64
|
-
addSignal -h 15 -UNSIGNED -ASC
|
47
|
+
addSubGroup "Comments"
|
48
|
+
addSignal -h 15 -UNSIGNED -ASC /origen/debug/comments0[1023:0]
|
49
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments1[1023:0]
|
50
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments2[1023:0]
|
51
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments3[1023:0]
|
52
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments4[1023:0]
|
53
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments5[1023:0]
|
54
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments6[1023:0]
|
55
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments7[1023:0]
|
56
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments8[1023:0]
|
57
|
+
addSignal -h 15 -UNSIGNED -ASC -holdScope comments9[1023:0]
|
58
|
+
endSubGroup "Comments"
|
59
|
+
addSignal -h 15 -UNSIGNED -UDEC /origen/debug/errors[31:0]
|
65
60
|
addGroup "DUT"
|
66
61
|
|
67
62
|
; getSignalForm Scope Hierarchy Status
|
68
63
|
; active file of getSignalForm
|
69
|
-
activeDirFile "" ""
|
70
64
|
|
71
65
|
GETSIGNALFORM_SCOPE_HIERARCHY_BEGIN
|
72
66
|
getSignalForm close
|
73
67
|
|
74
|
-
"/FSN_DLLDELAY_1"
|
75
68
|
"/origen"
|
76
69
|
|
77
70
|
SCOPE_LIST_BEGIN
|
78
|
-
"/testbench/msf1"
|
79
|
-
"/FSN_DLLDELAY_1"
|
80
|
-
"/testbench"
|
81
71
|
"/origen"
|
82
72
|
"/origen/dut"
|
83
73
|
"/origen/debug"
|
@@ -0,0 +1,141 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
OrigenSim supports analog/mixed-signal (AMS) simulations via real-number modeling (RNM), whereby
|
4
|
+
top-level pins can be defined as real wire types (WREALs) and then Origen APIs can be used to drive
|
5
|
+
and measure real number values from them.
|
6
|
+
|
7
|
+
By default, OrigenSim's built in simulation setups will run a digital simulation, allowing such real number
|
8
|
+
inputs to be used by behavioral models within that DUT which can themselves output real numbers to be
|
9
|
+
observed on the DUT's pins by Origen APIs.
|
10
|
+
|
11
|
+
The DUT could also contain full electical models which consume the real number inputs, in that
|
12
|
+
case a [custom simulation configuration](<%= path "guides/simulation/environment/#Custom_Simulator_Configuration" %>)
|
13
|
+
will be required to define the run command to start the simulation.
|
14
|
+
|
15
|
+
#### Building Support for AMS Simulation
|
16
|
+
|
17
|
+
AMS support must be added in when building the testbench, this is done by adding the `--wreal` switch to the
|
18
|
+
`sim:build` command:
|
19
|
+
|
20
|
+
~~~text
|
21
|
+
origen sim:build path/to/my_dut.v --wreal
|
22
|
+
~~~
|
23
|
+
|
24
|
+
By adding this switch, any pins which are defined as `wreal` types within the given top level will be assigned
|
25
|
+
an analog pin driver by the testbench rather than a digital driver which is the default.
|
26
|
+
|
27
|
+
Pins can be defined as a `wreal` type either by adding the `real` type to their definition:
|
28
|
+
|
29
|
+
~~~verilog
|
30
|
+
input real vddc,
|
31
|
+
~~~
|
32
|
+
|
33
|
+
or by adding a `wreal` wire within the module body:
|
34
|
+
|
35
|
+
~~~verilog
|
36
|
+
wreal vddc;
|
37
|
+
~~~
|
38
|
+
|
39
|
+
Here is an example which uses both approaches to declare the `vdd` and `ana` pins as analog pins whenever
|
40
|
+
the `USE_WREAL` define is enabled:
|
41
|
+
|
42
|
+
~~~verilog
|
43
|
+
module my_dut(
|
44
|
+
input tck, tdi, tms, trstn,
|
45
|
+
input rstn,
|
46
|
+
input [31:0] din,
|
47
|
+
input p1,
|
48
|
+
input p2,
|
49
|
+
`ifdef USE_WREAL
|
50
|
+
inout real vdd,
|
51
|
+
`else
|
52
|
+
inout vdd,
|
53
|
+
`endif
|
54
|
+
|
55
|
+
output tdo,
|
56
|
+
output done,
|
57
|
+
output [15:0] test_bus,
|
58
|
+
output [31:0] dout,
|
59
|
+
output ana
|
60
|
+
);
|
61
|
+
|
62
|
+
`ifdef USE_WREAL
|
63
|
+
wreal ana;
|
64
|
+
`endif
|
65
|
+
endmodule
|
66
|
+
~~~
|
67
|
+
|
68
|
+
A digital testbench for this would be built via this command:
|
69
|
+
|
70
|
+
~~~text
|
71
|
+
origen sim:build path/to/my_dut.v
|
72
|
+
~~~
|
73
|
+
|
74
|
+
while AMS support would be added by running:
|
75
|
+
|
76
|
+
~~~text
|
77
|
+
origen sim:build path/to/my_dut.v --wreal --define USE_WREAL
|
78
|
+
~~~
|
79
|
+
|
80
|
+
#### Origen Application Configuration
|
81
|
+
|
82
|
+
Within the corresponding Origen DUT model of the design, the wreal pins should be declared as either an
|
83
|
+
analog, power or ground pins.
|
84
|
+
|
85
|
+
From the above example, the wreal pins could be modeled like this:
|
86
|
+
|
87
|
+
~~~ruby
|
88
|
+
add_power_pin :vdd # Could also be a regular analog pin too, if you prefer
|
89
|
+
|
90
|
+
add_pin :ana, type: :analog
|
91
|
+
~~~
|
92
|
+
|
93
|
+
See the [Pins Guide](<%= path "guides/models/pins" %>) for more information on modeling pins in Origen.
|
94
|
+
|
95
|
+
#### AMS APIs
|
96
|
+
|
97
|
+
With all of the AMS configuration done, real values can now be driven and read from Origen application code
|
98
|
+
during a simulation like this:
|
99
|
+
|
100
|
+
~~~ruby
|
101
|
+
dut.power_pin(:vdd).drive(1.25)
|
102
|
+
|
103
|
+
dut.pin(:ana).read # => 0.7
|
104
|
+
|
105
|
+
# .measure is available as an alias of read for analog pins
|
106
|
+
dut.pin(:ana).measure # => 0.7
|
107
|
+
~~~
|
108
|
+
|
109
|
+
The `peek`, `poke` and `force` methods from [the Direct DUT Manipulation APIs](<%= path "guides/simulation/direct" %>) are
|
110
|
+
also available to manipulate real valued nets during simulation.
|
111
|
+
|
112
|
+
The analog pin APIs will not work correctly when generating a pattern for an ATE and the application code is
|
113
|
+
responsible for handling them safely, typically like this:
|
114
|
+
|
115
|
+
~~~ruby
|
116
|
+
# Example of a simulation-only assertion
|
117
|
+
if tester.sim?
|
118
|
+
measured = dut.pin(:ana).measure
|
119
|
+
if measured != 0.3125
|
120
|
+
OrigenSim.error "Expected to measure 0.3125V from the ana pin, got #{measured}V!"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
~~~
|
124
|
+
|
125
|
+
It is easy to build more complex functionality in your application code from these simple APIs, for example to
|
126
|
+
ramp a vdd pin:
|
127
|
+
|
128
|
+
~~~ruby
|
129
|
+
# Ramp up the power on VDD
|
130
|
+
v = 0
|
131
|
+
dut.power_pin(:vdd).drive!(v)
|
132
|
+
until v >= 1.25
|
133
|
+
v += 0.05
|
134
|
+
dut.power_pin(:vdd).drive!(v) # Note the use of drive! here which will generate a cycle
|
135
|
+
end
|
136
|
+
~~~
|
137
|
+
|
138
|
+
It is hoped that the community will contribute plugins that contain higher-level functionality like this
|
139
|
+
to make such functions available off-the-shelf in the future.
|
140
|
+
|
141
|
+
% end
|
@@ -81,7 +81,55 @@ origen sim:build path/to/my_top_level.v
|
|
81
81
|
top-level pin interface and reducing the amount of superfluous design code will reduce the chance
|
82
82
|
of parse errors during this step.**
|
83
83
|
|
84
|
-
|
84
|
+
For example, something like this is sufficient to be able to generate an Origen test bench:
|
85
|
+
|
86
|
+
~~~verilog
|
87
|
+
module my_dut(
|
88
|
+
input tck, tdi, tms, trstn,
|
89
|
+
input rstn,
|
90
|
+
input [31:0] din,
|
91
|
+
input p1,
|
92
|
+
input p2,
|
93
|
+
inout vdd,
|
94
|
+
|
95
|
+
output tdo,
|
96
|
+
output done,
|
97
|
+
output [15:0] test_bus,
|
98
|
+
output [31:0] dout,
|
99
|
+
output ana
|
100
|
+
);
|
101
|
+
|
102
|
+
endmodule
|
103
|
+
~~~
|
104
|
+
|
105
|
+
If you find that it does choke on your design files please do enter a ticket describing the code
|
106
|
+
which failed to parse here - <https://github.com/Origen-SDK/origen_verilog/issues>
|
107
|
+
|
108
|
+
In most cases any parse issues can be resolved by moving to a stub model like above or by simply removing the
|
109
|
+
offending code to create a partial stub.
|
110
|
+
|
111
|
+
The `sim:build` command does have some rudimentary support for evaluating and applying Verilog compiler
|
112
|
+
directive rules, though at the time of writing it does not evaluate Verilog parameters.
|
113
|
+
|
114
|
+
For example if your code contained something like this:
|
115
|
+
|
116
|
+
~~~verilog
|
117
|
+
output [`DATA_WIDTH-1:0] dout;
|
118
|
+
~~~
|
119
|
+
|
120
|
+
Then you can define it on the command line like this:
|
121
|
+
|
122
|
+
~~~text
|
123
|
+
origen sim:build path/to/my_dut.v --define DATA_WIDTH=8
|
124
|
+
~~~
|
125
|
+
|
126
|
+
Multiple defines should be specified like this:
|
127
|
+
|
128
|
+
~~~text
|
129
|
+
origen sim:build path/to/my_dut.v --define DATA_WIDTH=8 --define WREAL
|
130
|
+
~~~
|
131
|
+
|
132
|
+
Multiple files can be passed in, for example to include defines contained in a file rather than via the command line:
|
85
133
|
|
86
134
|
~~~text
|
87
135
|
origen sim:build path/to/my_defines.v path/to/my_top_level.v
|
@@ -93,14 +141,11 @@ If you prefer, it also works by supplying the source file directory path(s) sepa
|
|
93
141
|
origen sim:build my_defines.v my_top_level.v -s path/to
|
94
142
|
~~~
|
95
143
|
|
96
|
-
|
97
|
-
directive rules, though at the time of writing it does not evaluate Verilog parameters.
|
144
|
+
Run `origen sim:build -h` to see the additional switches that are supported.
|
98
145
|
|
99
|
-
|
100
|
-
|
146
|
+
Also refer to [AMS Support](<%= path "guides/simulation/ams" %>) for details on how to enable analog/mixed-signal support when
|
147
|
+
building the testbench.
|
101
148
|
|
102
|
-
In most cases any parse issues can be resolved by moving to a stub model or by simply removing the
|
103
|
-
offending code to create a partial stub.
|
104
149
|
|
105
150
|
Once you see a message like this, you are ready to move onto the next step:
|
106
151
|
|
@@ -160,7 +160,7 @@ Note that flushing will internally call a `sync_up` so you don't have to do both
|
|
160
160
|
The methods `tester.simulator.peek` and `tester.simulator.poke` are available for reading and writing values
|
161
161
|
to internal DUT nets respectively.
|
162
162
|
|
163
|
-
See the section on [
|
163
|
+
See the section on [Direct DUT Manipulation](<%= path "guides/simulation/direct" %>)
|
164
164
|
for more details on these.
|
165
165
|
|
166
166
|
#### Register Reading (and Writing)
|
@@ -0,0 +1,112 @@
|
|
1
|
+
% render "layouts/guides.html" do
|
2
|
+
|
3
|
+
A number of methods exist to directly manipulate the state of the DUT during a simulation, in all
|
4
|
+
cases these methods do not re-target to the ATE because they rely on being able to directly look inside
|
5
|
+
and manipulate the DUT which is not possible in the physical world.
|
6
|
+
|
7
|
+
The user is responsible for ensuring that the use of these APIs is safely handled when generating for
|
8
|
+
an ATE or other non-simulation target, normally via one of these constructs:
|
9
|
+
|
10
|
+
~~~ruby
|
11
|
+
# Simply skip this unless simulating
|
12
|
+
unless tester.sim?
|
13
|
+
tester.peek # ...
|
14
|
+
end
|
15
|
+
|
16
|
+
# Implement differently for ATE
|
17
|
+
if tester.sim?
|
18
|
+
tester.poke # ...
|
19
|
+
else
|
20
|
+
dut.do_something
|
21
|
+
end
|
22
|
+
~~~
|
23
|
+
|
24
|
+
#### Poke
|
25
|
+
|
26
|
+
Poking is the term commonly given to changing the value of a register or other variable, i.e. poking a new
|
27
|
+
value into an existing storage element.
|
28
|
+
|
29
|
+
To use the `poke` method, supply the net path of the storage element to be changed and the value you want to
|
30
|
+
change it to:
|
31
|
+
|
32
|
+
~~~ruby
|
33
|
+
# Poking a register
|
34
|
+
tester.poke("dut.my_ip.user_regs.some_reg", 0x1111)
|
35
|
+
|
36
|
+
# Poking a memory
|
37
|
+
tester.poke("dut.my_ip.mem[15]", 0x1111_2222)
|
38
|
+
~~~
|
39
|
+
|
40
|
+
The poke method can be used on real variables too, in that case a float should be given as the second
|
41
|
+
argument instead of an integer to indicate to Origen that a real value net is being poked. e.g. to poke
|
42
|
+
the value `1` to a real value net then supply `1.0` as the value argument instead of `1`.
|
43
|
+
|
44
|
+
~~~ruby
|
45
|
+
tester.poke("dut.my_ip.my_real_var", 1.25)
|
46
|
+
~~~
|
47
|
+
|
48
|
+
#### Peek
|
49
|
+
|
50
|
+
Peeking allows you to read the value of an internal register or other variable.
|
51
|
+
|
52
|
+
The value returned from the `peek` method will be
|
53
|
+
an instance of [Origen::Value](<%= path "api/Origen/Value.html" %>) which can also handle
|
54
|
+
`X` or `Z` values.
|
55
|
+
|
56
|
+
Normally, if you don't care about catching `Z` or `X` cases you can simply call `to_i` on the value
|
57
|
+
returned from `peek`, here are some examples:
|
58
|
+
|
59
|
+
~~~ruby
|
60
|
+
# Peeking a register
|
61
|
+
tester.peek("dut.my_ip.user_regs.some_reg").to_i # => 0x1111
|
62
|
+
|
63
|
+
# Peeking a memory
|
64
|
+
tester.peek("dut.my_ip.mem[15]").to_i # => 0x1111_2222
|
65
|
+
~~~
|
66
|
+
|
67
|
+
When peeking a real number, `X` or `Z` states are not supported and a float will be returned.
|
68
|
+
|
69
|
+
You must indicate to Origen that you are peeking a real value by supplying a second argument of `true`,
|
70
|
+
or for convenience calling `peek_real` instead:
|
71
|
+
|
72
|
+
~~~ruby
|
73
|
+
tester.peek("dut.my_ip.my_real_var", true) # => 1.25
|
74
|
+
|
75
|
+
tester.peek_real("dut.my_ip.my_real_var") # => 1.25
|
76
|
+
~~~
|
77
|
+
|
78
|
+
#### Force
|
79
|
+
|
80
|
+
When poking the DUT, you are changing the value
|
81
|
+
of a reg or other variable which provides drive. i.e. as soon as the `poke` operation is done, the responsibility
|
82
|
+
for maintaining and driving the new value is down to the DUT.
|
83
|
+
For this reason, you cannot just poke any net, only those which can store/drive state. In Verilog terms, you can
|
84
|
+
poke a register but you can't poke a wire.
|
85
|
+
|
86
|
+
With a force, the simulator provides infinite drive/storage of the forced value and this will override any drive
|
87
|
+
produced in the DUT.
|
88
|
+
So when you force a value on a net, that will persist there for the entire simulation regardless of what goes on
|
89
|
+
in the DUT until the force is released.
|
90
|
+
|
91
|
+
The `force` method has the same arguments as the `peek` method:
|
92
|
+
|
93
|
+
~~~ruby
|
94
|
+
# Forcing a register
|
95
|
+
tester.force("dut.my_ip.user_regs.some_reg", 0x1111)
|
96
|
+
|
97
|
+
# Forcing a memory
|
98
|
+
tester.force("dut.my_ip.mem[15]", 0x1111_2222)
|
99
|
+
|
100
|
+
# Forcing a real value
|
101
|
+
tester.force("dut.my_ip.my_real_var", 1.25)
|
102
|
+
~~~
|
103
|
+
|
104
|
+
A force can be released by calling the `release` method and supplying the net reference:
|
105
|
+
|
106
|
+
~~~ruby
|
107
|
+
# Releasing an existing force
|
108
|
+
tester.release("dut.my_ip.user_regs.some_reg")
|
109
|
+
~~~
|
110
|
+
|
111
|
+
|
112
|
+
% end
|
@@ -115,9 +115,12 @@ OrigenSim.cadence do |sim|
|
|
115
115
|
end
|
116
116
|
~~~
|
117
117
|
|
118
|
-
####
|
118
|
+
#### Custom Simulator Configuration
|
119
119
|
|
120
|
-
A
|
120
|
+
A custom simulator configuration allows you to use a tool that is not supported out of the box by <code>OrigenSim</code>,
|
121
|
+
or to setup a more advanced simulation run command such as that required to run an analog-digital co-simulation if your
|
122
|
+
DUT contains full electrical models of some IPs.
|
123
|
+
For these, it
|
121
124
|
is your responsibility to provide the command to start the simulation process, however, this allows for arbitrary commands to
|
122
125
|
start the process and allows end users to still use <code>origen g</code> as if with a fully <code>OrigenSim</code> supported
|
123
126
|
simulator configuration.
|
@@ -139,7 +142,7 @@ Here is an example using the predecessor of the supported Cadence tool <code>iru
|
|
139
142
|
OrigenSim.generic do |sim|
|
140
143
|
sim.testbench_top 'na_origen'
|
141
144
|
sim.generic_run_cmd do |s|
|
142
|
-
"ncsim na_origen -loadpli origen.so:
|
145
|
+
"ncsim na_origen -loadpli origen.so:origen_init +socket+#{s.socket_id}"
|
143
146
|
end
|
144
147
|
end
|
145
148
|
~~~
|
@@ -217,12 +217,7 @@ unless tester.simulator.peek("origen.dut.path.to.net")[4].z?
|
|
217
217
|
end
|
218
218
|
~~~
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
~~~ruby
|
223
|
-
if tester.sim?
|
224
|
-
test.simulator.poke "path.to.some.net[15:8]", 0x51
|
225
|
-
end
|
226
|
-
~~~
|
220
|
+
See the [Direct DUT Manipulation](<%= path "guides/simulation/direct" %>) guide for more details on these
|
221
|
+
APIs.
|
227
222
|
|
228
223
|
% end
|