编码器的 verilog 代码中的意外输出

Unexpected output in verilog code for encoder

我一直在尝试用 Verilog 编写编码器。代码编译没有错误,但输出是意外的。输出不随输入变化。我附上代码和输出图片。

我已经在每个模块中用值 0 初始化了。但是 out 的值没有在 case 语句中更新。这就是输出始终为零的原因。

我尝试使用 $display 关键字检查模块中变量 'in' 的值,但它没有显示任何内容。我猜编码器模块内的输入变量 'in' 没有从测试模块获取输入值。我不知道为什么会这样。

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

输出如下:

为什么输出没有变化?

在所有 ENCODER 模块中,更改:

initial begin

至:

always @* begin

您的 ENCODER 模块中的代码仅在时间 0 执行一次,因为该代码位于 initial 块中。您希望每次输入更改时更新模块输出。这是通过 always @*.

完成的

如果您在模拟器中启用 SystemVerilog 功能,您可以使用

always_comb begin

我看到输出在变化:

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