aboutsummaryrefslogtreecommitdiffstats
path: root/examples/cmos
diff options
context:
space:
mode:
Diffstat (limited to 'examples/cmos')
-rw-r--r--examples/cmos/.gitignore4
-rw-r--r--examples/cmos/README13
-rw-r--r--examples/cmos/cmos_cells.lib55
-rw-r--r--examples/cmos/cmos_cells.sp39
-rw-r--r--examples/cmos/cmos_cells.v44
-rw-r--r--examples/cmos/cmos_cells_digital.sp31
-rw-r--r--examples/cmos/counter.v12
-rw-r--r--examples/cmos/counter.ys16
-rw-r--r--examples/cmos/counter_digital.ys16
-rw-r--r--examples/cmos/counter_tb.gtkw5
-rw-r--r--examples/cmos/counter_tb.v33
-rw-r--r--examples/cmos/testbench.sh7
-rw-r--r--examples/cmos/testbench.sp29
-rw-r--r--examples/cmos/testbench_digital.sh15
-rw-r--r--examples/cmos/testbench_digital.sp26
15 files changed, 345 insertions, 0 deletions
diff --git a/examples/cmos/.gitignore b/examples/cmos/.gitignore
new file mode 100644
index 000000000..f58d95018
--- /dev/null
+++ b/examples/cmos/.gitignore
@@ -0,0 +1,4 @@
+counter_tb
+counter_tb.vcd
+synth.sp
+synth.v
diff --git a/examples/cmos/README b/examples/cmos/README
new file mode 100644
index 000000000..c459b4b54
--- /dev/null
+++ b/examples/cmos/README
@@ -0,0 +1,13 @@
+
+In this directory contains an example for generating a spice output using two
+different spice modes, normal analog transient simulation and event-driven
+digital simulation as supported by ngspice xspice sub-module.
+
+Each test bench can be run separately by either running:
+
+- testbench.sh, to start analog simulation or
+- testbench_digital.sh for mixed-signal digital simulation.
+
+The later case also includes pure verilog simulation using the iverilog
+and gtkwave for comparison.
+
diff --git a/examples/cmos/cmos_cells.lib b/examples/cmos/cmos_cells.lib
new file mode 100644
index 000000000..1b0bf8457
--- /dev/null
+++ b/examples/cmos/cmos_cells.lib
@@ -0,0 +1,55 @@
+// test comment
+/* test comment */
+library(demo) {
+ cell(BUF) {
+ area: 6;
+ pin(A) { direction: input; }
+ pin(Y) { direction: output;
+ function: "A"; }
+ }
+ cell(NOT) {
+ area: 3;
+ pin(A) { direction: input; }
+ pin(Y) { direction: output;
+ function: "A'"; }
+ }
+ cell(NAND) {
+ area: 4;
+ pin(A) { direction: input; }
+ pin(B) { direction: input; }
+ pin(Y) { direction: output;
+ function: "(A*B)'"; }
+ }
+ cell(NOR) {
+ area: 4;
+ pin(A) { direction: input; }
+ pin(B) { direction: input; }
+ pin(Y) { direction: output;
+ function: "(A+B)'"; }
+ }
+ cell(DFF) {
+ area: 18;
+ ff(IQ, IQN) { clocked_on: C;
+ next_state: D; }
+ pin(C) { direction: input;
+ clock: true; }
+ pin(D) { direction: input; }
+ pin(Q) { direction: output;
+ function: "IQ"; }
+ }
+ cell(DFFSR) {
+ area: 18;
+ ff("IQ", "IQN") { clocked_on: C;
+ next_state: D;
+ preset: S;
+ clear: R; }
+ pin(C) { direction: input;
+ clock: true; }
+ pin(D) { direction: input; }
+ pin(Q) { direction: output;
+ function: "IQ"; }
+ pin(S) { direction: input; }
+ pin(R) { direction: input; }
+ ; // empty statement
+ }
+}
diff --git a/examples/cmos/cmos_cells.sp b/examples/cmos/cmos_cells.sp
new file mode 100644
index 000000000..673b20d08
--- /dev/null
+++ b/examples/cmos/cmos_cells.sp
@@ -0,0 +1,39 @@
+
+.SUBCKT BUF A Y
+X1 A B NOT
+X2 B Y NOT
+.ENDS NOT
+
+.SUBCKT NOT A Y
+M1 Y A Vdd Vdd cmosp L=1u W=10u
+M2 Y A Vss Vss cmosn L=1u W=10u
+.ENDS NOT
+
+.SUBCKT NAND A B Y
+M1 Y A Vdd Vdd cmosp L=1u W=10u
+M2 Y B Vdd Vdd cmosp L=1u W=10u
+M3 Y A M34 Vss cmosn L=1u W=10u
+M4 M34 B Vss Vss cmosn L=1u W=10u
+.ENDS NAND
+
+.SUBCKT NOR A B Y
+M1 Y A M12 Vdd cmosp L=1u W=10u
+M2 M12 B Vdd Vdd cmosp L=1u W=10u
+M3 Y A Vss Vss cmosn L=1u W=10u
+M4 Y B Vss Vss cmosn L=1u W=10u
+.ENDS NOR
+
+.SUBCKT DLATCH E D Q
+X1 D E S NAND
+X2 nD E R NAND
+X3 S nQ Q NAND
+X4 Q R nQ NAND
+X5 D nD NOT
+.ENDS DLATCH
+
+.SUBCKT DFF C D Q
+X1 nC D t DLATCH
+X2 C t Q DLATCH
+X3 C nC NOT
+.ENDS DFF
+
diff --git a/examples/cmos/cmos_cells.v b/examples/cmos/cmos_cells.v
new file mode 100644
index 000000000..27278facb
--- /dev/null
+++ b/examples/cmos/cmos_cells.v
@@ -0,0 +1,44 @@
+
+module BUF(A, Y);
+input A;
+output Y;
+assign Y = A;
+endmodule
+
+module NOT(A, Y);
+input A;
+output Y;
+assign Y = ~A;
+endmodule
+
+module NAND(A, B, Y);
+input A, B;
+output Y;
+assign Y = ~(A & B);
+endmodule
+
+module NOR(A, B, Y);
+input A, B;
+output Y;
+assign Y = ~(A | B);
+endmodule
+
+module DFF(C, D, Q);
+input C, D;
+output reg Q;
+always @(posedge C)
+ Q <= D;
+endmodule
+
+module DFFSR(C, D, Q, S, R);
+input C, D, S, R;
+output reg Q;
+always @(posedge C, posedge S, posedge R)
+ if (S)
+ Q <= 1'b1;
+ else if (R)
+ Q <= 1'b0;
+ else
+ Q <= D;
+endmodule
+
diff --git a/examples/cmos/cmos_cells_digital.sp b/examples/cmos/cmos_cells_digital.sp
new file mode 100644
index 000000000..e1cb82a2f
--- /dev/null
+++ b/examples/cmos/cmos_cells_digital.sp
@@ -0,0 +1,31 @@
+
+.SUBCKT BUF A Y
+.model buffer1 d_buffer
+Abuf A Y buffer1
+.ENDS NOT
+
+.SUBCKT NOT A Y
+.model not1 d_inverter
+Anot A Y not1
+.ENDS NOT
+
+.SUBCKT NAND A B Y
+.model nand1 d_nand
+Anand [A B] Y nand1
+.ENDS NAND
+
+.SUBCKT NOR A B Y
+.model nor1 d_nor
+Anand [A B] Y nor1
+.ENDS NOR
+
+.SUBCKT DLATCH E D Q
+.model latch1 d_latch
+Alatch D E null null Q nQ latch1
+.ENDS DLATCH
+
+.SUBCKT DFF C D Q
+.model dff1 d_dff
+Adff D C null null Q nQ dff1
+.ENDS DFF
+
diff --git a/examples/cmos/counter.v b/examples/cmos/counter.v
new file mode 100644
index 000000000..f21658724
--- /dev/null
+++ b/examples/cmos/counter.v
@@ -0,0 +1,12 @@
+module counter (clk, rst, en, count);
+
+ input clk, rst, en;
+ output reg [2:0] count;
+
+ always @(posedge clk)
+ if (rst)
+ count <= 3'd0;
+ else if (en)
+ count <= count + 3'd1;
+
+endmodule
diff --git a/examples/cmos/counter.ys b/examples/cmos/counter.ys
new file mode 100644
index 000000000..a784f3465
--- /dev/null
+++ b/examples/cmos/counter.ys
@@ -0,0 +1,16 @@
+
+read_verilog counter.v
+read_verilog -lib cmos_cells.v
+
+proc;; memory;; techmap;;
+
+dfflibmap -liberty cmos_cells.lib
+abc -liberty cmos_cells.lib;;
+
+# http://vlsiarch.ecen.okstate.edu/flows/MOSIS_SCMOS/latest/cadence/lib/tsmc025/signalstorm/osu025_stdcells.lib
+# dfflibmap -liberty osu025_stdcells.lib
+# abc -liberty osu025_stdcells.lib;;
+
+write_verilog synth.v
+write_spice synth.sp
+
diff --git a/examples/cmos/counter_digital.ys b/examples/cmos/counter_digital.ys
new file mode 100644
index 000000000..a5e728e02
--- /dev/null
+++ b/examples/cmos/counter_digital.ys
@@ -0,0 +1,16 @@
+
+read_verilog counter.v
+read_verilog -lib cmos_cells.v
+
+proc;; memory;; techmap;;
+
+dfflibmap -liberty cmos_cells.lib
+abc -liberty cmos_cells.lib;;
+
+# http://vlsiarch.ecen.okstate.edu/flows/MOSIS_SCMOS/latest/cadence/lib/tsmc025/signalstorm/osu025_stdcells.lib
+# dfflibmap -liberty osu025_stdcells.lib
+# abc -liberty osu025_stdcells.lib;;
+
+write_verilog synth.v
+write_spice -neg 0s -pos 1s synth.sp
+
diff --git a/examples/cmos/counter_tb.gtkw b/examples/cmos/counter_tb.gtkw
new file mode 100644
index 000000000..4a2eac400
--- /dev/null
+++ b/examples/cmos/counter_tb.gtkw
@@ -0,0 +1,5 @@
+[dumpfile] "counter_tb.vcd"
+counter_tb.clk
+counter_tb.count[2:0]
+counter_tb.en
+counter_tb.reset
diff --git a/examples/cmos/counter_tb.v b/examples/cmos/counter_tb.v
new file mode 100644
index 000000000..bcd7d992c
--- /dev/null
+++ b/examples/cmos/counter_tb.v
@@ -0,0 +1,33 @@
+module counter_tb;
+
+ /* Make a reset pulse and specify dump file */
+ reg reset = 0;
+ initial begin
+ $dumpfile("counter_tb.vcd");
+ $dumpvars(0,counter_tb);
+
+ # 0 reset = 1;
+ # 4 reset = 0;
+ # 36 reset = 1;
+ # 4 reset = 0;
+ # 6 $finish;
+ end
+
+ /* Make enable with period of 8 and 6,7 low */
+ reg en = 1;
+ always begin
+ en = 1;
+ #6;
+ en = 0;
+ #2;
+ end
+
+ /* Make a regular pulsing clock. */
+ reg clk = 0;
+ always #1 clk = !clk;
+
+ /* UUT */
+ wire [2:0] count;
+ counter c1 (clk, reset, en, count);
+
+endmodule
diff --git a/examples/cmos/testbench.sh b/examples/cmos/testbench.sh
new file mode 100644
index 000000000..061704b64
--- /dev/null
+++ b/examples/cmos/testbench.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -ex
+
+../../yosys counter.ys
+ngspice testbench.sp
+
diff --git a/examples/cmos/testbench.sp b/examples/cmos/testbench.sp
new file mode 100644
index 000000000..e571d2815
--- /dev/null
+++ b/examples/cmos/testbench.sp
@@ -0,0 +1,29 @@
+
+* supply voltages
+.global Vss Vdd
+Vss Vss 0 DC 0
+Vdd Vdd 0 DC 3
+
+* simple transistor model
+.MODEL cmosn NMOS LEVEL=1 VT0=0.7 KP=110U GAMMA=0.4 LAMBDA=0.04 PHI=0.7
+.MODEL cmosp PMOS LEVEL=1 VT0=-0.7 KP=50U GAMMA=0.57 LAMBDA=0.05 PHI=0.8
+
+* load design and library
+.include cmos_cells.sp
+.include synth.sp
+
+* input signals
+Vclk clk 0 PULSE(0 3 1 0.1 0.1 0.8 2)
+Vrst rst 0 PULSE(0 3 0.5 0.1 0.1 2.9 40)
+Ven en 0 PULSE(0 3 0.5 0.1 0.1 5.9 8)
+
+Xuut clk rst en out0 out1 out2 COUNTER
+
+.tran 0.01 50
+
+.control
+run
+plot v(clk) v(rst)+5 v(en)+10 v(out0)+20 v(out1)+25 v(out2)+30
+.endc
+
+.end
diff --git a/examples/cmos/testbench_digital.sh b/examples/cmos/testbench_digital.sh
new file mode 100644
index 000000000..afaaf4d43
--- /dev/null
+++ b/examples/cmos/testbench_digital.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -ex
+
+# iverlog simulation
+echo "Doing Verilog simulation with iverilog"
+iverilog -o counter_tb counter.v counter_tb.v
+./counter_tb; gtkwave counter_tb.gtkw &
+
+# yosys synthesis
+../../yosys counter_digital.ys
+
+# requires ngspice with xspice support enabled:
+ngspice testbench_digital.sp
+
diff --git a/examples/cmos/testbench_digital.sp b/examples/cmos/testbench_digital.sp
new file mode 100644
index 000000000..c5f9d5987
--- /dev/null
+++ b/examples/cmos/testbench_digital.sp
@@ -0,0 +1,26 @@
+
+* load design and library
+.include cmos_cells_digital.sp
+.include synth.sp
+
+* input signals
+Vclk clk 0 PULSE(0 3 1 0.1 0.1 0.8 2)
+Vrst rst 0 PULSE(0 3 0.5 0.1 0.1 2.9 40)
+Ven en 0 PULSE(0 3 0.5 0.1 0.1 5.9 8)
+
+Xuut dclk drst den dout0 dout1 dout2 counter
+* Bridge to digital
+.model adc_buff adc_bridge(in_low = 0.8 in_high=2)
+.model dac_buff dac_bridge(out_high = 3.5)
+Aad [clk rst en] [dclk drst den] adc_buff
+Ada [dout0 dout1 dout2] [out0 out1 out2] dac_buff
+
+
+.tran 0.01 50
+
+.control
+run
+plot v(clk) v(rst)+5 v(en)+10 v(out0)+20 v(out1)+25 v(out2)+30
+.endc
+
+.end