【发布时间】:2018-06-08 08:44:15
【问题描述】:
我现在正在尝试使用 VHDL 语言编写有限状态机 (FSM)(实际上我是 VHDL 的新手)。我想要实现的是,每当机器在 S11 中时,STint 会随着 CLK2 分别减小(所以我可以控制下降的速度有多快)。然而,S0 直到 S10 都由 CLK1 控制。
这是我的代码:
begin
process(state,DI,HI,QI,rst)
begin
case State is
when S0 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0'; STint <= 9;
if DI'EVENT and DI = '1' then Nextstate <= S4;
elsif HI'EVENT and HI = '1' then Nextstate <= S2;
elsif QI'EVENT and QI = '1' then Nextstate <= S1;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S0; end if;
when S1 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S5;
elsif HI'EVENT and HI = '1' then Nextstate <= S3;
elsif QI'EVENT and QI = '1' then Nextstate <= S2;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S1; end if;
when S2 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S6;
elsif HI'EVENT and HI = '1' then Nextstate <= S4;
elsif QI'EVENT and QI = '1' then Nextstate <= S3;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S2; end if;
when S3 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S7;
elsif HI'EVENT and HI = '1' then Nextstate <= S5;
elsif QI'EVENT and QI = '1' then Nextstate <= S4;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S3; end if;
when S4 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S8;
elsif HI'EVENT and HI = '1' then Nextstate <= S6;
elsif QI'EVENT and QI = '1' then Nextstate <= S5;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S4; end if;
when S5 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
if DI'EVENT and DI = '1' then Nextstate <= S9;
elsif HI'EVENT and HI = '1' then Nextstate <= S7;
elsif QI'EVENT and QI = '1' then Nextstate <= S6;
elsif rst'EVENT and rst = '1' then Nextstate <= S10;
else Nextstate <= S5; end if;
when S6 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '0';
Nextstate <= S11;
when S7 =>
DO <= '0'; HO <= '0'; QO <= '1'; ST <= '0';
QOint <= -1;
Nextstate <= S11;
when S8 =>
DO <= '0'; HO <= '1'; QO <= '0'; ST <= '0';
HOint <= HOint -1;
Nextstate <= S11;
when S9 =>
DO <= '0'; HO <= '1'; QO <= '1'; ST <= '0';
HOint <= HOint -1;
QOint <= QOint -1;
Nextstate <= S11;
when S10 =>
DOint <= 9; HOint <= 9; QOint <= 9; STint <= 9;
Nextstate <= S0;
when others => null;
end case;
end process;
process(CLK1)
begin
if CLK1'EVENT and CLK1 = '1' then
State <= Nextstate;
end if;
end process;
process(state,CLK2)
begin
case State is
when S11 =>
DO <= '0'; HO <= '0'; QO <= '0'; ST <= '1';
if CLK2'EVENT and CLK2 = '1' then STint <= STint -1;
elsif STint <= 0 then Nextstate <= S0; end if;
when others => null;
end case;
end process;
我尝试了很多替代方法,例如使用 CLK1 作为时钟来减少 STint,但效果不佳,因为另一个 int em>(s) 会一次又一次地减少。
进一步的信息,这个FSM实际上类似于自动售货机,除了在S11中,一个计时器将开始倒计时然后进入下一个状态,即S0。其他状态仅用于输入(例如货币)和输出(例如更改)。在 S11 中,只要计时器还在倒计时,ST LED 就会亮起。
有什么办法可以做到这一点?如果有人能指出我的代码为什么不起作用,我会非常高兴。似乎只要机器处于 S11 中,它就无法更改其状态。这就是我的代码在 TINA 中的样子:
非常感谢。祝你今天过得愉快!
PS:计时器显示在STcount输出
【问题讨论】:
-
首先,为了帮助我们帮助您,提供MCVE。然后是关于 VHDL 的两个提示:时钟进程在敏感度列表中应该只有 CLK(和潜在的异步 RST),在你的进程中也只写一个 clk 边缘检测。然后要使用 2 个不同的时钟,请阅读有关“时钟域交叉”的信息。
-
1/ 你的代码充满了时钟。删除你所有的
XX'EVENT and XX = '1',除了 XX 是你的主时钟。 2/ 每个输入信号都需要一个同步器电路。之后,您可以检查它是高还是低。 3/如果这应该是一个真实的电路添加开关去弹跳。 4/ 用 1K 的“有效”时钟替换 1K 时钟,从 2K 中除以二。 -
您不能驱动来自多个进程的信号。不要使用多个时钟:使用计时器/延迟计数器。
标签: vhdl state-machine fsm