Question

Im new to verilog, and Im trying to write certain multiplier, but when I run my testbench it doesn't show much. It looks like generate block does not assign any values to partial. Here is a screen:

enter image description here

And code:

Changed names in code, so it is more familiar for english users.

`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

Please tell me what I'm doing wrong.

Was it helpful?

Solution

The generate block is assigning to partial and result, however there are multiple drivers to the same wire. Generate block expands the code at compile time. When Executed it will be the equivalent to the following:

// 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));

Conflicting assignment values will cause the output to be X and having an assignment that feedback on self without a way to break the loop will also always be X.

An always block can be used instead. Part select cannot have variables (e.g. [7:i]), so you need to assign all of the bits at once or assign each bit. This is equivalent to generate code:

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

Note: The multiplier function does work as expected. It is outside the scope of the question to solve it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top