在 VHDL 中实现 FSM
只是想知道如果我在 VHDL 中实现有限状态机,是否需要说明每种可能状态下的所有输出?即使我知道某些输出不会从一种状态更改为另一种状态,并且我知道状态的顺序也将采用相同的顺序?
例如,在这个(强制)示例中:
entity test is
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic;
);
end test;
architecture Behavioral of test is
type executionStage is (s1,s2,s3);
signal currentstate, nextstate: executionStage;
begin
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
else
currentstate <= currentstate;
end if;
end process;
process(currentstate)
begin
case currentstate is
when s1 =>
if (a = '1') then
b <= '1';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s2;
when s2 =>
-- b doesnt change state from s1 to here, do I need to define what it is here?
if (a = '1') then
b <= '1';
c <= '1';
else
b <= '1';
c <= '0';
end if;
nextstate <= s3;
when s3 =>
if (a = '1') then
b <= '0';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s1;
end case;
end process;
end Behavioral;
根据我的理解,如果我不这样做,那么会创建锁存器?
在像这个例子中这并不是什么大问题,但是如果我有一台具有超过 10 个输出和超过 10 个状态的机器,那么我的 VHDL 文件开始看起来非常混乱,我确信复制和粘贴文件一定是不好的做法。同样的事情一遍又一遍。有更好的方法吗?
编辑:我可以为输出定义“默认”状态吗? IE 在所有进程之外将 b 设置为 1,然后只在为 0 的 case 语句中定义它是什么?那行得通吗?
Just wondering if I'm implementing a finite state machine in VHDL whether or not I need to state what all of the outputs are in every possible state? Even if I know that some outputs won't change from one state to the other and I know that the order of the states will also be in the same order?
For example, in this (forced) example:
entity test is
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic;
);
end test;
architecture Behavioral of test is
type executionStage is (s1,s2,s3);
signal currentstate, nextstate: executionStage;
begin
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
else
currentstate <= currentstate;
end if;
end process;
process(currentstate)
begin
case currentstate is
when s1 =>
if (a = '1') then
b <= '1';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s2;
when s2 =>
-- b doesnt change state from s1 to here, do I need to define what it is here?
if (a = '1') then
b <= '1';
c <= '1';
else
b <= '1';
c <= '0';
end if;
nextstate <= s3;
when s3 =>
if (a = '1') then
b <= '0';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s1;
end case;
end process;
end Behavioral;
From my understanding if I don't do this then latches are created?
It's not a big deal in something like that example but if I have a machine with more than 10 outputs and more than 10 states then my VHDL files start to look incredibly messy and I'm sure it must be bad practice to copy and paste the same thing over and over. Is there a better way of doing this?
edit: Can I define a 'default' state for an ouput? IE set b to be 1 outside of all the processes and then only define what it is in the case statements where it is 0? Would that work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的,如果您仅驱动旨在在流程的某些分支中进行组合的信号,您将推断出锁存器。
但是,您只需在
case
语句之前(但在同一进程内)为其分配一个值即可定义信号的“默认”状态。例如:Yes, you will infer latches if you only drive signals intended to be combinatorial in some branches of the process.
However, you can define a 'default' state for the signal simply by assigning a value to it before the
case
statement (but within the same process). For example:示例代码的三个问题:
端口列表中的最后一个端口不应有分号:
在注册过程中,不应有“else”语句。虽然这可能会被工具接受,但它会让您的 VHDL 设计人员同事感到困惑。
在您的组合逻辑中,敏感度列表应包含您读取的所有信号:
process(a, currentstate)
。在这种特殊情况下(再次),事情可能会顺利进行,但如果您的敏感度列表不正确,您必然会推断出锁存器或导致其他问题。至于您的问题:
Three problems with your example code:
The last port in your port list should not have a semicolon:
In your register process, you should not have an "else" statement. While this will probably be accepted by the tools, it will confuse your fellow-VHDL designers.
In your combinational logic, the sensitivity list should contain all signals that you read:
process(a, currentstate)
. In this particular case (again) things will probably work out fine, but you are bound to infer latches or cause other problems if your sensitivity list is not correct.As for your question:
只是对菲利普的回应的一个注释(不能直接评论它?)..
我确实更喜欢以两种进程风格编写状态机。它非常清楚地表明您期望在哪里推断触发器,在哪里不期望推断触发器。这也有点类似于
描述硬件 - 例如,想象一下构建一个具有板级逻辑的状态机。
注册的设备匹配state<=next_state进程,
case 语句映射到状态寄存器前面的 and/or 数组。
话虽如此,我通常使用一个进程状态机来执行小型简单任务,并转移到两台进程状态机来执行较大的任务。
我什至有时会使用第三个过程将状态输出组织到不同的“任务”组中......但不经常。一个非常大的状态机往往会告诉我架构需要工作。
Just a note to Philippe's response (can't comment on it directly?)..
I do prefer to write state machines in the two process style. It makes it very clear where you expect inferred flipflops and where you don't. It's also a bit more along the lines of
describing the hardware - imagine building a state machine with board level logic for example.
The registered device matches the state <= next_state process,
and the case statement maps to the and/or array in front of the state register..
Having said that, I typically use one process state machines for small simple tasks, and move over to two process machines for bigger ones.
I will even sometimes use a third process for organizing state outputs into different "task" groups.. but not often. A really large state machine tends to tell me the architecture needs work..
您好,
上述过程有问题,但不是由于敏感列表所致。只为顺序进程声明 clk 是可以的。模拟和综合工具都不会出现问题。毕竟,clk 是代码中变化/转换最快的信号。
但是,您应该使用(最好)异步重置。当然,现在的供应商表示,对于 FPGA 设计来说,复位甚至是不必要的;它们发生在启动时。或者他们建议同步重置。
尽管如此,异步复位对于基于板的环境仍然很有价值。
简而言之:在您的设计中添加重置并正确修复其行为。
亲切的问候
尼古拉斯·卡瓦迪亚斯
Hi
the above process is problematic but not due to the sensitivity list. It is ok to only declare clk for sequential process. Both simulation and synthesis tools won't have problems with it. clk is the fastest changing/transitioning signal after all in your code.
However, you should use an (preferrably) asynchronous reset. Of course, vendors nowadays say that for FPGA design, resets are not even necessary; they happen at boot time. Or they propose a synchronous reset.
Still, an asynchronous reset is valuable for a board-based environment.
In short: add a reset to your design and fix its behavior properly.
Kind regards
Nikolaos Kavvadias
以下VHDL代码是边缘敏感状态机。
本例中的边缘敏感过程将使“out1”和“out2”与“clk”同相。
这是测试台
The following VHDL code is edge sensitive state machine.
The edge sensitive process in this example will make both “out1” and “out2” in phase with “clk”.
here is the test bench
以下VHDL代码是电平敏感状态机。
本例中的电平敏感过程将使“out1”与“clk”异相,“out2”与“clk”同相。
这是测试台
The following VHDL code is level sensitive state machine.
The level sensitive process in this example will make “out1” out of phase with “clk” and “out2” in phase with “clk”.
here is the test bench