状态机常用的样式是在一个非常简单的时钟进程中改变状态,在同一个进程或另一个进程中,组合部分定义转换到下一个状态:(这里我使用同步复位,因为我有一个主复位同步器)
process( aclk, state, next_state, bob, alice )
begin
if rising_edge( aclk ) then
if resetn = '0' then
state <= IDLE;
else
state <= next_state;
end if;
end if;
next_state <= state;
case state is
when IDLE =>
if bob = alice then
next_state <= ANOTHER_STATE;
......等等。有些人喜欢将组合部分放在另一个过程中,风格各不相同。我把机器和各种东西分开,例如控制状态转换的计数器分成小的进程,但我知道有些人不喜欢这种风格。
将所有内容保存在同步块中是否存在严重问题,如:
process( aclk )
begin
if rising_edge( aclk ) then
if resetn = '0' then
state <= IDLE;
else
case state is
when IDLE =>
if bob = alice then
state <= ANOTHER_STATE;
end if;
when others =>
null;
end case;
end if;
end if;
end process;
我问,因为当我开始编程时(非常糟糕,作为一个软件人!)我曾经使用第二种方法,我想知道是否应该重写代码。
我有一个朋友写了一些ARM逻辑,(不是索菲!我认为她用的是铅笔和纸......)谁告诉我他的规则永远不会用敏感时钟以外的任何东西创建流程列表。
祝你好运 杰夫
答案 0 :(得分:0)
我不认为你可以规定要做什么。与许多编码风格一样,有些人更喜欢另一种。 肯定没有好或坏风格。
对于小型简单状态机,我使用第一种方法。
对于大型,复杂的状态机,我更喜欢第二种方法。
技巧我喜欢第二种方法:
R <= A;
。此外,如果你改变你的状态机,你不应该忘记这一点
第二种方法通常有一个state和next_state变量。然后你可以写:if (next_state==X) R <= A;
。您现在可以使用您的代码和知道当您到达状态X时,R将被赋值为A. 爆发:假设您需要紧急停止&#39;或者用户否定&#39;启用&#39;比特和整个FSM需要停止。在方法1中,您必须使用以下符号启动每个状态条件:if (stop_everything) state<=IDLE else...
在方法二中,您注册的部分变为:
if (stop_everything)
state <= IDLE;
else
state <= next_state;
我使用过大CPU核心供应商的IP(你可以猜出他们的名字)。在他们的代码中,即使对于最简单的代码,您也只能看到第二种方法。我认为如果你为他们工作,这是一种强制性的编码风格。