16-битный сумматор из 4-битного опережающего переноса (CLA) — Cout из блока Generate and Propagate

Я новичок в Verilog. Вот что я сделал до сих пор, и 4-битный CLA работает. Однако 16-битный (с использованием экземпляров 4-битного CLA) этого не делает. Проблема определенно заключается в установке значений Cout_itermed (промежуточные переносы) из блока распространения (BP) и создания блока (BG). Я создал модуль carries для решения этой проблемы.

В Xilinx ISE выходной сигнал выглядит следующим образом (волна не показана):

Xilinx ISE

module CLA_4bit(
        output [3:0] S,
        output Cout, PG, GG,
        input [3:0] A, B,
        input Cin
        );

        wire [3:0] G,P,C;

        assign G = A & B; //Generate
        assign P = A ^ B; //Propagate

        assign C[0] = Cin;
        assign C[1] = G[0] | (P[0] & C[0]);
        assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
        assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);

        assign Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
        assign S = P ^ C;

        assign PG = P[3] & P[2] & P[1] & P[0]; // block generate
        assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]); // block propagate
endmodule

module CLA_16bit(
        output reg [15:0] S,
        output reg Cout,
        input [15:0] A, B,
        input Cin
        );

        reg [3:0] BP, BG;

        reg [3:0] Cout_itermed;

        carries my_carries(BP, GP, Cin, Cout_itermed, Cout);

        CLA_4bit cla0(S[3:0], Cout_itermed[0], BP[0], BG[0], A[3:0], B[3:0], Cin);

        CLA_4bit cla1(S[7:4], Cout_itermed[1], BP[1], BG[1], A[7:4], B[7:4], Cout_itermed[0]);

        CLA_4bit cla2(S[11:8], Cout_itermed[2], BP[2], BG[2], A[11:8], B[11:8], Cout_itermed[1]);

        CLA_4bit cla3(S[15:12], Cout_itermed[3], BP[3], BG[3], A[15:12], B[15:12], Cout_itermed[2]);

        Cout = Cout_itermed[3];
endmodule

module carries (
        input [3:0] BP,
        input [3:0] BG,
        input Cin,
        output reg [3:0] Cout_itermed,
        output reg Cout
        );

        assign Cout_itermed[0] = BG[0] |  (BP[0] & Cin);
        assign Cout_itermed[1] = BG[1] |  (BP[1] & Cout_itermed[0]);
        assign Cout_itermed[2] = BG[2] |  (BP[2] & Cout_itermed[1]);

        assign Cout = Cout_itermed[3]; 

endmodule

Форма сигнала отображается (и правильно), когда я запускаю тестовый стенд 4-битного CLA. Может ли кто-нибудь объяснить, где проблема заключается в модуле carries или CLA_16bit?


person U. Muneeb    schedule 05.10.2016    source источник


Ответы (1)


Cout_itermed имеет два драйвера: первый является выходом Cout модуля CLA_4bit, а второй - выходом Cout_itermed модуля carries.

То же самое относится к Cout в CLA_16bit (хотя два драйвера в конечном итоге являются одним и тем же сигналом, Cout_itermed[3], в CLA_16bit и carries).

Помните, что в Verilog вы описываете физическую схему, и у вас никогда не должно быть двух источников (драйверов), подключенных к одному и тому же проводу - вот как мы получаем короткие замыкания!

Следующее основано на https://en.wikipedia.org/wiki/Lookahead_carry_unit#16-bit_adder. Что вам нужно сделать, так это определить удаление Cout_itermed[x] из порта Cout в CLA_16bits (вы можете просто оставить порт висящим). Вы должны переместить логику для определения Cout_itermed[3] (т.е. BG[3] | (BP[3]&Cout_itermed[2])) в модуль carries.

person wilcroft    schedule 05.10.2016