我是Verilog的新手。
我被指派使用pmos和nmos原语编写一个4位CLA。
我找到了一个详细说明原理图的网站:Design of VLSI Systems
CLA为6.5.3。我正在使用静态实现。
从导线c4的原理图开始,我设计了3个原理图来计算导线c1,c2和c3的值。
我粘贴了我的代码:
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
我遇到的问题是,当我模拟模型时,我在其中一个测试输入的总和上得到一个未知值。
Simulation
答案 0 :(得分:0)
检查以下几行:
pmos pm1_c1(c1, vdd, p0);
时间80的p0
值很低。因此,nmos正试图将c1
推向高位。
另一方面:
nmos nm1_c1(c1, gnd, g0);
时间80处g0
的值很高。因此,nmos正试图将c1
推向低位。
由于c1
有两个值1
和0
的驱动因素,因此其真实值未知,即x
。
修改强>
我不确定这种设计是否正确。您要将c1 = g0 + p0.c0转换为CMOS网表。将布尔方程式转换为CMOS网表非常简单。以下是一些很好的参考资料:http://cs.utexas.edu/users/fussell/cs310/lectures/cs310-lecture3.pdf和http://acipo.com/blog/cmos-design-intro
更仔细地查看C1的代码,你得到了NMOS部分。 PMOS网络只是NMOS的双重,这意味着pm1_c1应具有与nm1_c1相同的门(即控制)信号。只需更改它,它应该至少为C1解决问题!