VHDL 中 SIGNALS 的阻塞分配

Blocking Assignments on SIGNALS in VHDL

我正在用 VHDL 制作 FSM。当 valid = 1 从 stateA 变为 stateB 时,最简单的可能。

令人困惑的部分是蓝色矩形选择的上升沿。当有效 = '1' 时。在第一个上升沿,状态将被计算为 B,但直到下一个上升沿才会生效,但在第一个上升沿生效的情况发生了什么。

因为从A到B的状态变化应该会影响到NEXT循环中设计中的其他部分(并行过程)。从波形来看,If valid = '1' 就在 CLK_1.

之前

At, CLK_1 all other processes should see state = A | waveform correct output

At, CLK_2 all processes start seeing state = B. another parallel process checks if state = B then it drives ENTERED_STATEB_LASTCYCLE to be 1 waveform correct output

Then at CLK_3, waveform correct output

我是不是理解错了什么?

Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.KDlib.all;

entity nearestPoint is
generic ( ARRAY_WIDTH : integer := 8);
    port (
        clk: in std_logic;
        reset: in std_logic;
        inpoint: in kdvector;
        valid: in std_logic;
        finished: buffer std_logic
        );

end nearestPoint;

architecture behave of nearestPoint is
signal state: two_state_type;
signal stateB_entered_lastCycle: std_logic;
begin

process ( clk )
begin
if ( reset = '1' ) then
elsif ( rising_edge(clk) ) then
    case state is
        when stateA =>
            if ( valid = '1' ) then
                state <= stateB;
            end if;
        when stateB =>
        when others =>
    end case;
end if;
end process;


process(clk)
begin
if ( reset = '1' ) then
elsif ( clk = '1' ) then
    case state is
        when stateA =>
        when stateB =>
            stateB_entered_lastCycle <= '1';
        when others =>
    end case;
end if;
end process;

end behave;

VHDL 没有 blocking/non-blocking 赋值的概念。有信号和变量,它们的赋值不同。

对于您的情况,您需要记住模拟是在一系列增量循环上运行的。 1 delta 是无限小的 space 时间,但它们是按顺序发生的。信号分配直到delta结束才生效,因此在时钟上升沿之后的delta周期中state = B。第二个进程只对时钟敏感,所以它不能更新stateB_entered_lastcycle直到时钟再次上升。

我通过数字电路棱镜给大家讲解一下。这是开发VHDL时必须牢记的一种思维方式。

你的有效在时钟边沿之前为1。你在模拟中,所以你可以想象你所有的计算都是即时的。在你的触发器的输入端,你的状态的新值已经计算出来了。

我习惯于只使用一个顺序过程和一个或多个组合过程进行编码。也许你会更好地理解这段代码与你的代码具有相同的功能(有点简化):

SEQ : process(clk, rst)
begin

  if rst = '1' then
    current_state <= '0';
  elsif rising_edge(clk) then
    current_state <= next_state;
  end if;

end process SEQ;

此代码对应的电路:

COMB : process(current_state, valid)
begin

  next_state <= current_state; -- Default value to ensure that next_state will always be affected

  if current_state = '0' and valid = '1' then
    next_state <= '1';
  end if;

end process COMB;

此代码对应的电路:

如果考虑到valid变化时next_state是瞬间刷新的,current_state(代码中的 state)在下一个时钟上升沿变高。

希望您能理解,如果您需要更精确的信息,请不要犹豫,我可以编辑我的 post 或在评论中回答。

重要说明:如果您在顺序过程中有异步重置,它必须在敏感列表中。