这种 VHDL 状态机设计方法的缺点是什么?
What is the disadvantage of this approach to VHDL state machine design?
状态机的一种常用样式是在一个非常简单的时钟进程中更改状态,在同一个进程或另一个进程中,一个组合部分定义了到下一个状态的转换:(这里我使用同步重置,因为我有一个主重置同步器)
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 逻辑的朋友(不是 Sophie!我想她用的是铅笔和纸......)他告诉我他的规则是永远不要用时钟以外的任何东西创建进程敏感度列表。
此致
杰夫
我不认为你可以规定要做什么。与许多编码风格一样,有些人更喜欢其中一种。 绝对没有好或坏风格。
对于小型简单状态机,我使用第一种方法。
对于大型、复杂的状态机,我更喜欢第二种方法。
我喜欢第二种方法的技巧:
- 例如在状态 X 中,您需要一个寄存器 R 来获得值 A。在第一种方法中,您必须追踪到 X 的每个状态转换并添加:
R <= A;
。另外,如果你改变了你的状态机,你不应该忘记这一点。
第二种方法通常有一个状态和 next_state 变量。那么你可以这样写:
if (next_state==X) R <= A;
。您现在可以尝试使用您的代码,并且知道当您到达状态 X 时,R 将被赋予值 A。
Break out:假设需要有一个'emergency stop'或者用户否定了'enable'位,整个FSM需要停止。在方法 1 中,您必须启动 every 状态条件:if (stop_everything) state<=IDLE else...
在方法二中,您注册的部分变为:
if (stop_everything)
state <= IDLE;
else
state <= next_state;
我曾使用过来自大型 CPU 核心供应商的 IP(您可以猜出他们的名字)。在他们的代码中,即使是最简单的代码,您也只能看到第二种方法。如果你为他们工作,我认为这是一种强制性的编码风格。
状态机的一种常用样式是在一个非常简单的时钟进程中更改状态,在同一个进程或另一个进程中,一个组合部分定义了到下一个状态的转换:(这里我使用同步重置,因为我有一个主重置同步器)
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 逻辑的朋友(不是 Sophie!我想她用的是铅笔和纸......)他告诉我他的规则是永远不要用时钟以外的任何东西创建进程敏感度列表。
此致 杰夫
我不认为你可以规定要做什么。与许多编码风格一样,有些人更喜欢其中一种。 绝对没有好或坏风格。
对于小型简单状态机,我使用第一种方法。
对于大型、复杂的状态机,我更喜欢第二种方法。
我喜欢第二种方法的技巧:
- 例如在状态 X 中,您需要一个寄存器 R 来获得值 A。在第一种方法中,您必须追踪到 X 的每个状态转换并添加:
R <= A;
。另外,如果你改变了你的状态机,你不应该忘记这一点。
第二种方法通常有一个状态和 next_state 变量。那么你可以这样写:
if (next_state==X) R <= A;
。您现在可以尝试使用您的代码,并且知道当您到达状态 X 时,R 将被赋予值 A。 Break out:假设需要有一个'emergency stop'或者用户否定了'enable'位,整个FSM需要停止。在方法 1 中,您必须启动 every 状态条件:
if (stop_everything) state<=IDLE else...
在方法二中,您注册的部分变为:if (stop_everything) state <= IDLE; else state <= next_state;
我曾使用过来自大型 CPU 核心供应商的 IP(您可以猜出他们的名字)。在他们的代码中,即使是最简单的代码,您也只能看到第二种方法。如果你为他们工作,我认为这是一种强制性的编码风格。