我有这个信号,应该为零,直到另一个信号Start = 0.我怎么能做到这一点?以下是相关代码:
din<=0;
wait until falling_edge(start);
for i in 0 to 63 loop
wait until clk = '1' and clk'event;
if i = 0 then
Start <= '1','0' after clk_period;
end if;
if (i < 24) then
din <= 255;
elsif (i > 40) then
din <= 255;
else
din <= 0;
end if;
end loop;
wait;
我想我可以让din = 0直到开始的下降沿,但它会在开始的上升沿停止。我想在start = 0时开始读取din值。在那之前din = 0。
这是一张照片:
编辑:实际上我是从正确的信号值开始的,但是dout值总是有一个不必要的中间值。在这种情况下,它的78450.我知道这与testbench代码有关,但我不能让它只是在正确的时间计算正确的值。可以对下面的代码进行哪些更改以消除中间值?
din<=0;
for i in 0 to 63 loop
wait until clk = '1' and clk'event;
if i = 0 then
Start <= '1','0' after clk_period;
elsif (i < 24) then
din <= 255;
elsif (i > 40) then
din <= 255;
else
din <= 0;
end if;
end loop;
答案 0 :(得分:4)
首先,我假设(并希望)您正在编写测试平台。如果没有,您应该避免使用等待语句,因为它们在综合工具中的支持非常有限。
即使在测试平台中,最好只使用基于时间的等待或后续语句来生成时钟,并使所有其他信号依赖于事件(例如rising_edge(clk)
)。这避免了在delta周期0期间多个信号随时钟变化的问题。
考虑典型寄存器的以下代码:
process(clk) begin
if(rising_edge(clk)) then
a <= b;
end if;
end process;
并假设clk
和b
在测试平台中生成如下:
clk <= not clock after 1 ns;
process begin
b <= '1', '0' after 10 ns;
wait;
end process;
clk
变为'1',b
变为'1'。clk
更改后运行,a
将更改为“1”。clk
变为'0'。clk
更改后运行,但没有任何反应,因为rising_edge(clk)
为false。clk
变为'1',b
变为'0'。请注意,clk
和b
会在相同的增量周期中发生变化。a
变为'0'!就结果而言,这意味着b
在时钟上升之前发生变化!即使在这个简单的系统中这种行为是可以理解的,它也可能导致一些非常难以找到的模拟错误。因此,最好将所有信号基于适当的时钟。
process begin
-- Initialize b to 1.
b <= '1';
-- Wait for 5 cycles.
for i in 1 to 5 loop
wait for rising_edge(clk);
end loop;
-- Set b to 0.
b <= '0';
-- Done.
wait;
end process;
这可以避免意外行为,因为所有信号将在相关时钟之后至少改变一个增量周期,这意味着在所有过程中都会保持因果关系。
答案 1 :(得分:0)
I have this signal that should be zero until another signal Start = 0. How can I accomplish this?
也许您可以使用握手信号并将其放入流程的敏感列表中。它的行为就像一个复位信号。
process (handshake_s, ...)
begin
if (handshake_s = '1') then -- failing edge of start
din <= 0;
else
-- do something
end if;
end process;
使用其他进程更新 handshake_s 。
process (start, ...)
begin
if failing_edge(start) then
handshake_s <= '1', '0' after 10 ns; -- produce a pulse
end if;
-- do something
end process;
你介意在这里发布所有代码,以便我们更好地理解波形吗?
答案 2 :(得分:0)
Testbench或RTL代码?
对于测试平台,您的编码风格基本上没问题,但是,您的信号Start有问题,并且在时钟的上升沿期间永远不会为'1'。它在时钟的上升沿之后变为“1”,并且将在时钟之前与时钟或1个增量循环同时返回“0”(取决于您的时钟设置)。无论哪种方式,在rising_edge时钟上运行的任何内容(例如您的设计)都不会将其视为“1”。
避免这种情况的一种简单方法是在所有进入DUT(被测设备)的测试平台输出上使用标称延迟(tperiod_Clk的25%)。脉冲的模式如下。
wait until clk = '1' ; -- I recommend using rising_edge(Clk) for readability
Start <= '1' after tpd, '0' after tpd + tperiod_clk ;
或者,您可以通过不使用波形分配来避免此问题。如下。在这种情况下,您不需要tpd,但是,如果它确实是一个测试平台,我建议使用它。
wait until clk = '1' ;
if i = 0 then
Start <= '1' after tpd ;
else
Start <= '0' after tpd ;
end if ;
对于 RTL代码,您需要探索不同的方法。非常简短的一种方法是如下。注意不要使用任何延迟,波形分配或循环。
-- Counter to count from 0 to 63. Use "+ 1". Use "mod 64" if using type integer.
-- Start logic = decoder (can be coded separately)
-- Din Logic = decoder (can be coded separately)