I'm new to Verilog.
I've been assigned to write a 4-bit CLA using pmos and nmos primitives.
I found a website which details the schematic: Design of VLSI Systems
The CLA is at 6.5.3. I'm using the static implementation.
Starting from the schematic for wire c4, I designed 3 more schematics to calculate the values of wires c1, c2 and c3.
I'm pasting my code:
module carryCMOS(a, b, c_in, sum, c_out);
// variables
input [3:0] a, b;
input c_in;
output [3:0] sum;
output c_out;
// VDD and GND
supply1 vdd;
supply0 gnd;
// internal wires
wire g0, g1, g2, g3;
wire p0, p1, p2, p3;
wire c1, c2, c3, c4;
// for wire c4
wire pw_c41, pw_c42, pw_c43, pw_c44;
wire nw_c41, nw_c42, nw_c43, nw_c44;
// for wire c3
wire pw_c31, pw_c32, pw_c33;
wire nw_c31, nw_c32, nw_c33;
// for wire c2
wire pw_c21, pw_c22;
wire nw_c21, nw_c22;
// for wire c1
wire pw_c11;
wire nw_c11;
// carry look ahead formulas
assign g0 = a[0] & b[0];
assign g1 = a[1] & b[1];
assign g2 = a[2] & b[2];
assign g3 = a[3] & b[3];
assign p0 = a[0] ^ b[0];
assign p1 = a[1] ^ b[1];
assign p2 = a[2] ^ b[2];
assign p3 = a[3] ^ b[3];
// c4
pmos pm1_c4(c4, vdd, p3);
pmos pm2_c4(c4, pw_c41, p2);
pmos pm3_c4(c4, pw_c42, p1);
pmos pm4_c4(c4, pw_c43, p0);
pmos pm5_c4(pw_c41, vdd, g3);
pmos pm6_c4(pw_c42, pw_c41, g2);
pmos pm7_c4(pw_c43, pw_c42, g1);
pmos pm8_c4(pw_c44, pw_c43, g0);
pmos pm9_c4(c4, pw_c44, c_in);
nmos nm1_c4(c4, gnd, g3);
nmos nm2_c4(c4, nw_c41, g2);
nmos nm3_c4(c4, nw_c42, g1);
nmos nm4_c4(c4, nw_c43, g0);
nmos nm5_c4(nw_c41, gnd, p3);
nmos nm6_c4(nw_c42, nw_c41, p2);
nmos nm7_c4(nw_c43, nw_c42, p1);
nmos nm8_c4(nw_c44, nw_c43, p0);
nmos nm9_c4(c4, nw_c44, c_in);
// c3
pmos pm1_c3(c3, vdd, p2);
pmos pm2_c3(c3, pw_c31, p1);
pmos pm3_c3(c3, pw_c32, p0);
pmos pm4_c3(pw_c31, vdd, g2);
pmos pm5_c3(pw_c32, pw_c31, g1);
pmos pm6_c3(pw_c33, pw_c32, g0);
pmos pm7_c3(c3, pw_c33, c_in);
nmos nm1_c3(c3, gnd, g2);
nmos nm2_c3(c3, nw_c31, g1);
nmos nm3_c3(c3, nw_c32, g0);
nmos nm4_c3(nw_c31, gnd, p2);
nmos nm5_c3(nw_c32, nw_c31, p1);
nmos nm6_c3(nw_c33, nw_c32, p0);
nmos nm7_c3(c3, nw_c33, c_in);
// c2
pmos pm1_c2(c2, vdd, p1);
pmos pm2_c2(c2, pw_c21, p0);
pmos pm3_c2(pw_c21, vdd, g1);
pmos pm4_c2(pw_c22, pw_c21, g0);
pmos pm5_c2(c2, pw_c22, c_in);
nmos nm1_c2(c2, gnd, g1);
nmos nm2_c2(c2, nw_c21, g0);
nmos nm3_c2(nw_c21, gnd, p1);
nmos nm4_c2(nw_c22, nw_c21, p0);
nmos nm5_c2(c2, nw_c22, c_in);
// c1
pmos pm1_c1(c1, vdd, p0);
pmos pm2_c1(pw_c11, vdd, g0);
pmos pm3_c1(c1, pw_c11, c_in);
nmos nm1_c1(c1, gnd, g0);
nmos nm2_c1(nw_c11, gnd, p0);
nmos nm3_c1(c1, nw_c11, c_in);
// sum and carry
assign sum[0] = p0 ^ c_in;
assign sum[1] = p1 ^ (!c1);
assign sum[2] = p2 ^ (!c2);
assign sum[3] = p3 ^ (!c3);
assign c_out = !c4;
endmodule
module test_carry;
reg [3:0] in1, in2;
wire [3:0] out;
reg c_in;
wire c_out;
carryCMOS carry(in1, in2, c_in, out, c_out);
initial begin
$dumpfile("carry.vcd");
in1 = 4'd0;
in2 = 4'd1;
assign c_in = 0;
#20;
$display("time:%d in1:%d in2:%d c_in:%d out:%d c_out:%d", $time,
in1, in2, c_in, out, c_out);
#20;
in1 = 4'd7;
in2 = 4'd8;
assign c_in = 1;
#20;
$display("time:%d in1:%d in2:%d c_in:%d out:%d c_out:%d", $time,
in1, in2, c_in, out, c_out);
#20;
in1 = 4'd5;
in2 = 4'd1;
assign c_in = 1;
#20;
$display("time:%d in1:%d in2:%d c_in:%d out:%d c_out:%d", $time,
in1, in2, c_in, out, c_out);
#20;
in1 = 4'd5;
in2 = 4'd10;
assign c_in = 0;
#20;
$display("time:%d in1:%d in2:%d c_in:%d out:%d c_out:%d", $time,
in1, in2, c_in, out, c_out);
$dumpvars(0, carry);
end
endmodule
The problem I have been facing is that when I simulate the model, I'm getting an unknown value at the sum for one of the test inputs.
Simulation
Check the following lines:
pmos pm1_c1(c1, vdd, p0);
The value of p0
at time 80 is low. Therefore the nmos is trying to drive c1
to high.
On the other hand:
nmos nm1_c1(c1, gnd, g0);
The value of g0
at time 80 is high. Therefore the nmos is trying to drive c1
to low.
Since c1
has two drivers of values 1
and 0
, its true value is unknown, i.e. x
.
EDIT:
I'm not sure if this design is correct. You are to convert c1=g0+p0.c0 to a CMOS netlist. Converting a Boolean equation to a CMOS netlist is very trivial. Here are some good references: http://cs.utexas.edu/users/fussell/cs310/lectures/cs310-lecture3.pdf and http://acipo.com/blog/cmos-design-intro
Looking at your code for C1 more closely, you got the NMOS part right. The PMOS network is just the dual of NMOS, that means pm1_c1 should have the same gate (i.e. control) signal as nm1_c1. Just change it, and it should fix the problem at least for C1!