Verilog CMOS模拟超前进位过程中的未知值

Verilog CMOS模拟超前进位过程中的未知值,verilog,modelsim,Verilog,Modelsim,我是Verilog的新手。 我被指派使用pmos和nmos原语编写一个4位CLA。 我找到了一个网站,详细介绍了示意图: 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]

我是Verilog的新手。
我被指派使用pmos和nmos原语编写一个4位CLA。
我找到了一个网站,详细介绍了示意图:
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

我一直面临的问题是,当我模拟模型时,我在其中一个测试输入的总和上得到一个未知值。

检查以下行:

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网表非常简单。以下是一些很好的参考资料:以及


更仔细地看C1的代码,NMOS部分是正确的。PMOS网络只是NMOS的对偶,这意味着pm1_c1应具有与nm1_c1相同的门(即控制)信号。只要改变它,它至少可以解决C1的问题

如果您得到输出位的未知值,确定哪些晶体管驱动该位,并检查其栅极上的值。重复上述步骤,直到问题变得明显。@JoeHass我猜是c1线的一个晶体管引起了问题。如何查看晶体管栅极上的值?我使用的是ModelSim PE学生版10.3。对不起,我不知道ModelSim,但必须有办法查看连接到构成c1的晶体管的内部节点。@JoeHass我在pw_c11和nw_c11导线上都获得了高阻抗值。也许这就是原因?好吧,我理解问题所在。我是否应该为所有nmos交换机声明一个临时导线,然后以某种方式合并结果?丹·索雷斯库:我不确定这个设计是否正确。您需要将
c1=g0+p0.c0
转换为CMOS网表。将布尔方程转换为CMOS网表非常简单。这里有一些很好的参考资料:更仔细地看一下C1的代码,就知道NMOS部分是对的。PMOS网络只是NMOS的对偶,这意味着
pm1_c1
应该具有与
nm1_c1
相同的门(即控制)信号。只要改变它,它至少可以解决C1的问题!那个网站证明是有用的。我唯一需要补充的是输出是反转的,这意味着为了得到求和的每一位的正确结果,必须反转每条
c
导线的值。我已经完成了
c1
c2
连线。我将报告我的工作结果。:-)如何让你的评论与我的网站接受的答案?谢谢