如何在 vhdl 中重置序列识别自动机中的变量?

Posted

技术标签:

【中文标题】如何在 vhdl 中重置序列识别自动机中的变量?【英文标题】:How to reset variables in a sequence recognition automaton in vhdl? 【发布时间】:2018-05-18 11:42:42 【问题描述】:

我是 vhdl 的初学者。我创建了一个 000010 序列的识别器自动机 (Moore) 来访问电梯。识别全序列后,在X1状态电梯门打开,两个LED灯亮,X2和X3在5秒后门关闭,10秒后,电梯到达所需楼层。 用Modelsim模拟一切,没有错误。

我的问题是想要重置所有变量(然后返回到初始状态 X0)以防万一,例如,您处于任何状态。例如,在 X1 中,变量“esito”、led1 和 led2 应该返回 0。

由于无法在第一个过程中重置这些变量(重置条件 = 1),因为我会遇到错误“无法解析网络的多个常量驱动程序”(两者都使用相同的变量进程),我想问一下我在下面的代码中采用的解决方案是否正确(在对插入的序列执行控制之前重置X0中的变量)。

我希望我已经清楚了,你可以帮助我。

这是代码:

library IEEE;
use IEEE.std_logic_1164.all;

entity riconoscitore is
port(   
    simbolo:inout  std_logic_vector(5 downto 0);
    clock,esito,reset:inout std_logic;
    led1,led2:out std_logic
    );
end riconoscitore;

architecture myriconosc of riconoscitore is
type state_values is 
(X0,X1,X2,X3);
signal current_st,next_st:state_values;
signal timer:std_logic;
begin

process(clock,reset) 
begin
if(reset='1') then
  current_st<=X0;
elsif(rising_edge(clock))then
current_st<=next_st;
end if;
end process;

process(current_st,simbolo,timer,reset)
begin
next_st<=X0;

case current_st is

when X0 =>
esito<='0';
led1<='0';
led2<='0';
reset<='0';
timer<='0';
simbolo<=('U','U','U','U','U','U');
if(simbolo="000010")then
  next_st<=X1; 
else
  next_st<=X0;
end if;

when X1 =>
esito<='1';
led1<='1';
led2<='1';
timer<= transport '1' after 5 sec;
next_st<=X2;

when X2=>
led1<='0';
if(timer='1') then
  next_st<=X3;
  reset<= transport '1' after 10 sec;
else next_st<=X2;
end if;

when X3=>
if (reset='1') then
  next_st<=X0;
  esito<='U';
  reset<='U';
  timer<='U';
  simbolo<=('U','U','U','U','U','U');
  led2<='0';
else 
  next_st<=X3;
end if;

end case;
end process;

end myriconosc;

【问题讨论】:

【参考方案1】:

您在顺序过程中的重置是异步的

process(clock,reset) 
begin
if(reset='1') then
  current_st<=X0;
elsif(rising_edge(clock))then
current_st<=next_st;
end if;
end process;

只有在发生某些异常时才使用异步复位将触发器置于已知状态,目前最常见的是上电。永远不要将异步复位用于任何其他目的。永远不要将异步复位作为电路正常操作的一部分。

例如,假设您有一个带有两个按钮的秒表:START/STOPRESET。因此,在比赛开始时,计时员会按 START/STOP 开始计时,而在比赛结束时,计时员会再次按 START/STOP停止计时。记录时间后,计时员将按下 RESET 将手表归零,为下一场比赛做好准备。假设一段时间后,电池耗尽。计时员会装上新电池,然后会发现秒表已经重置,为下一场比赛做好了准备。您可以使用异步重置来重置第二个(新电池)外壳中的手表;你永远不应该在第一种情况下使用一个,因为这不是一个例外 - 为下一场比赛重置为零是秒表作为其正常操作的一部分所做的事情。

因此,异步复位应该只连接到顺序进程(如上面的那个),并且应该用于将触发器无条件置于已知状态(即复位状态不应依赖于任何其他信号)。如果您不遵循这些规则,您将不会有同步设计,并且会给自己带来问题。

因此,在您的设计中,您应该使用异步复位将触发器置于已知状态 - X0(正如您所做的那样) - 并且处于该状态时 FSM 的状态输出就是该状态他们有重置。就是这样。如果您不喜欢X0 状态下的输出状态,那么您需要更改它或者您需要将触发器重置为不同的状态。

【讨论】:

【参考方案2】:

一个 您遇到问题的原因是您没有遵循 HDL 的编码规则。

您有两个部分:寄存器/时钟部分和组合部分。

在组合部分,您必须为每个状态下的每个信号和变量赋值。如果您忘记创建闩锁。应该避免闩锁,当然如果你只是开始编程的话。 这些锁存器保持其价值,这就是导致您的问题的原因。

有两种解决方案:

    为每个状态下的每个信号和变量分配一个值。 使用默认值

两个 还有一个我以前没有见过的错误: 您的process(clock,reset) 取决于重置。在该过程中,您设置状态。

然后在下一个过程中您使用状态来设置重置。你刚刚创建了一个最讨厌的循环状态机! 从第二个过程中删除所有重置的使用。重置应该只控制你的第一个进程!

【讨论】:

啊,是的,我来自 Verilog,我们只有信号,我经常将信号称为变量。我会更新文字。

以上是关于如何在 vhdl 中重置序列识别自动机中的变量?的主要内容,如果未能解决你的问题,请参考以下文章

重置自动递增序列 pl-sql

如何在 VHDL 中使用“函数”从同一计算中返回多个变量?

如何在 Keras 中重置状态变量?

AS3:如何从影片剪辑内部检查和重置主时间轴上的变量

设计中的自定义变量重置密码说明?

VHDL触发器复位不同于0