output - Why are my Verilog output registers only outputting "x"?
问题描述
I've written the following module to take in a 12-bit stream of input, and run it through the Exponential Moving Average (EMA) formula. When simulating the program, it appears as if my output is a 12-bit stream of "don't cares". Regardless of what my input is, it isn't realized by the output register.
I'm a beginner at Verilog, so I'm sure there are a slew of issues here, but I expected to at least get some kind of output. Why is this behavior occurring and how can I fix it from occurring in the future? I've linked a screenshot of my waveform results at the bottom of this post.
My verilog module:
`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
My verilog testbench:
`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. Note that both output registers are giving no values.
解决方案
您的代码中有很多错误。@先生。Snrub 列出了其中的一些。您可以纠正注释中列出的错误,通过进一步编辑您的代码,您可以使其按您的意愿工作,但还有更重要的基本问题。您必须在将来进一步和难以调试错误之前解决它们,这也有助于更好地理解 HDL 概念。
- 首先,您需要了解软件编程语言和硬件描述语言之间的区别。您应该对此进行进一步的研究,您所犯的错误通常是由假设 HDL 类似于软件编程语言的开发人员所犯的。检查此链接以获取更多信息。
- 您需要进一步了解 Verilog HDL(或任何其他 HDL)代码是如何合成的以及使用它们的原因。
- 需要熟悉何时以及如何使用阻塞
=
或非阻塞<=
分配以及它们是如何工作的。检查此链接。
当您研究列出的主题时,您会明白在边缘敏感(同步或顺序)always
块中,使用阻塞=
分配是个坏主意。
当您使用阻塞分配时,分配是按顺序完成的,就像在常见的软件编程语言中一样。在边缘敏感always
块的情况下,您完成always
块内所有必需分配的时间非常有限。
在您的情况下,由于边缘敏感 always 块内的所有分配都是阻塞的(假设没有重置条件):
- 首先,它检查是否
count
小于 64,如果是,则完成分配。所有其他作业都在等待该作业完成。 - 当第一次分配完成时,
always
具有敏感性的块posedge clock_in
可能已经结束执行并等待时钟的下一个边沿。因此,其他任务没有完成。 - 由于您尚未初始化输出寄存器,因此它们最初填充了“无关”,并且永远不会再次分配新值,因此,您得到了该输出(填充了“无关”)。
- 即使
count
变得大于或等于 64,在将值分配给newEMA
.
推荐阅读
- android - 在没有 android studio 的情况下在 windows 上运行颤振的问题
- html - Flow/Typescript 从字符串验证 HTML 元素类型
- java - 程序类型已经存在:androidx.test.InstrumentationRegistry
- r - 如何使非常小的数字在r中精确为零?
- oracle - 案例陈述中缺少右括号
- python-3.x - 从 RaspberryPi 按钮向 Firebase 添加数据
- android-studio - 清除缓存/无效后 Android Studio 将无法打开
- c# - 将 http 更改为 https mvc 时 jquery 库的错误 Https
- android - LifecycleOwner: Fragment (self) 和 Fragment#viewLifecycle 的区别
- javascript - jQuery触发单击以显示错误不起作用