VHDL中信号的分块分配

VHDL中信号的分块分配,vhdl,digital,Vhdl,Digital,我正在用VHDL做一个FSM。当valid=1时,最简单的方法是将stateA更改为stateB 令人困惑的部分是由蓝色矩形选择的上升边。有效时='1'。在第一个上升沿,状态将被计算为B,但直到下一个上升沿才生效,但在第一个上升沿生效时发生的情况 因为从A到B的状态变化应该会影响下一个周期设计中的其他部件(并行过程)。从波形中,如果有效='1'正好在CLK_1之前 在CLK|U 1时,所有其他过程应看到状态=A |波形正确 输出 状态=A enteredlastcycle=0 此时,CLK_

我正在用VHDL做一个FSM。当valid=1时,最简单的方法是将stateA更改为stateB

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

因为从A到B的状态变化应该会影响下一个周期设计中的其他部件(并行过程)。从波形中,如果有效='1'正好在CLK_1之前

在CLK|U 1时,所有其他过程应看到状态=A |波形正确 输出

  • 状态=A
  • enteredlastcycle=0
此时,CLK_2所有进程开始看到状态=B。另一个并行 进程检查状态是否为B,然后将输入的\u STATEB\u LASTCYCLE驱动到 be 1波形正确输出

  • 状态=B
  • enteredlastcycle=0
然后在CLK_3,波形正确输出

  • 状态=B
  • enteredlastcycle=1
我误解了什么吗?
IEEE库;
使用IEEE.std_logic_1164.all;
使用IEEE.numeric_std.all;
使用work.KDlib.all;
实体最近点是
通用(数组宽度:整数=8);
港口(
clk:标准逻辑中;
复位:在标准逻辑中;
输入点:在kdvector中;
有效:在标准逻辑中;
完成:缓冲区标准逻辑
);
最接近终点;
最近点的建筑表现是
信号状态:双状态型;
上一周期输入的信号状态:标准逻辑;
开始
过程(clk)
开始
如果(重置='1'),则
elsif(上升沿(clk))然后
案例状态为
当stateA=>
如果(有效='1'),则
陈述
当其他人=>
终例;
如果结束;
结束过程;
过程(clk)
开始
如果(重置='1'),则
elsif(clk='1'),然后
案例状态为
当stateA=>
当stateB=>
上一个周期进入的状态
终例;
如果结束;
结束过程;
端行为;

VHDL没有阻塞/非阻塞分配的概念。有信号和变量,它们的分配方式不同


在您的例子中,您需要记住模拟是在一系列增量循环上运行的。1 delta是一个无限小的时间空间,但它们是按顺序发生的。信号分配直到增量结束才生效,因此在时钟上升沿之后的增量周期中,状态=B。第二个进程仅对时钟敏感,因此在时钟再次上升之前,它无法更新上次循环输入的状态。

我将通过数字电路棱镜向您解释。这是一种在开发VHDL时必须牢记的思维方式

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

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

SEQ:过程(时钟、rst)
开始
如果rst='1',则

当前_状态只是为了增加更多的混乱,原始post中的重置作为一个时钟启用(当重置为“1”时信号不能更改)。事实上,但我认为作者在发布代码之前删除了一些代码以简化,因此我认为如果重置为“1”,那么这其中可能有一些内容。他会告诉我们:)是的,在第一个clk时状态应等于B,但这不应影响同一周期中的其他并行进程。如果您查看波形,您可以看到A到B的事务发生在第一个周期中,但它也影响了其他进程,而这不应发生(我不需要关心模拟中的设置/保持时间)我认为这个小故障是因为我在测试台上使用的异步有效信号。当我使用同步有效信号时,它按预期工作。另外,你的代码工作正常。非常感谢。你能推荐一本参考书/教科书来学习更复杂的设计吗?对不起,我不知道关于这个主题的书籍:(是的,确切地说,使用信号应该始终是一个非阻塞分配,因此在一个周期中从a到B的状态变化应该影响下一个周期中的其他进程。这里发生的情况是,它影响了与阻塞分配相同的事务周期中的其他进程。否,它没有。状态变化,然后其他进程改变s。)下一个循环中的信号。波形显示了代码的精确行为。您可能会发现这很有用。我认为您缺少的是,即使clk='1',第二个进程也看不到新的“状态”值,因为它直到下一个clk事件才被唤醒。有趣的是,如果添加“状态”,会发生什么到它的敏感度列表?回答这个问题,然后尝试。。。
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;
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;