1

I have been trying to code encoder in Verilog. The code is compiling without error but the output are unexpected. The output is not changing with input. I am attaching the code and the pic of the output.

I have initialized out with value 0 in each module. But the value of out is not getting updated in the case statement. That's why the output is always zero.

I tried to check value of the variable 'in' in the modules using the $display keyword, but it isn't showing anything. I guess the input variable 'in' inside the encoder modules is not taking the input values from the test module. I don't know why is this happening.

module ENCODER_2_1(
    output reg out,
    input [1:0] in,
    input enable);

    initial begin
        out = 1'b0;
        if (enable) begin
            case (in)
                2'b00 : out = 1'b0;
                2'b10 : out = 1'b1;
                default : out = 8'b00000000;
            endcase
        end
    end

endmodule

module ENCODER_4_2(
    output reg [1:0] out,
    input [3:0] in,
    input enable);

    initial begin
        out = 2'b00;
        if (enable) begin
            case (in)
                4'b0000 : out = 2'b00;
                4'b0001 : out = 2'b01;
                4'b0010 : out = 2'b10;
                4'b0100 : out = 2'b11;
                default : out = 8'b00000000;
            endcase
        end
    end

endmodule

module ENCODER_8_3(
    output reg [2:0] out,
    input [7:0] in,
    input enable);

    initial begin
        out = 3'b000;
        if (enable) begin
            case (in)
                8'b00000000 : out = 3'b000;
                8'b00000001 : out = 3'b001;
                8'b00000010 : out = 3'b010;
                8'b00000100 : out = 3'b011;
                8'b00001000 : out = 3'b100;
                8'b00010000 : out = 3'b101;
                8'b00100000 : out = 3'b110;
                8'b01000000 : out = 3'b111;
                default : out = 8'b00000000;
            endcase
        end
    end

endmodule

module ENCODER_16_4(
    output reg [3:0] out,
    input [15:0] in,
    input enable);

    initial begin
        out = 4'b0000;
        if (enable) begin
            case (in)
                16'h0000 : out = 4'b0000;
                16'h0001 : out = 4'b0001;
                16'h0002 : out = 4'b0010;
                16'h0004 : out = 4'b0011;
                16'h0008 : out = 4'b0100;
                16'h0010 : out = 4'b0101;
                16'h0020 : out = 4'b0110;
                16'h0040 : out = 4'b0111;
                16'h0080 : out = 4'b1000;
                16'h0100 : out = 4'b1001;
                16'h0200 : out = 4'b1010;
                16'h0400 : out = 4'b1011;
                16'h0800 : out = 4'b1100;
                16'h1000 : out = 4'b1101;
                16'h2000 : out = 4'b1110;
                16'h4000 : out = 4'b1111;
                default : out = 8'b00000000;
            endcase
        end
    end

endmodule

//To run the test uncomment this block

module test();


    wire out1;
    wire [1:0] out2;
    wire [2:0] out3;
    wire [3:0] out4;

    reg [1:0] in2;
    reg [3:0] in4;
    reg [7:0] in8;
    reg [15:0] in16;

    reg enable;

    ENCODER_2_1 enc_2_1(out1, in2, enable);
    ENCODER_4_2 enc_4_2(out2, in4, enable);
    ENCODER_8_3 enc_8_3(out3, in8, enable);
    ENCODER_16_4 enc_16_4(out4, in16, enable);

    initial begin
        
        enable = 1;

        #1 $display("\n2:1 Encoder");
           $monitor("input = %b | output = %b",in2, out1);

           in2 = 2'b00;
        #1 in2 = 2'b10;

        #1 $display("\n4:2 Encoder");
           $monitor("input = %b | output = %b",in4, out2);

           in4 = 4'b0000;
        #1 in4 = 4'b0001;
        #1 in4 = 4'b0010;
        #1 in4 = 4'b0100;

        #1 $display("\n8:3 Encoder");
           $monitor("input = %b | output = %b",in8, out3);

           in8 = 8'b00000000;
        #1 in8 = 8'b00000001;
        #1 in8 = 8'b00000010;
        #1 in8 = 8'b00000100;
        #1 in8 = 8'b00001000;
        #1 in8 = 8'b00010000;
        #1 in8 = 8'b00100000;
        #1 in8 = 8'b01000000;

        #1 $display("\n16:4 Encoder");
           $monitor("input = %h | output = %b",in16, out4);

           in16 = 16'h0000;
        #1 in16 = 16'h0001;
        #1 in16 = 16'h0002;
        #1 in16 = 16'h0004;
        #1 in16 = 16'h0008;
        #1 in16 = 16'h0010;
        #1 in16 = 16'h0020;
        #1 in16 = 16'h0040;
        #1 in16 = 16'h0080;
        #1 in16 = 16'h0100;
        #1 in16 = 16'h0200;
        #1 in16 = 16'h0400;
        #1 in16 = 16'h0800;
        #1 in16 = 16'h1000;
        #1 in16 = 16'h2000;
        #1 in16 = 16'h4000;

    end 

endmodule

The output is given below:

Output

Why isn't the output changing?

1 Answer 1

0

In all your ENCODER modules, change:

initial begin

to:

always @* begin

The code in your ENCODER modules only executes once at time 0 because the code is in an initial block. You want the module outputs to be updated every time any input changes. This is accomplished with always @*.

If you enable SystemVerilog features in your simulator, you could use

always_comb begin

I see the output changing:

2:1 Encoder
input = 00 | output = 0
input = 10 | output = 1

4:2 Encoder
input = 0000 | output = 00
input = 0001 | output = 01
input = 0010 | output = 10
input = 0100 | output = 11

8:3 Encoder
input = 00000000 | output = 000
input = 00000001 | output = 001
input = 00000010 | output = 010
input = 00000100 | output = 011
input = 00001000 | output = 100
input = 00010000 | output = 101
input = 00100000 | output = 110
input = 01000000 | output = 111
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.