Verilog 4x16 解码器输出错误数据

Posted

技术标签:

【中文标题】Verilog 4x16 解码器输出错误数据【英文标题】:Verilog 4x16 Decoder outputs wrong data 【发布时间】:2016-03-18 03:51:01 【问题描述】:

我已经使用 Verilog 及其测试实现了一个 4x16 解码器。对于每种情况,解码器都应输出一个 16 位数字,其中只有一个位为高位。运行程序时,我无法获得所有所需的输出。这是解码器和测试的代码,以及控制台的输出:

4x16 解码器:

module Decoder4x16 (input [3:0] select, input enable, output reg [16:0] out);

always @(select, enable)
begin

    if(enable == 1'b0)
        out = 16'b0000000000000000;
    else if(enable == 1'b1)
        if(select == 4'b0000)
            out <= 16'b0000000000000001;
        else if(select == 4'b0001)
            out <= 16'b0000000000000010;
        else if(select == 4'b0010)
            out <= 16'b0000000000000100;
        else if(select == 4'b0011)
            out <= 16'b0000000000001000;
        else if(select == 4'b0100)
            out <= 16'b0000000000010000;
        else if(select == 4'b0101)
            out <= 16'b0000000000100000;
        else if(select == 4'b0110)
            out <= 16'b0000000001000000;
        else if(select == 4'b0111)
            out <= 16'b0000000010000000;
        else if(select == 4'b1000)
            out <= 16'b0000000100000000;
        else if(select == 4'b1001)
            out <= 16'b0000001000000000;
        else if(select == 4'b1010)
            out <= 16'b0000010000000000;
        else if(select == 4'b1011)
            out <= 16'b0000100000000000;
        else if(select == 4'b1100)
            out <= 16'b0001000000000000;
        else if(select == 4'b1101)
            out <= 16'b0010000000000000;
        else if(select == 4'b111)
            out <= 16'b0100000000000000;
        else if(select == 4'b1111)
            out <= 16'b1000000000000000;
    end

endmodule

测试:

module Decoder4x16_test;

reg [3:0] select;
reg enable;
wire [16:0] out;

parameter sim_time = 2800;

Decoder4x16 decoder(select, enable, out);
initial #sim_time $finish;
initial
begin
    select = 4'b0000;
    enable = 1'b0;

    repeat(16) #10 begin
        enable = 1'b1;
        #85 $display("select = %b \t out = %b", select, out);
        select = select + 4'b0001;
    end
end
endmodule

当我运行程序时,它会输出正确的输出,直到它到达输入为 1101 的测试用例。之后,解码器输出它应该显示的错误值。这是输出:

select = 0000    out = 00000000000000001
select = 0001    out = 00000000000000010
select = 0010    out = 00000000000000100
select = 0011    out = 00000000000001000
select = 0100    out = 00000000000010000
select = 0101    out = 00000000000100000
select = 0110    out = 00000000001000000
select = 0111    out = 00000000010000000
select = 1000    out = 00000000100000000
select = 1001    out = 00000001000000000
select = 1010    out = 00000010000000000
select = 1011    out = 00000100000000000
select = 1100    out = 00001000000000000
select = 1101    out = 00010000000000000
select = 1110    out = 00010000000000000
select = 1111    out = 01000000000000000

【问题讨论】:

您打错了一个条件:else if(select == 4'b111) 应该是 else if(select == 4'b1110) 【参考方案1】:

这里,out 是一个reg,这意味着它拥有一个分配给它的值。 select=4'b1110 没有 else if 条件。因此,out保持保留先前的值来自select=4'b1101。也就是说,out 持有值00010000000000000,并显示出来。

所以,添加 else if 条件为select=4'b1110 并且代码可以正常工作。

  else if(select == 4'b1110)
            out <= 16'b0100000000000000;

此外,解码器是纯组合电路。在创建任何组合逻辑时,最好使用阻塞赋值(=)。因此,请使用以下语法。

  else if(select == 4'b1110)
            out = 16'b0100000000000000; // blocking

还有一点要详细说明,使用always@(*) 而不是手动敏感列表。这将有助于减少敏感度列表的混淆。

【讨论】:

【参考方案2】:

试试这个简单的代码,

module Decoder4x16 (input [3:0] select, 
                    input enable, 
                    output wire [16:0] out);

assign out = 17enable & (1'b1 << select);

endmodule

也在 ISE 中合成。

【讨论】:

你能解释一下assign out = 17enable &amp; (1'b1 &lt;&lt; select);吗? 1 移动到由选择输入给出的小数位。

以上是关于Verilog 4x16 解码器输出错误数据的主要内容,如果未能解决你的问题,请参考以下文章

编码器/译码器(Verilog HDL)|计算机组成

FPGA纯verilog代码解码CameraLink视频,附带工程源码和技术支持

FPGA纯verilog代码实现jpg解码rgb并输出显示,私我提供工程源码

Verilog学习笔记(05)

你知道Verilog HDL程序是如何构成的吗

Verilog编的8-3编码器