1

我是 verilog 的新手,我正在尝试编写某些乘数,但是当我运行我的测试台时,它并没有显示太多。看起来生成块没有为部分分配任何值。这是一个屏幕:

在此处输入图像描述

和代码:

更改了代码中的名称,因此对于英语用户来说更熟悉。

`timescale 1ns/1ps


`ifndef N_WIDTH
`define N_WIDTH 8
`endif

module mult(datX, datY, result);

   parameter n = 8;
   input [n-1:0]  datX, datY;
   output [2*n-1:0] result;
   //assign datX = 8'b0;
   //assign datY = 8'b0;
   wire [n-1:0] partial;

   genvar i;
   generate
       for(i=0; i<n; i=i+1) begin: IloczynyCzesciowe
         if(i<7) assign partial[7:i] = datY[n-1-i:0];
         if(i==1) assign partial[0] = datY[7];
     if(i==7) assign partial[7] = datY[0];
         if(i>1) assign partial[i-1:0] = datY[n-1:n-i];
         assign partial = datX[i] * partial;
         assign result = result + (partial % (2^n-1));
       end
   endgenerate

endmodule

module testbench_mul;
 parameter n = 8;//`N_WIDTH;
 parameter clk_period = 2;
 reg clk, clk_ena;
 reg [n-1:0]  a,b;
 wire [2*n-1:0] res;
 reg [2*n-1:0] res_expected;



    initial begin
        a = 8'b00000001;
        b = 8'b00001111;
        #clk_period;
        clk = 0;
        clk_ena = 1;
        $display("actual_s = %d", a );
        res_expected = a + b;

    end

    always begin
        #clk_period;
        if (clk_ena)
            clk = ~clk;
    end

    mult #(.n(n)) UUT (.datX(a), .datY(b), .result(res));

    always @(posedge clk) begin
        a = a + 1;
        res_expected = a+b;
        #1;
        if (res != res_expected) begin
            $display("ERROR: a: %b, b: %b, sum:%b, expected:%b partial:%d", a,b,res, res_expected, UUT.partial);
        end
    end

    initial
    #200 $finish;

endmodule

请告诉我我做错了什么。

4

1 回答 1

3

生成块分配给partialresult,但是同一线路有多个驱动程序。生成块在编译时扩展代码。执行时,它将等效于以下内容:

// loop n=0
assign partial[7:0] = datY[n-1-0:0];
assign partial = datX[0] * partial;
assign result = result + (partial % (2^n-1));
// loop n=1
assign partial[7:1] = datY[n-1-1:0];
assign partial[0] = datY[7];
assign partial = datX[1] * partial;
assign result = result + (partial % (2^n-1));
// loop n=2
assign partial[7:2] = datY[n-1-2:0];
assign partial[2-1:0] = datY[n-1:n-2];
assign partial = datX[2] * partial;
assign result = result + (partial % (2^n-1));
// loop n=3
assign partial[7:3] = datY[n-1-3:0];
assign partial[3-1:0] = datY[n-1:n-3];
assign partial = datX[3] * partial;
assign result = result + (partial % (2^n-1));
// loop n=4
assign partial[7:4] = datY[n-1-4:0];
assign partial[4-1:0] = datY[n-1:n-4];
assign partial = datX[4] * partial;
assign result = result + (partial % (2^n-1));
// loop n=5
assign partial[7:5] = datY[n-1-5:0];
assign partial[5-1:0] = datY[n-1:n-5];
assign partial = datX[5] * partial;
assign result = result + (partial % (2^n-1));
// loop n=6
assign partial[7:6] = datY[n-1-6:0];
assign partial[6-1:0] = datY[n-1:n-6];
assign partial = datX[6] * partial;
assign result = result + (partial % (2^n-1));
// loop n=7
assign partial[7] = datY[0];
assign partial[7-1:0] = datY[n-1:n-7];
assign partial = datX[7] * partial;
assign result = result + (partial % (2^n-1));

冲突的赋值值将导致输出为X并且有一个赋值给 self 反馈而没有办法打破循环也将永远是X

可以使用 always 块代替。零件选择不能有变量(例如[7:i]),因此您需要一次分配所有位或分配每个位。这相当于生成代码:

reg [2*n-1:0] result;
reg [n-1:0] partial;
integer i;
always @* begin
  result = 0;
  for(i=0; i<n; i=i+1) begin: IloczynyCzesciowe
    // partial[7:0] = {datY,datY} >> (8-i); // this functional also works
    for(j=0; j<n; j++) begin : assign_bits
      partial[j] = datY[(8+j-i)%8];
    end
    partial = datX[i] * partial;
    result = result + (partial % (2^n-1));
  end
end

注意:乘法器功能确实按预期工作。解决它超出了问题的范围。

于 2013-06-05T23:15:03.547 回答