origen_sim 0.16.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|