2013-12-04 3 views
0

Я разработал множитель 16 на 16 в verilog. Он компилируется без ошибок, но результаты неверны. Может ли кто-нибудь помочь мне в преобразовании кода?verilog код для 16-битного умножителя

Код:

module q_1_2 (input [15:0]x,y, output [31:0]z); 

    parameter size=256, width=16; 
    wire [size-1:0]pi,ci,po,co; 

    genvar i,j; 
    generate 

    for (j=0;j<16;j=j+1) assign pi[width*0+j]=0; 
    for (i=0;i<16;i=i+1) assign ci[width*i+0]=0; 
    q_1_1 eb0_0 (x[0],y[0],pi[o],ci[0],po[0],co[0]); 

    for (j=1;j<16;j=j+1) begin 
    assign ci[width*0+j] = co[width*0+(j-1)]; 
    q_1_1 eb0_j (x[0],y[j],pi[width*0+j],ci[width*0+j],po[width*0+j],co[width*0+j]); 
    end 

    for (i=1;i<16;i=i+1) begin 
    assign pi[width*i+0] = po[width*(i-1)+0]; 
    q_1_1 ebi_0 (x[i],y[0],pi[width*i+0],ci[width*i+0],po[width*i+0],co[width*i+0]); 
    end 

    for (i=1;i<16;i=i+1) begin 
     for (j=1;j<15;j=j+1) begin 
     assign ci[width*i+j] = co[width*i+(j-1)]; 
     assign pi[width*i+j] = po[width*(i-1)+j]; 
     q_1_1 ebi_j (x[i],y[j],pi[width*i+j],ci[width*i+j],po[width*i+j],co[width*i+j]); 
     end 

     assign ci[width*i+15] = co[width*i+14]; 
     assign pi[width*i+15] = co[width*(i-1)+15]; 
     q_1_1 ebi_15 (x[i],y[15],pi[width*i+15],ci[width*i+15],po[width*i+15],co[width*i+15]); 
    end 

    for (i=0;i<16;i=i+1) assign z[i] = po[width*i+0]; 
    for (j=1;j<16;j=j+1) assign z[j+15] = po[width*15+j]; 
    assign z[31] = co[width*15+15]; 

    endgenerate 
endmodule 

где модуль q_1_1 является:

module q_1_1 (input xi,yi,pi,ci, output po,co); 
    wire i,j,k,l,m,n; 
    and #5 (i,xi,yi); 
    and #5 (j,pi,i); 
    and #5 (k,ci,i); 
    and #5 (l,pi,ci); 
    or #5 (m,j,k); 
    or #5 (co,l,m); 
    xor #5 (n,pi,i); 
    xor #5 (po,ci,i); 
endmodule 

и ТБ является:

module testq_1_2(); 

reg [15:0] xx,yy; 
wire[31:0] zz; 

q_1_2 eb(xx,yy,zz); 

initial begin 
    #0  xx=0;  yy=0; 
    #1000 xx=9;  yy=11; 
    #1000 xx=16; yy=8; 
    #1000 xx=14; yy=14; 
    #1000 xx=7;  yy=12; 
    #1000 xx=24; yy=3; 
    #1000 xx=83; yy=201; 
    #1000 xx=24831; yy=19047; 
    #1000 xx=0;  yy=0; 
    #1000; 
    end 
endmodule 

так что не так?

tnx!

+0

Я не понимаю, вы говорите, что у него нет ошибок, а затем говорят: «Но это не значит, может ли кто-нибудь помочь мне посредством преобразования кода?» Я не знаю, что это значит – Morgan

ответ

0

Несмотря на то, что он скомпилирован, соединения неверны. Например, ci[width*i], где i>0 будет иметь два драйвера, один - оператор назначения assign ci[width*i+0]=0;, а другой - assign ci[width*0+j] = co[width*0+(j-1)];. Аналогичная проблема для pi[width*i]. Существует также pi[o], который, я считаю, должен быть pi[0]. Модуль q_1_1 имеет неиспользуемые ворота и сети. В коде нет комментариев или ярлыков, из-за которых сложно следовать.

Попробуйте разделить перенос. Одна группа, выполняемая для каждой частичной суммы. Другая - как локальная сеть, сгенерирующая for-loop. В общем случае создание локальных сетей с генератором for-loop может помочь с удобочитаемостью и вероятно. Вместо того, чтобы отлаживать множитель 16 на 16, уменьшите его до 4 на 4 или 2 на 2. Это будет легче отлаживать. У вас уже есть параметр, просто нужно использовать его еще в нескольких местах.

Ниже приведен пример того, как соединения должны работать для множителя. Я удалил логические части, так как этот вопрос кажется домашним заданием.

wire [WIDTH*WIDTH-1:0] pp,mask; 
wire [WIDTH-1:0] rco; // ripple carry out 

assign rco[0] = 1'b0; 
assign pp[WIDTH-1:0] = mask[WIDTH-1:0]; 

genvar i,j; 
generate 
    for (i=0; i<WIDTH; i=i+1) begin : mask_mux 
     assign mask[WIDTH*i +: WIDTH] = // mux logic ... 
    end 

    for (i=1; i<WIDTH; i=i+1) begin : ripple_adder 
     // These wire are local to this scope 
     wire [WIDTH-1:0] part_sel; 
     wire [WIDTH:0] carry; 
     assign carry[0] = 1'b0; 
     assign part_sel[WIDTH-1] = rco[i-1]; 
     assign part_sel[WIDTH-2:0] = pp[WIDTH*(i-1)+1 +: WIDTH-1]; 
     for (j=0; j<WIDTH; j=j+1) begin : bit_adder 
      // adder logic ... 
     end 
     assign rco[i] = carry[WIDTH]; 
    end 
    for (i=0; i<WIDTH;i=i+1) begin : output_lsb 
     assign z[i] = pp[WIDTH*i]; 
    end 
endgenerate 
assign z[WIDTH*2-1:WIDTH] = {rco[WIDTH-1],pp[WIDTH*WIDTH-1 -: WIDTH-1]}; 
Смежные вопросы