【问题标题】:Why are my Verilog output registers only outputting "x"?为什么我的 Verilog 输出寄存器只输出“x”?
【发布时间】:2019-03-20 03:20:44
【问题描述】:

我编写了以下模块来接收 12 位输入流,并通过 Exponential Moving Average (EMA) 公式运行它。在模拟程序时,我的输出似乎是一个 12 位的“不关心”流。不管我的输入是什么,它都不是由输出寄存器实现的。

我是 Verilog 的初学者,所以我确信这里有很多问题,但我希望至少能得到某种输出。为什么会发生这种行为,我该如何解决它,以免将来发生?我在这篇文章的底部链接了我的波形结果的屏幕截图。

我的verilog模块:

`timescale 1ns / 1ps
module EMATesting (     input signed [11:0] signal_in,
                        output reg signed [11:0] signal_out,
                        input clock_in,
                        input reset,
                        input enable,
                        output reg [11:0] newEMA);

reg [11:0] prevEMA;
reg [11:0] y;
reg [11:0] temp;
integer count = 0;
integer t = 1;
integer one = 1;
integer alpha = 0.5;

always @(posedge clock_in) begin

    if (reset) begin
        count = 0;
        end

    else if (count < 64) begin
         count = count + 1;
        end

//set the output equal to the first value received
    if (count == 1) begin
        newEMA = signal_in;
        end

//if not the first value, run through the formula
    else begin
        temp = newEMA;
        prevEMA = temp;
        newEMA = alpha * signal_in + (one-alpha) * prevEMA;
        count = count + 1;
        end
    end
endmodule

我的 verilog 测试平台:

`timescale 10ns / 1ns
module testbench_EMA;

reg signal_in;
reg clock_in, reset, enable;
wire [11:0] signal_out;
wire [11:0] newEMA;

initial begin
    signal_in = 0; reset = 0; enable = 0;
    clock_in = 0;
end

EMATesting DUT(signal_in, signal_out, clock_in, reset, enable, newEMA);

initial
begin
//test some values with timing intervals here 
#100;
reset = 1;
#100;
reset = 0;
enable = 1;
#100;
//set signal_in to "1" repeating 12 times
signal_in = { 12 { 1'b1}};
#100;
reset = 1;
#100; //buffer to end simulation
$finish;
end


always
    #5 clock_in = !clock_in;

endmodule

Waveform results of my testbench。请注意,两个输出寄存器都没有给出任何值。

【问题讨论】:

  • 您可能应该将此问题移至电气工程堆栈交换,在那里您可能会有更好的运气。我自己不是 Verilog 用户(取而代之的是 VHDL),但我可以指出三个基本问题:1)您永远不会在任何地方为 signal_out 赋值,这样就可以解释 X 在那里,2)您应该始终重置您的所有reset 块中的输出,以及 3) 您将 alpha 设置为 0.5,但您已将其声明为 integer,因此这显然不起作用。似乎也存在一些 Verilog 分配问题,但您仍然需要实际的 Verilog 用户来指出这些问题。
  • 我同意@Mr.鼻涕虫。此外,永远不要在 always@(posedge clock_in) 块中使用 '=' - 阻塞分配。

标签: output verilog


【解决方案1】:

您的代码中有很多错误。 @先生。 Snrub 列出了其中的一些。您可以更正 cmets 中列出的错误,并且通过进一步编辑您的代码,您可以使其按您的意愿工作,但还有更重要的基本问题。您必须先解决这些问题,然后再犯进一步且难以调试的错误,这也有助于更好地理解 HDL 概念。

  • 首先,您需要了解软件编程语言和硬件描述语言之间的区别。您应该对此进行进一步的研究,您所犯的错误通常是由假设 HDL 类似于软件编程语言的开发人员所犯的。检查this 链接以获取更多信息。
  • 您需要进一步了解 Verilog HDL(或任何其他 HDL)代码是如何合成的以及使用它们的原因。
  • 需要熟悉何时以及如何使用阻塞 = 或非阻塞 &lt;= 分配以及它们的工作原理。检查this 链接。

当您研究列出的主题时,您会明白在边缘敏感(同步或顺序)always 块中,使用阻塞 = 分配是个坏主意。

当您使用阻塞分配时,分配是按顺序完成的,就像在常见的软件编程语言中一样。对于边缘敏感的always 块,您完成always 块内所有必需分配的时间非常有限。

在您的情况下,由于边缘敏感总是块内的所有分配都是阻塞的(假设没有重置条件):

  • 首先,它检查count 是否小于64,如果是,则完成分配。所有其他作业都在等待该作业完成。
  • 在第一次分配完成时,具有posedge clock_in 灵敏度的always 块可能已经结束执行并等待时钟的下一个边沿。所以,其他的作业没有做完。
  • 由于您尚未初始化输出寄存器,它们最初被填充为“不关心”,并且从未再次分配新值,因此,您得到了该输出(填充为“不关心” )。
  • 即使count 大于或等于 64,在将值分配给 newEMA 之前,您还有其他阻塞分配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多