Electronic – output won’t work verilog

decoderverilog

I'm very new to verilog, and I'm not quite sure I'm getting it. I have a 4×16 decoder module that utilizes two 3×8 modules I've included from a separate file that worked under simulation. The problem is even though the test bench is providing the correct inputs, the output is undefined (XXXXXXXXXXX) so I'm pretty sure the 4 to 16 decoder is not returning the output as it should. Any help with this project would be much appreciated.

`timescale 1ns / 1ps

module decoder4_16test;

    // Inputs
    reg [3:0] d;

    // Outputs
    wire [15:0] o;

    // Instantiate the Unit Under Test (UUT)
    decoder4_16 uut (
        .d(d), 
        .o(o)
    );

    reg clk;
    reg [3:0] count;

    initial begin
        // Initialize Inputs
        d = 0;
        count = 0;
        clk = 0;
        // Wait 100 ns for global reset to finish
        #100;
        forever #10 clk = ~clk;
    end

    always @(posedge clk) begin
    //  if (count > 3) count = 0;
        d <= count[3:0];
        count <= count + 1; 
   end
endmodule

4 to 16 decoder (XXXbrokenXXX)

`timescale 1ns / 1ps
module decoder4_16(
    //inputs
    input [3:0] d,
    output reg [15:0] o
);

    wire en1, en2;
//  assign en1 = d[3];
    assign en1 = 1;
//  assign en2 = ~d[3];
    assign en2 = 0;

    decoder3_8 a(
        .d(d[2:0]),
        .en(en1), 
        .o(o[7:0])
    );

    decoder3_8 b(
        .d(d[2:0]), 
        .en(en2),
        .o(o[15:8])
    );

endmodule

3 to 8 decoder
`timescale 1ns / 1ps

module decoder3_8(
        //Inputs
        input [2:0] d,
        input en,
        //outputs
        output reg [7:0] o
        );

    //combinational logic
        always @(*) begin
                //conditional cases
                if(en) begin
                        case(d)
                                //converts binary comb to output wire
                                3'd7: o=8'd128;
                                3'd6: o=8'd64;
                                3'd5: o=8'd32;
                                3'd4: o=8'd16;
                                3'd3: o=8'd8;
                                3'd2: o=8'd4;
                                3'd1: o=8'd2;
                                3'd0: o=8'd1;
                                default: o = 8'd0;
                        endcase
                        if (!en) o = 8'd0;
                end
                //default case
                else
                        o=8'd0;
        end         
endmodule

enter image description here
Also, any resources you guys found that helped you learn verilog would be awesome as well (instructor only provided the readme text for verilog IEEE that might as well be in Greek).

edit changing the output type from reg to wire fixed the problem. The test bench now looks normal.
enter image description here

Best Answer

In decoder4_16 you declare o to be a reg type, but then you connect it to an output of a module instance. For a net that will be driven by a module instance output, you need to declare it as a wire type (for an output of the module being written, just remove the reg qualifier).

Other than that I don't see any glaring errors.

Make sure you test decoder3_8 and make sure it is working correctly before starting on decoder4_16.