Verilog:甚至在时钟上设置恒定值
我是 Verilog 新手,所以这个问题可能很愚蠢。
我正在尝试:我有一个具有 clk、8 位输入和 8 位输出的组件。它应该做的是:
如果时钟事件是下降沿,则应将输出设置为 0 如果时钟事件是正边沿,则应将输出设置为边沿事件此时的输入。在时钟的高电平阶段,无论输入发生变化,输出都不应改变。
到目前为止我尝试过的:
always @(negedge clk)
_ledOut <= 0;
always @(posedge clk)
_ledOut[RowSize-1:0] <= ledIn[RowSize-1:0];
这告诉我,它无法解析 net _ledOut 的多个常量驱动程序。
然而,将其放在始终 @(negedge clk, posege clk) 中告诉我,它无法测试这两种条件。
所以我尝试只制作一个always @(clk) 块,然后使用if 语句:
always @(clk) begin
if(clk == 0)
_ledOut <= 0;
else if(clk == 1)
_ledOut[RowSize-1:0] <= ledIn[RowSize-1:0];
end
但这不仅仅是打开clk 事件。在时钟的高电平阶段,它将 _ledOut 与 ledIn 链接起来,因此 ledIn 上的更改也会对 _ledOut 产生影响。我在这里做错了什么?
此致, 迈克尔
I am new to Verilog, so this question might be quite dumb.
What I am trying: I have a component that has a clk, an 8 bit input and an 8 bit output. What it should do, is:
If the clock event is negative edge, it should set the output to 0
If the clock event is positive edge, it should set the output to whatever input is at this moment of the edge event. During the high phase of the clock, the output should NOT change, regardless changes on the input.
What I tried so far:
always @(negedge clk)
_ledOut <= 0;
always @(posedge clk)
_ledOut[RowSize-1:0] <= ledIn[RowSize-1:0];
This tells my, that it can't resolve multiple constant drivers for net _ledOut.
However, putting this together in an always @(negedge clk, posedge clk) tells me, it can't test for both conditions.
So I tried to make just one always @(clk) block and then used an if statement:
always @(clk) begin
if(clk == 0)
_ledOut <= 0;
else if(clk == 1)
_ledOut[RowSize-1:0] <= ledIn[RowSize-1:0];
end
But this didn't just switch on a clk event. During the high phase of the clock, it links _ledOut with ledIn, so that changes on ledIn do also have effect on _ledOut. What am I doing wrong here?
Best regards,
Michael
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于综合,您不能从多个always块分配reg类型。
这实质上描述了 DDR 寄存器。虽然许多 FPGA 器件都具有这些特性,但它们通常无法综合。如果您确实需要此功能,Xilinx 可以使用 ODDR2 和 IDDR2 原语。
如果这就是您所需要的,那么您可以使用输出端带有与门的 D 触发器。触发器将在 clk 的每个上升沿对 ledIn 进行采样,并且只要时钟为零,与门就会屏蔽输出。这并不理想,因为您通常不希望时钟接触非顺序逻辑,但避免这种情况可能意味着改变您的要求。
正如 toolic 所示,您发布的代码将起作用,但您应该了解该代码将合成到由 clk 控制的多路复用器。
For synthesis you cannot assign reg types from multiple always blocks.
This essentially describes a DDR register. While many FPGA devices have these they typically cannot be synthesized. Xilinx uses ODDR2 and IDDR2 primitives if you really need this functionality.
If this is all you need then you can use a D flip flop with an AND gate on the output. The flip-flop will sample ledIn on each rising edge of clk and the AND gate will mask the output whenever the clock is zero. This is not ideal as you generally do not want clocks to touch non-sequential logic but avoiding this would likely mean changing your requirements.
As toolic indicated, the code you posted will work but you should understand that code will synthesize to a multiplexer controlled by clk.
好的,现在这是我的工作解决方案。也许这不是您见过的最好的 verilog 代码。 ;)然而,这是我用它做的第一件事,作为我大学的一个项目。所以只要它做了我想让它做的事,这对我来说就是巨大的成功! ;)
这是我现在使用的代码,感谢 Adam12:
Ok, here is my working solution now. Maybe it's not the best verilog code you have seen out there. ;) This is, however, my first thing I do with it, as a project at my university. So as long as it does what I want it to do, this is a great success to me! ;)
Here is the code I used now, thanks to Adam12:
考虑以下激励:
它产生以下输出:
请注意,在时间 22 处,当
ledIn
发生变化时,_ledOut
输出不会发生变化。_ledOut
仅在时间 30 处clk
的下一个 posege 处发生变化。因此,always @(clk)
解决方案正在执行您想要的操作:正如您所指定的,输出仅在时钟沿发生变化。Consider the following stimulus:
It produces this output:
Notice at time 22, when
ledIn
changes, the_ledOut
output does not change._ledOut
only changes at the next posedge ofclk
at time 30. Therefore, thealways @(clk)
solution is doing what you want: the output only changes at the clock edge, as you specified.这是一个非常不寻常的问题,它让我建议您需要提供更多有关您实际想要实现的目标的信息,因为如果这是针对 FPGA,它很可能会影响时序性能和时钟约束。已经提到了综合,但是您将把时钟门控输出输入什么?如果它是引脚焊盘,那么您应该阅读设备规范中的 DDR 焊盘缓冲区,并推断能够驱动 DDR 信号的特定原语。
如果您将此信号保留在芯片内,那么这是一个非常奇怪的请求。如果我需要生成该波形,我可能会使用 PLL 生成两倍于基频的锁相时钟,并将门控数据放入该域,并通过切换来应用桅杆,以便工具能够正确分析时钟交叉,并且生成的数据路径仍然在单个边沿有效转换。
上面推断在输出上强制使用组合多路复用器的寄存器的答案很有趣,但是无论您将其输入什么,都必须处理尴尬的设置/保持条件,并且如果在片上,则无论如何都只会采样一个边缘,所以这有点多余。
This is a pretty unusual question, and it makes me advise you need to give more information about what you are actually trying to achieve, since it may well impact the timing performance and clock constraints if this is targeting an FPGA. Synthesis has been mentioned, but what will you be feeding the clock-gated output into? If it's a pin-pad, then you should read the DDR pad buffers in the device specifications and infer the specific primitive to be able to drive a DDR signal.
If you are keeping this signal within the chip then this is a very bizarre request. If I needed to generate that waveform, I would probably use a PLL to generate a phase-locked clock at twice the base frequency and put the gated data into that domain, with a toggle to apply the mast, so that the tooling will be able to properly analyse the clock crossings and the resulting data path is still effectively transitioning on a single edge.
The answers above to infer a register with a combinatorial multiplexer forced on the output is interesting, but whatever you feed this into will have to deal with awkward setup/hold conditions, and if on-chip, would only be sampling one edge anyway, so this is kind of redundant.