Lets look at spice first. An RC lowpass (1 ohm, 1 farad)… The stanza
gnucap> spice spice> .subckt rclp in out ref spice> R1 in out 1 spice> C1 out ref 1 spice> .ends
declares a subcircuit (macro) with 3 ordered ports and no parameters. It could model a PCB with a 3 pin connector (or so), and some oversimplification.
Instanciate it (in spice mode) with
spice> Xmylp in out 0 rclp
Ports are assigned in the order matching the declaration. The “0” is the global ground node. Note the weird label, it has to start with an X, because on a punchcard, the first character is the type.
You typically need some kind of testbench to simulate. Lets build a stupid one. A single dc voltage source.
spice> V1 in 0 1
You can now run a dc simulation.
spice> .dc [..]
And there's nothing, because there are no probes set.
try again
spice> .print dc v(in) v(out) spice> .dc [..some table] spice> .dc V1 0 10 1 [..some bigger table]
The bigger table simply repeats the dc analysis in a loop sweeping the dc voltage from 0 to 10 step 1 [Volts].
(You might ask why you need to set probes *before* you run the simulation. Reason is, to avoid computational overhead. Other Spices do not require it, and it appears to be an advantage. It is not.)
Lets repeat the analysis with Verilog syntax.
gnucap> verilog verilog> module rclp(in, out, ref); verilog> resistor #(.r(1)) R1(.p(in), .n(out)); verilog> capacitor #(.c(1)) C1(.p(out), .n(ref)); verilog> endmodule
verilog> rclp #() mylp(.in(in), .ref(0), .out(out)); verilog> vsource #(.dc(1)) V1(.p(in), .n(0));
verilog> print dc v(in) v(out) verilog> dc [..] verilog> dc V1 0 10 1 [..]
Perhaps no surprises. Ports and parameters have names, the order of the connections does not matter (much), and the syntax is more regular, types are full words, and labels are arbitrary. Maybe interesting: the Verilog standard does not allow device instances at top level. But we do (under restrictions). This way the top level can act as a test bench, as needed.
Nodes in a subcircuit instance are not mapped, and can't be probed directly through “print”. Instead, either use a “meter”, or probe the voltage at the port of a known device.
gnucap> verilog verilog> module divid(); verilog> resistor #(.r(11)) R1(in, out); verilog> resistor #(.r(22)) R2(out, 0); verilog> vsource #(.dc(1.23)) V1(in, 0); verilog> meter mout(out, 0, 0, 0); verilog> endmodule verilog> divid #() mydiv(); verilog> print dc v(mydiv.mout) v1(mydiv.R1) verilog> dc
You could as well maintain connectivity to the top level, which has named ports. Note how the top level is not instanciated, and the nodes are accessible by name.
gnucap> verilog verilog> module divid(out); verilog> resistor #(.r(11)) R1(in, out); verilog> resistor #(.r(22)) R2(out, 0); verilog> vsource #(.dc(1.23)) V1(in, 0); verilog> meter mout(out, 0, 0, 0); verilog> endmodule verilog> divid #() mydiv(out); verilog> print dc v(out) verilog> dc