【问题标题】:16-bit multiplier simulation results are incorrect16位乘法器仿真结果不正确
【发布时间】:2013-12-04 10:47:12
【问题描述】:

我在 Verilog 中设计了一个 16×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

而 tb 是:

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

怎么了?

【问题讨论】:

    标签: verilog


    【解决方案1】:

    即使它编译,连接也不正确。例如,ci[width*i] 其中i&gt;0 将有两个驱动程序,一个是assign 语句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 模块有未使用的门和网络。该代码没有任何难以理解的 cmets 或标签。

    尝试拆分进位。一组作为每个部分和的执行。另一个作为带有生成for循环的本地网络。通常,在生成 for 循环中创建本地网络有助于提高可读性并且是可能的。与其调试 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]};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多