在VHDL上实现状态机时,我想知道如何设置输出/当前状态的初始条件。我在here上阅读了其中一个问题。
其中一个答案说我们在案例结构之前进行了初始化:
process(currentstate, a)
begin
b <= '1';
c <= '1';
case currentstate is
when s1 =>
if (a = '1') then
c <= '0';
end if;
nextstate <= s2;
但是,当我们进入流程时,这不会让我们自动设置b<='1'
和c<='1'
吗?因此,如果我们处于一个说A的状态,并且每当我们进入流程时我们都处于移动到B的条件,这直接使b<='1'
和c<='1'
不正确?
或者它实际上只是在我们启动程序后运行,然后在案例结构中受限制?
同时检查this link。
在他们的FSM实现中,他们没有指定初始状态编译器或FPGA如何确定启动状态?
答案 0 :(得分:3)
您正在查看的行未执行初始化。
b <= '1';
c <= '1';
请记住,VHDL是一种硬件描述语言,而不是编程语言。这两个分配的作用是为这些信号设置默认分配,除非此过程中的其他内容与这些分配相矛盾。您可以在一个进程中多次分配相同的信号,并且最后发生的任何分配都将优先考虑。这样可以节省编写类似的代码:
case State is
when s1 =>
a <= '0';
b <= '1';
c <= '1';
when s2 =>
a <= '1';
b <= '0';
c <= '1';
when s2 =>
a <= '1';
b <= '1';
c <= '0';
end case;
最终可能会在很多状态下具有相同的重复性并且容易出错,因此默认分配可以真正整理它:
a <= '1';
b <= '1';
c <= '1';
case State is
when s1 =>
a <= '0';
when s2 =>
b <= '0';
when s2 =>
c <= '0';
end case;
相同的模式适用于if
语句,您不希望覆盖每个逻辑分支中的每个输出信号。
如果您想要初始状态,根据场景,有两种方法可能适用。在这里,您可以在启动时断言reset
以设置初始状态。请注意,case语句位于一个时钟进程内:
process (clk)
begin
if (rising_edge(clk)) then
if (reset = '1') then
State <= s1;
else
case State is
when s1 =>
State <= s2;
when s2 =>
State <= s1;
end case;
end if;
end if;
end process;
另一个选项是使用初始值定义状态信号:
signal State : state_type := s1;
我不会深入探讨使用初始值的优缺点,因为现有的问题可以探索这个问题。