0
\$\begingroup\$

I'm very new to verilog, and I'm not quite sure I'm getting it. I have a 4x16 decoder module that utilizes two 3x8 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

\$\endgroup\$
  • 1
    \$\begingroup\$ Did you get any warnings or errors when you compiled decoder4_16? The output should NOT be declared as a reg, since it's being connected directly to submodule outputs. Also, I don't think it matters in this case, but I would use <= assignments in decoder3_8. \$\endgroup\$ – Dave Tweed Feb 14 '17 at 23:10
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 3_8 was working before I started. Changing reg to wire on my output did the trick. Thank you very much. \$\endgroup\$ – Alan Boxx Feb 14 '17 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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