1
\$\begingroup\$

I have a problem with verilog. So the structure for my code is I have top module, then have another 2 sub-module that I called on the top module

Here's some of my code

genvar i;
genvar j;
wire[2:0] encoder[7:0]; //4bit reg array of 8 element
wire[8:0] save_tmp[7:0];
wire [8:0] tmp; //1bit

generate
    for(i=0;i<N;i=i+1) begin: gen_loop
        module1 mod1(.prev(0), .cur(1), .next(1), .out(encoder[i]));               
        
        for(j=0;j<N;j=j+1) begin: gen_ppg
            module2 mod2(.encoded(encoder[i]), .in1(1'b0), .in2(1'b0), .out(tmp[j]));
        end
        assign save_tmp[i] = tmp;
    end
endgenerate

I can get the output from the first module (through encoder) and also no problem when I sent it into the second module (module2). Here's my second module:

module module2(encoded, in1, in2, out);
    input [2:0] encoded; 
    input in1, in2; 
    output out;
    
    wire nand1, nand2;
    
    assign nand1 = ~(in1 & encoded[2]);
    assign nand2 = ~(in2 & encoded[1]);
    
    assign out =  ~(nand1 & nand2) ^ encoded[0];
endmodule

I'm trying to make a testbench just for calling module2 and it's working. But when I put it on the top function, I can get the value from nand1 and nand2 but not the output.

enter image description here Can anyone knows the problem ?

\$\endgroup\$
1
  • \$\begingroup\$ + you should add full codes \$\endgroup\$
    – Mitu Raj
    Nov 15, 2021 at 16:33

2 Answers 2

0
\$\begingroup\$

Each index of tmp as more than one driver. If any of the drivers values conflict, the result is an X. Each index of tmp needs to have only one driver. There are two ways to do this.

One is to add more bits to tmp and assign explicitly:

genvar i;
genvar j;
wire[2:0] encoder[7:0]; //4bit reg array of 8 element
wire[8:0] save_tmp[7:0];
wire [8:0] tmp [7:0]; //1bit <-- Add range [7:0]

generate
    for(i=0;i<N;i=i+1) begin: gen_loop
        module1 mod1(.prev(0), .cur(1), .next(1), .out(encoder[i]));               
        
        for(j=0;j<N;j=j+1) begin: gen_ppg
            module2 mod2(.encoded(encoder[i]), .in1(1'b0), .in2(1'b0), .out(tmp[i][j])); // <-- Add [i]
        end
        assign save_tmp[i] = tmp[i]; // <-- Add [i]
    end
endgenerate

The other approach is the declare tmp inside the generate loop. Then each index of the loop will have its own scope limited instance.

genvar i;
genvar j;
wire[2:0] encoder[7:0]; //4bit reg array of 8 element
wire[8:0] save_tmp[7:0];

generate
    for(i=0;i<N;i=i+1) begin: gen_loop
        wire [8:0] tmp; //1bit <-- tmp is now local to the gen_loop index
        module1 mod1(.prev(0), .cur(1), .next(1), .out(encoder[i]));               
        
        for(j=0;j<N;j=j+1) begin: gen_ppg
            module2 mod2(.encoded(encoder[i]), .in1(1'b0), .in2(1'b0), .out(tmp[j]));
        end
        assign save_tmp[i] = tmp;
    end
endgenerate
\$\endgroup\$
0
1
\$\begingroup\$

If N is greater than 1, then you will have contention on the tmp signals, resulting in unknowns (x).

For example, assume N=2. If you were to unroll the nested for loops, you would have 4 instances of the module2 module like this:

module2 mod2_00 (.encoded(encoder[0]), .in1(1'b0), .in2(1'b0), .out(tmp[0]));
module2 mod2_01 (.encoded(encoder[0]), .in1(1'b0), .in2(1'b0), .out(tmp[1]));
module2 mod2_10 (.encoded(encoder[1]), .in1(1'b0), .in2(1'b0), .out(tmp[0]));
module2 mod2_11 (.encoded(encoder[1]), .in1(1'b0), .in2(1'b0), .out(tmp[1]));

The 1st and the 3rd lines both drive the tmp[0] net, which is contention, resulting in x.

Similarly, the 2nd and the 4th lines both drive the tmp[1] net.

You need to rework your design to avoid multiple drivers of the same net.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.