Search code examples
vectorveriloghdl

Passing a vector and performing operations on it results in X


This is the module that I'm trying to implement. What I want to do is, receive a vector say 2 bits wide having 4 elements that I linearize and pass from the testbench to the test_module1. Now I want to de-linearize it and perform some combinational operations on it to get a fitness value based on Rosenbrock function. However, I get the fitness value as XX.

I'm unable to understand the issue here.

module test_module1 ( x, fitness);
    input   [4*2 -1:0]  x;  
    output  [1:0]   fitness;

    wire [1:0] x_i;
    wire [1:0] x_im1;
    wire [1:0] fitness_val = 2'b00;
    wire [3:0] a;
    wire [3:0] b;
    wire [1:0] x_array1 [3:0];
    
    genvar k;
    assign fitness = fitness_val;
    genvar j;
    
    generate
      for (j =0 ; j <4 ; j = j+1) begin
          assign x_array1[j] = x[2*j +: 2];
      end
    

      for (k=1; k<4; k=k+1) begin
            assign x_i      = x_array1[k];
            assign x_im1    = x_array1[k-1];
            assign a = 100*(x_i[1:0] - x_im1[1:0])*(x_i[1:0] - x_im1[1:0]);
            assign b = (1 - x_im1[1:0])*(1 - x_im1[1:0]);
            assign fitness_val = fitness_val + a[2:1] + b[2:1];
        end
    endgenerate 
endmodule

Testbench:

module tb_tm1();
  wire  [1:0]   fitness;
  wire [4*2-1:0] x_array;
  
  test_module1 tm1(x_array, fitness);
  
  assign x_array = 8'b11100100;
  
endmodule

The output I get is like this: Output


Solution

  • The cause of the X (unknown value) is due to contention caused by multiple drivers for the same signal.

    For example, signal fitness_val has 5 drivers. The 1st is the line:

    wire [1:0] fitness_val = 2'b00;
    

    This is a continuous assignment, which means the simulator is always trying to drive it to 0. The other 4 drivers are from the for k loop:

    assign fitness_val = fitness_val + a[2:1] + b[2:1];
    

    If you were to write out the loop long-hand, you would have 4 identical assign lines. fitness_val should only have 1 driver, not 5.

    You have multiple drivers of all 5 signals in that for loop.

    Another problem with the assign fitness_val line is that it creates a combinational loop. You should not have fitness_val on both the LHS and RHS of a continuous assignment.