verilogfpgaquartusintel-fpga

Verilog - output exuals to XXXXXXXX


I'm trying to design a 32-bit ALU. While simulating using Modelsim output R becomes mixed with x's and 0's like this, at time=20 the addition is calculated and at time=40, substraction is calcualted.

output

In the ALU I'm only calling 3 modules. Adder, substractor and 32-bit 2x1 mux. I will provide their code below except adder and substractor because I've tested them and they give correct results. Something weird happens when I put them in ALU. How can I fix this?

module alu32(input [31:0] A, input [31:0] B, input [2:0] ALUOP, output [31:0] R);
    
    wire [31:0] w0, w1, w2, w3, w4, w5, w6, w7;
    wire carry_out_add, carry_out_sub, carry_in;

    adder add(.sum(w0), .carry_out(carry_out_add), .A(A), .B(B), .carry_in(1'b0));  // ADD 000
    
    sub sub(.A(A), .B(B), .out(w1));  // SUB 001
    
    _32bit_mux2x1 mux(w0, w1, ALUOP, R);
    
endmodule

Here is my testbench for ALU:

`timescale 1ns / 1ps
`define DELAY 20

module testbench_alu32();
    reg [31:0] A = 32'b0; 
    reg [31:0] B = 32'b0; 
    wire [31:0] R = 32'b0;
    reg [2:0] ALUOP;
    reg clk, start;

    alu32 alu(A, B, ALUOP, R);

    initial begin
        clk = 1'b0;
        #10 start = 1'b1;
        #2100 $finish;
    end

    always #100 clk = ~clk;


    initial begin
        
        #`DELAY;

        // add
        A = 32'b00000001111000000001111011110101;
        B = 32'b00000000000000000000000000000010;
        ALUOP = 3'b000;

        #`DELAY;

        // sub
        A = 32'b00000000000000000000000000001111;
        B = 32'b00000000000000000000000000000011;
        ALUOP = 3'b001;

        #`DELAY;
    end


    initial 
    begin
        $monitor("\ntime=%2d, \nA=%32b, \nB=%32b, \nR=%32b, \nALUOP=%3b \n\n", $time, A, B, R, ALUOP);
    end

endmodule

32 bit 2x1 mux:

module _32bit_mux2x1(input [31:0] I0, input [31:0] I1, input s, output [31:0] out);

    genvar i;

    generate
    for(i=0; i<32; i=i+1)
        begin: no_time_left
            _1bit_mux2x1 mux2x1(I0[i], I1[i], s, out[i]);
        end
    endgenerate

endmodule

and finally 1-bit 2x1 mux:

module _1bit_mux2x1(input I0, input I1, input s, output out);

    wire input0;
    wire input1;
    wire s_not;
    
    not not_s(s_not, s);
    
    and and0(input0, s_not, I0);
    and and1(input1, s,     I1);
    
    or or0(out, input0, input1);

endmodule

Solution

  • The wire R has multiple drivers in your testbench. One is

    assign R = 32'b0;
    

    The other one is from ALU output:

    alu32 alu(A, B, ALUOP, R);
    

    You will see the bits of R become 'x' when ALU outputs '1' on those bits. You may fix the error by removing the "assign R" line.