Add additional examples of Verilog co-simulation and share the Verilog
source and large parts of the example circuits between Verilator and Icarus Verilog. Verilog source file adc.v has improved style: all assignments in the always block are now non-blocking.
This commit is contained in:
parent
64a9a0bfbc
commit
35968d1da6
|
|
@ -0,0 +1,10 @@
|
|||
Verilog-controlled simple timer.
|
||||
|
||||
* This is the model for an RS flip-flop implemented by Icarus Verilog.
|
||||
|
||||
.model vlog_ff d_cosim simulation="ivlng" sim_args=["555"]
|
||||
|
||||
* The bulk of the circuit is in a shared file.
|
||||
|
||||
.include ../verilator/555.shared
|
||||
.end
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
The circuits in this directory illustrate the use of the d_cosim
|
||||
XSPICE code model as a container for a Verilog simulation using
|
||||
Icarus Verilog. Icarus Verilog must be built with the --enable-libvvp option,
|
||||
so that its simulation engine is available as a dynamic library.
|
||||
The Verilog source code and included parts of the circuit definitions
|
||||
can be found in the adjacent "verilator" directory.
|
||||
|
||||
The example circuits are:
|
||||
|
||||
555.cir: The probably familiar NE555 oscillator provides a minimal example
|
||||
of combined simulation with SPICE and Verilog.
|
||||
The digital part of the IC, a simple SR flip-flop, is expressed in Verilog.
|
||||
|
||||
delay.v: A very simple example of using delays in Verilog to generate
|
||||
waveform outputs.
|
||||
|
||||
pwm.c: Verilog delays controlling a pulse-width modulated output generate
|
||||
an approximate sine wave.
|
||||
|
||||
adc.cir: Slightly more complex Verilog describes the controlling part
|
||||
of a switched-capacitor ADC.
|
||||
|
||||
Before a simulation can be run, the associated Verilog code must be compiled:
|
||||
|
||||
iverilog -o 555 ../verilator/555.v
|
||||
|
||||
Similar compilations are needed to prepare the other examples.
|
||||
|
||||
The simulations require additional dynamic libraries, ivlng.so (or ivlng.DLL)
|
||||
and ivlng.vpi: they are expected to be in the usual installation location.
|
||||
|
||||
To use the versions in a built source tree that has not been installed,
|
||||
the .model definitions in the circuit files must be changed to the ugly:
|
||||
|
||||
.model vlog_ff d_cosim sim_args=["555"]
|
||||
+ simulation = "../../../release/src/xspice/verilog/.libs/ivlng"
|
||||
+ lib_args = [ "libvvp"
|
||||
+ "../../../release/src/xspice/verilog/.libs/ivlngvpi.so" ]
|
||||
|
||||
Or for Windows builds using MSVC:
|
||||
|
||||
.model vlog_ff d_cosim sim_args=["555"]
|
||||
+ simulation = "..\..\..\visualc\xspice\verilog\ivlng.DLL"
|
||||
+ lib_args = [ "libvvp"
|
||||
+ "..\..\..\visualc\xspice\verilog\shim.vpi" ]
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim
|
||||
|
||||
* Model line for the digital control implemented by Icarus Verilog.
|
||||
|
||||
.model dut d_cosim simulation="ivlng" sim_args=["adc"]
|
||||
|
||||
* The bulk of the circuit is in a shared file.
|
||||
|
||||
.include ../verilator/adc.shared
|
||||
.end
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
* Waveform generation by Verilog delays
|
||||
|
||||
adut null [ d4 d3 d2 d1 d0 ] ring
|
||||
.model ring d_cosim simulation="ivlng" sim_args = [ "delay" ]
|
||||
|
||||
.control
|
||||
tran 20u 100u
|
||||
plot d4 d3 d2 d1 d0 digitop
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
* Waveform generation by PWM in Verilog
|
||||
|
||||
adut null [ out ] pwm_sin
|
||||
.model pwm_sin d_cosim simulation="ivlng" sim_args = [ "pwm" ]
|
||||
|
||||
r1 out smooth 100k
|
||||
c1 smooth 0 1u
|
||||
.control
|
||||
tran 1m 2
|
||||
plot out-3.3 smooth
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Verilog-controlled simple timer.
|
||||
|
||||
* This is the model for an RS flip-flop implemented by Verilator.
|
||||
|
||||
.model vlog_ff d_cosim simulation="./555"
|
||||
|
||||
* The bulk of the circuit is in a shared file.
|
||||
|
||||
.include 555.shared
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
* This file is not intended to be used directly, but by 555.cir.
|
||||
* That allows it to be shared by different implemnetations.
|
||||
|
||||
* This sub-circuit simulates the NE555 timer IC, with the very simple
|
||||
* digital part as a Verilog module.
|
||||
|
||||
.subckt NE555 trigger threshold reset control output discharge vcc ground
|
||||
|
||||
* Resistor chain
|
||||
|
||||
r1 vcc control 5k
|
||||
r2 control trigger_ref 5k
|
||||
r3 trigger_ref ground 5k
|
||||
|
||||
* Two XSPICE ADC instances serve as comparators.
|
||||
|
||||
.model comparator adc_bridge(in_low = -0.0001 in_high = 0.0001)
|
||||
athresh_comparator [%vd threshold control] [over_threshold] comparator
|
||||
atrigger_comparator [%vd trigger_ref trigger] [under_trigger] comparator
|
||||
|
||||
* A tiny Verilog module supplies the flip-flop.
|
||||
* The model is supplied by the outer circuit file.
|
||||
|
||||
averilog [ under_trigger over_threshold reset ] [ output qbar ] vlog_ff
|
||||
|
||||
* The discharge transistor and its base resistor.
|
||||
|
||||
rbase qbar discharge_base 10k
|
||||
qdischarge discharge discharge_base ground npn_transistor
|
||||
.model npn_transistor npn
|
||||
|
||||
.ends ; Ends subcircuit NE555
|
||||
|
||||
|
||||
* The usual 555 oscillator with threshold connected to discharge.
|
||||
|
||||
.param vcc=12
|
||||
|
||||
X555 trigger_threshold trigger_threshold reset control output discharge vcc 0 ne555
|
||||
|
||||
r1 vcc discharge 10k
|
||||
r2 discharge trigger_threshold 10k
|
||||
Ct trigger_threshold 0 1uF ic=0
|
||||
|
||||
* A resistive load forces analog output.
|
||||
|
||||
rload output 0 1k
|
||||
|
||||
* A voltage source for power.
|
||||
|
||||
Vcc vcc 0 {vcc}
|
||||
|
||||
* Pulse the Reset signal low for 2uS each 51mS
|
||||
|
||||
Vpulse reset 0 PULSE {vcc} 0.2 0 1u 1u 2u 51m
|
||||
|
||||
.control
|
||||
tran 10u 200m uic
|
||||
plot trigger_threshold output x555.under_trigger-3 x555.over_threshold-1.5
|
||||
.endc
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Very simple logic for a 555 timer simulation
|
||||
|
||||
`timescale 1us/100ns
|
||||
|
||||
module VL555(Trigger, Threshold, Reset, Q, Qbar);
|
||||
input wire Trigger, Threshold, Reset; // Reset is active low.
|
||||
output reg Q;
|
||||
output wire Qbar;
|
||||
|
||||
wire ireset, go;
|
||||
|
||||
assign Qbar = !Q;
|
||||
|
||||
// The datasheet implies that Trigger overrides Threshold.
|
||||
|
||||
assign go = Trigger & Reset;
|
||||
assign ireset = (Threshold & !Trigger) | !Reset;
|
||||
|
||||
initial begin
|
||||
Q = 0;
|
||||
end
|
||||
|
||||
always @(posedge(go), posedge(ireset)) begin
|
||||
Q = go;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -1,10 +1,32 @@
|
|||
The circuit adc.cir in this directory illustrates the use of the d_cosim
|
||||
XSPICE code model as a container for a Verilog simulation. Before the
|
||||
simulation can be run, the Verilog code must be compiled by Verilator
|
||||
using the command:
|
||||
The circuits in this directory illustrate the use of the d_cosim
|
||||
XSPICE code model as a container for a Verilog simulation, using the
|
||||
Verilator compiler. The example circuits are:
|
||||
|
||||
ngspice vlnggen adc.v
|
||||
555.cir: The probably familiar NE555 oscillator provides a minimal example
|
||||
of combined simulation with SPICE and Verilog. The digital part of the IC,
|
||||
a simple SR flip-flop, is expressed in Verilog.
|
||||
|
||||
That should create a shared library file, adc.so (or adc.DLL on Windows)
|
||||
delay.v: A very simple example of using delays in Verilog to generate
|
||||
waveform outputs.
|
||||
|
||||
pwm.c: Verilog delays controlling a pulse-width modulated output generate
|
||||
an approximate sine wave.
|
||||
|
||||
adc.cir: Slightly more complex Verilog describes the controlling part
|
||||
of a switched-capacitor ADC.
|
||||
|
||||
Before a simulation can be run, the associated Verilog code must be compiled
|
||||
by Verilator using a command script that is included with ngspice:
|
||||
|
||||
ngspice vlnggen 555.v
|
||||
|
||||
That should create a shared library file, 555.so (or 555.DLL on Windows)
|
||||
that will be loaded by the d_cosim code model. The compiled Verilog code that
|
||||
it contains will be executed during simulation.
|
||||
it contains will be executed during simulation. Similar compilations
|
||||
are needed to prepare the other examples, but for Verilog with delays the
|
||||
command looks like:
|
||||
|
||||
ngspice vlnggen -- --timing delay.v
|
||||
|
||||
(The "--" prevents "--timing" from being treated as a ngspice option, so it is
|
||||
passed on to Verilator.)
|
||||
|
|
|
|||
|
|
@ -1,103 +1,10 @@
|
|||
Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim
|
||||
|
||||
.subckt sar_adc input vref start valid d5 d4 d3 d2 d1 d0 clk
|
||||
* Model line for the digital control implemented by Verilator.
|
||||
|
||||
* A transmission gate connects the input to the capacitor set.
|
||||
.model dut d_cosim simulation="./adc"
|
||||
|
||||
xsample input iin sample vref tgate
|
||||
rin iin test_v 1k
|
||||
* The bulk of the circuit is in a shared file.
|
||||
|
||||
* Capacitors and controlling inverters
|
||||
|
||||
xb5 test_v vref d5 ccap c=1p
|
||||
xb4 test_v vref d4 ccap c={1p / 2}
|
||||
xb3 test_v vref d3 ccap c={1p / 4}
|
||||
xb2 test_v vref d2 ccap c={1p / 8}
|
||||
xb1 test_v vref d1 ccap c={1p / 16}
|
||||
xb0 test_v vref d0 ccap c={1p / 32}
|
||||
clast test_v 0 {1p / 32}
|
||||
|
||||
* An XSPICE ADC bridge functions as a comparator.
|
||||
|
||||
acomp [%vd(test_v vref)] [comp] comparator
|
||||
.model comparator adc_bridge in_low=0 in_high=0
|
||||
|
||||
* The digital portion of the circuit is specified in compiled Verilog.
|
||||
* Outputs inverted to cancel the inverter in subcircuit ccap,
|
||||
* and produce the correct numerical output value.
|
||||
|
||||
adut [ Clk Comp Start] [Sample Valid ~d5 ~d4 ~d3 ~d2 ~d1 ~d0] null dut
|
||||
.model dut d_cosim simulation="./adc.so"
|
||||
.ends // SUBCKT sar_adc
|
||||
|
||||
* Some MOS transistors complete the circuit.
|
||||
* Models from https://homepages.rpi.edu/~sawyes/AIMSPICE_TutorialManual.pdf
|
||||
|
||||
.model p1 pmos
|
||||
+ level=2 vto=-0.5 kp=8.5e-6 gamma=0.4 phi=0.65 lambda=0.05 xj=0.5e-6
|
||||
.model n1 nmos
|
||||
+ level=2 vto=0.5 kp=24e-6 gamma=0.15 phi=0.65 lambda=0.015 xj=0.5e-6
|
||||
|
||||
* Use those for an inverter.
|
||||
|
||||
.subckt ainv in out vdd
|
||||
mn out in 0 0 n1
|
||||
mp out in vdd vdd p1
|
||||
.ends
|
||||
|
||||
* A transmission gate modelled by a switch.
|
||||
|
||||
.subckt mos_tgate a b ctl vdd
|
||||
mn a ctl b b n1
|
||||
xinv ctl ictl vdd ainv
|
||||
mp b ictl a a p1
|
||||
.ends
|
||||
|
||||
.subckt tgate a b ctl vdd
|
||||
switch a b ctl 0 tg
|
||||
.model tg sw vt=1.5 ron=2k
|
||||
.ends
|
||||
|
||||
* The per-bit subcircuit in the adc
|
||||
|
||||
.subckt ccap in vcc ctl c=10p
|
||||
xinv ctl tail vcc ainv
|
||||
cb in tail {c}
|
||||
.ends
|
||||
|
||||
**** End of the ADC and its subcircuits. Begin test circuit ****
|
||||
|
||||
.param vcc=3.3
|
||||
vcc vcc 0 {vcc}
|
||||
|
||||
* Digital clock signal
|
||||
|
||||
aclock 0 clk clock
|
||||
.model clock d_osc cntl_array=[-1 1] freq_array=[1Meg 1Meg]
|
||||
|
||||
* A simple DAC so that the result may be compared to the input.
|
||||
|
||||
r5 d5 sum 2
|
||||
r4 d4 sum 4
|
||||
r3 d3 sum 8
|
||||
r2 d2 sum 16
|
||||
r1 d1 sum 32
|
||||
r0 d0 sum 64
|
||||
|
||||
vamm sum 0 0
|
||||
|
||||
* Pulse the Start signal high for 1.3uS each 10uS
|
||||
|
||||
Vpulse Start 0 PULSE 0 {vcc} 0.2u 10n 10n 1.3u 10u
|
||||
Vtest input 0 PULSE 0 3 0 200u 200u 1u 401u
|
||||
|
||||
* The ADC for testing
|
||||
|
||||
xtest input vcc start valid d5 d4 d3 d2 d1 d0 clk sar_adc
|
||||
|
||||
|
||||
.control
|
||||
tran 100n 250u
|
||||
plot input xtest.test_v vamm#branch clk/2 start/3 xtest.sample/3 valid
|
||||
.endc
|
||||
.include adc.shared
|
||||
.end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
* This file is not intended to be used directly, but by adc.cir.
|
||||
* That allows it to be shared by different implemnetations.
|
||||
|
||||
* Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim
|
||||
|
||||
.subckt sar_adc input vref start valid d5 d4 d3 d2 d1 d0 clk
|
||||
|
||||
* A transmission gate connects the input to the capacitor set.
|
||||
|
||||
xsample input iin sample vref tgate
|
||||
rin iin test_v 1k
|
||||
|
||||
* Capacitors and controlling inverters
|
||||
|
||||
xb5 test_v vref d5 ccap c=1p
|
||||
xb4 test_v vref d4 ccap c={1p / 2}
|
||||
xb3 test_v vref d3 ccap c={1p / 4}
|
||||
xb2 test_v vref d2 ccap c={1p / 8}
|
||||
xb1 test_v vref d1 ccap c={1p / 16}
|
||||
xb0 test_v vref d0 ccap c={1p / 32}
|
||||
clast test_v 0 {1p / 32}
|
||||
|
||||
* An XSPICE ADC bridge functions as a comparator.
|
||||
|
||||
acomp [%vd(test_v vref)] [comp] comparator
|
||||
.model comparator adc_bridge in_low=0 in_high=0
|
||||
|
||||
* The digital portion of the circuit is specified in compiled Verilog.
|
||||
* Outputs inverted to cancel the inverter in subcircuit ccap,
|
||||
* and produce the correct numerical output value. The model definition
|
||||
* is supplied by the calling circuit file.
|
||||
|
||||
adut [ Clk Comp Start] [Sample Valid ~d5 ~d4 ~d3 ~d2 ~d1 ~d0] dut
|
||||
.ends // SUBCKT sar_adc
|
||||
|
||||
* Some MOS transistors complete the circuit.
|
||||
* Models from https://homepages.rpi.edu/~sawyes/AIMSPICE_TutorialManual.pdf
|
||||
|
||||
.model p1 pmos
|
||||
+ level=2 vto=-0.5 kp=8.5e-6 gamma=0.4 phi=0.65 lambda=0.05 xj=0.5e-6
|
||||
.model n1 nmos
|
||||
+ level=2 vto=0.5 kp=24e-6 gamma=0.15 phi=0.65 lambda=0.015 xj=0.5e-6
|
||||
|
||||
* Use those for an inverter.
|
||||
|
||||
.subckt ainv in out vdd
|
||||
mn out in 0 0 n1
|
||||
mp out in vdd vdd p1
|
||||
.ends
|
||||
|
||||
* A transmission gate modelled by a switch.
|
||||
|
||||
.subckt mos_tgate a b ctl vdd
|
||||
mn a ctl b b n1
|
||||
xinv ctl ictl vdd ainv
|
||||
mp b ictl a a p1
|
||||
.ends
|
||||
|
||||
.subckt tgate a b ctl vdd
|
||||
switch a b ctl 0 tg
|
||||
.model tg sw vt=1.5 ron=2k
|
||||
.ends
|
||||
|
||||
* The per-bit subcircuit in the adc
|
||||
|
||||
.subckt ccap in vcc ctl c=10p
|
||||
xinv ctl tail vcc ainv
|
||||
cb in tail {c}
|
||||
.ends
|
||||
|
||||
**** End of the ADC and its subcircuits. Begin test circuit ****
|
||||
|
||||
|
||||
.param vcc=3.3
|
||||
vcc vcc 0 {vcc}
|
||||
|
||||
* Digital clock signal
|
||||
|
||||
aclock 0 clk clock
|
||||
.model clock d_osc cntl_array=[-1 1] freq_array=[1Meg 1Meg]
|
||||
|
||||
* A simple DAC so that the result may be compared to the input.
|
||||
|
||||
r5 d5 sum 2
|
||||
r4 d4 sum 4
|
||||
r3 d3 sum 8
|
||||
r2 d2 sum 16
|
||||
r1 d1 sum 32
|
||||
r0 d0 sum 64
|
||||
|
||||
vamm sum 0 0
|
||||
|
||||
* Pulse the Start signal high for 1.3uS each 10uS
|
||||
|
||||
Vpulse Start 0 PULSE 0 {vcc} 0.2u 10n 10n 1.3u 10u
|
||||
Vtest input 0 PULSE 0 3 0 200u 200u 1u 401u
|
||||
|
||||
* The ADC for testing
|
||||
|
||||
xtest input vcc start valid d5 d4 d3 d2 d1 d0 clk sar_adc
|
||||
|
||||
|
||||
.control
|
||||
tran 100n 250u
|
||||
plot input xtest.test_v vamm#branch clk/2 start/3 xtest.sample/3 valid
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
// Digital control for a successive approximation ADC with switched capacitors.
|
||||
|
||||
`timescale 100ns/100ns
|
||||
|
||||
module adc(Clk, Comp, Start, Sample, Done, Result);
|
||||
input wire Clk, Comp, Start;
|
||||
output reg Sample, Done;
|
||||
|
|
@ -22,14 +24,12 @@ module adc(Clk, Comp, Start, Sample, Done, Result);
|
|||
if (Running) begin
|
||||
if (Sample) begin
|
||||
Sample <= 0;
|
||||
SR[Bits - 1] = 1;
|
||||
Result[Bits - 1] = 1;
|
||||
SR[Bits - 1] <= 1;
|
||||
Result[Bits - 1] <= 1;
|
||||
end else if (SR != 0) begin
|
||||
if (Comp)
|
||||
Result &= ~SR;
|
||||
SR >>= 1;
|
||||
Result |= SR;
|
||||
if (SR == 0) begin
|
||||
Result <= (Comp ? (Result & ~SR) : Result) | (SR >> 1);
|
||||
SR <= SR >> 1;
|
||||
if (SR == 1) begin
|
||||
Running <= 0;
|
||||
Done <= 1;
|
||||
end
|
||||
|
|
@ -38,8 +38,8 @@ module adc(Clk, Comp, Start, Sample, Done, Result);
|
|||
Running <= 1;
|
||||
Sample <= 1;
|
||||
Done <= 0;
|
||||
SR = 0;
|
||||
Result = 0;
|
||||
SR <= 0;
|
||||
Result <= 0;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
* Waveform generation by Verilog delays
|
||||
*
|
||||
|
||||
adut null [ d4 d3 d2 d1 d0 ] ring
|
||||
.model ring d_cosim simulation="./delay"
|
||||
|
||||
.control
|
||||
tran 20u 100u
|
||||
plot d4 d3 d2 d1 d0 digitop
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
`timescale 1us/100ns
|
||||
|
||||
module delay(out);
|
||||
output reg [4:0] out;
|
||||
reg t;
|
||||
|
||||
initial out = 0;
|
||||
always begin
|
||||
#1;
|
||||
t = out[4];
|
||||
out <<= 1;
|
||||
out[0] = ~t;
|
||||
end
|
||||
endmodule; // delay
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
* Waveform generation by PWM in Verilog
|
||||
|
||||
adut null [ out ] pwm_sin
|
||||
.model pwm_sin d_cosim simulation="./pwm"
|
||||
|
||||
r1 out smooth 100k
|
||||
c1 smooth 0 1u
|
||||
.control
|
||||
tran 1m 2
|
||||
plot out-3.3 smooth
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
`timescale 1us/100ns
|
||||
|
||||
//`include "constants.vams"
|
||||
`define M_TWO_PI 6.28318530717958647652
|
||||
|
||||
module pwm(out);
|
||||
output reg out;
|
||||
parameter Cycles = 1000, Samples = 1000;
|
||||
integer i, j, width;
|
||||
real sine;
|
||||
|
||||
initial begin
|
||||
i = 0;
|
||||
j = 0;
|
||||
width = Cycles / 2;
|
||||
out = 0;
|
||||
end
|
||||
|
||||
always begin
|
||||
#1;
|
||||
++i;
|
||||
if (i == width)
|
||||
out = 0;
|
||||
if (i == Cycles) begin
|
||||
i = 0;
|
||||
++j;
|
||||
if (j == Samples)
|
||||
j = 0;
|
||||
sine = $sin(j * `M_TWO_PI / Samples);
|
||||
width = $rtoi(Samples * (1.0 + sine) / 2.0);
|
||||
out = (width == 0) ? 0 : 1;
|
||||
end
|
||||
end
|
||||
endmodule // pwm
|
||||
Loading…
Reference in New Issue