Неизвестна стойност по време на симулация Carry Look Ahead с CMOS

Аз съм нов във Verilog.
Беше ми възложено да напиша 4-битов CLA, използвайки pmos и nmos примитиви.
Намерих уебсайт с подробности за схемата: Проектиране на VLSI системи
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


Проблемът, с който се сблъсках, е, че когато симулирам модела, получавам неизвестна стойност в сумата за един от тестовите входове.
Симулация


person DanS    schedule 30.04.2014    source източник
comment
Ако получавате неизвестно за изходен бит, определете кои транзистори управляват този бит и проверете стойностите на техните порти. Повторете, докато проблемът стане очевиден.   -  person    schedule 30.04.2014
comment
@JoeHass Предполагам, че един от транзисторите на проводника c1 причинява проблема. Как да видите стойностите на портите на транзисторите? Използвам ModelSim PE Student Edition 10.3.   -  person DanS    schedule 30.04.2014
comment
Съжалявам, не познавам ModelSim, но трябва да има начин да разгледам вътрешните възли, свързани с транзисторите, които правят c1.   -  person    schedule 30.04.2014
comment
@JoeHass Получавам високи стойности на импеданс както на проводниците pw_c11, така и на nw_c11. Може би това е причината?   -  person DanS    schedule 30.04.2014


Отговори (1)


Проверете следните редове:

pmos pm1_c1(c1, vdd, p0);

Стойността на p0 в момент 80 е ниска. Следователно nmos се опитва да задвижи c1 на високо ниво.

От друга страна:

nmos nm1_c1(c1, gnd, g0);

Стойността на g0 в момент 80 е висока. Следователно nmos се опитва да задвижи c1 до ниско ниво.

Тъй като c1 има два драйвера със стойности 1 и 0, истинската му стойност е неизвестна, т.е. x.

РЕДАКТИРАНЕ:

Не съм сигурен дали този дизайн е правилен. Трябва да конвертирате c1=g0+p0.c0 в CMOS netlist. Преобразуването на булево уравнение в CMOS netlist е много тривиално. Ето някои добри препратки: 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!

person Ari    schedule 30.04.2014
comment
Добре, разбирам проблема. Трябва ли да декларирам временен проводник за всички nmos превключватели, след което да комбинирам резултатите по някакъв начин? Някакви идеи как да го поправя? - person DanS; 01.05.2014
comment
@Dan Sorescu: Не съм сигурен дали този дизайн е правилен. Трябва да конвертирате c1=g0+p0.c0 в CMOS списък с мрежи. Преобразуването на булево уравнение в CMOS netlist е много тривиално. Ето някои добри препратки: cs.utexas.edu/ users/fussell/cs310/lectures/cs310-lecture3.pdf и acipo.com /blog/cmos-design-intro - person Ari; 01.05.2014
comment
Разглеждайки по-внимателно вашия код за C1, вие сте разбрали правилно NMOS частта. PMOS мрежата е само двойната на NMOS, което означава, че pm1_c1 трябва да има същия гейт (т.е. контролен) сигнал като nm1_c1. Просто го смени и трябва да реши проблема поне за C1! - person Ari; 01.05.2014
comment
Този уебсайт се оказа полезен. Единственото нещо, което трябва да добавя е, че изходът е обърнат, което означава, че за да получите правилния резултат за всеки бит от сумата, стойността на всеки c проводник трябва да бъде обърната. Вече направих c1 и c2 жицата. Ще докладвам с резултатите от моята работа. :-) - person DanS; 02.05.2014
comment
Как да направя вашия коментар с уебсайта мой приет отговор? Благодаря. - person DanS; 03.05.2014
comment
@Дон Сореску: Добавих коментарите към отговора. Ето връзка с повече информация как да приемете отговор: meta.stackexchange.com/a/5235 - person Ari; 03.05.2014
comment
Благодаря ви за вашите усилия! :-) - person DanS; 03.05.2014