VHDL:有限状态机中的默认值

VHDL:有限状态机中的默认值,vhdl,xilinx-ise,Vhdl,Xilinx Ise,我正在尝试制作一个有限状态机,它根据串行输入切换状态。我需要一些关于我的代码是如何执行的解释。我在一本教科书中读到,在我标记“默认值”的过程中,我应该将默认值放在哪里。然而,每当我切换状态时,我的信号似乎都具有这些值。例如,我将idle旁边的state_设置为默认值。这样做会导致FSM无缘无故地继续从其他状态跳转到空闲状态 我的另一个问题是澄清如何执行FSM的整个过程。当我从一种状态移动到另一种状态时,是否应该执行case语句(标记为默认值的部分)之前的部分?还是只有当我从某个稍后的状态移回空闲

我正在尝试制作一个有限状态机,它根据串行输入切换状态。我需要一些关于我的代码是如何执行的解释。我在一本教科书中读到,在我标记“默认值”的过程中,我应该将默认值放在哪里。然而,每当我切换状态时,我的信号似乎都具有这些值。例如,我将idle旁边的state_设置为默认值。这样做会导致FSM无缘无故地继续从其他状态跳转到空闲状态

我的另一个问题是澄清如何执行FSM的整个过程。当我从一种状态移动到另一种状态时,是否应该执行case语句(标记为默认值的部分)之前的部分?还是只有当我从某个稍后的状态移回空闲状态时才执行?默认值部分应该在什么时候执行

我的代码如下所示。请参阅“下一状态逻辑”部分

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity delay_incrementor is
     generic ( delay_ports : natural := 3;
               width_ports : natural := 3
                );
    Port ( clk,reset: in STD_LOGIC;
              update : in STD_LOGIC;
              in_data : in  STD_LOGIC_VECTOR (7 downto 0);
              led : out STD_LOGIC_VECTOR (2 downto 0);
              out_data : out  STD_LOGIC_VECTOR (7 downto 0);
              d_big,d_mini,d_opo : inout  STD_LOGIC_VECTOR (25 downto 0);
              w_big,w_mini,w_opo : inout STD_LOGIC_VECTOR (25 downto 0));
end delay_incrementor;

architecture fsm_arch of delay_incrementor is
    type state_type is (idle,channel,d_or_w,delay_channel,delay_channel_inc,width_channel,width_channel_inc);
    type delay_file_type is array (delay_ports-1 downto 0) of std_logic_vector (25 downto 0);
    type width_file_type is array(width_ports-1 downto 0) of std_logic_vector (25 downto 0);
    signal d_reg,d_next,d_succ: delay_file_type;
    signal w_reg,w_next,w_succ: width_file_type;
    signal state_reg,state_next: state_type;
    signal which_channel,which_channel_next: natural;
begin
--------------------------------------
--State Register
--------------------------------------
process(clk,reset)
begin
if reset='1' then
    state_reg <= idle;
    d_reg <= (others => (others => '0'));
    w_reg <= (others => (others => '0'));
    which_channel <= 0;
elsif (clk='1' and clk'event) then
    state_reg <= state_next;
    d_reg <= d_next;
    w_reg <= w_next;
    which_channel <= which_channel_next;
end if;
end process;
--------------------------------------
--Next-State Logic/Output Logic
--------------------------------------
process(state_reg,in_data,d_reg,w_reg,which_channel)
begin
    state_next <= idle; --DEFAULT VALUES
    d_succ <= d_reg;
    w_succ <= w_reg;
    which_channel_next <= 0;
    case state_reg is
        when idle =>
            if in_data = "01100011" then --"c"
                state_next <= channel;
                which_channel_next <= 0;
            end if;
        when channel =>
            if (48 <= unsigned(in_data)) and (unsigned(in_data)<= 57) then
                which_channel_next <= (to_integer(unsigned(in_data))-48);
                state_next <= d_or_w;
            elsif in_data = "00100011" then --"#"
                state_next <= idle;
                which_channel_next <= which_channel;
            end if;
        when d_or_w =>
            if in_data = "01100100" then --"d"
                state_next <= delay_channel;
            elsif in_data = "01110111" then --"w"
                state_next <= width_channel;
            elsif in_data = "00100011" then --"#"
                state_next <= idle;
            end if;
        when delay_channel =>
            if in_data = "01101001" then --"i"
                state_next <= delay_channel_inc;
            elsif in_data = "00100011" then --"#"
                state_next <= idle;
            end if;
        when delay_channel_inc =>
            if in_data = "01110101" then --"u"
                d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))+250);
            elsif in_data = "01100100" then --"d"
                d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))-250);
            else
                d_succ(which_channel) <= d_reg(which_channel);
            end if;
            if in_data = "00100011" then --"#"
                state_next <= idle;
            end if;
        when width_channel =>
            if in_data = "01101001" then --"i"
                state_next <= width_channel_inc;
            elsif in_data = "00100011" then --"#"
                state_next <= idle;
            end if;
        when width_channel_inc =>
            if in_data = "01110101" then --"u"
                w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))+250);
            elsif in_data = "01100100" then --"d"
                w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))-250);
            else
                w_succ(which_channel) <= w_reg(which_channel);
            end if;
            if in_data = "00100011" then --"#"
                state_next <= idle;
            end if;
    end case;
end process;
process(update,d_reg,w_reg,reset)
begin
if reset='1' then
    d_next <= (others => (others =>'0'));
    w_next <= (others => (others =>'0'));
elsif (update'event and update='1') then
    d_next <= d_succ;
    w_next <= w_succ;
else
    d_next <= d_reg;
    w_next <= w_reg;
end if;
end process;
--------------------------------------
--Output Logic
--------------------------------------
d_big <= d_reg(0);
d_mini <= d_reg(1);
d_opo <= d_reg(2);
w_big <= w_reg(0);
w_mini <= w_reg(1);
w_opo <= w_reg(2);
end fsm_arch;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.ALL;
实体延迟增量为
通用(延迟端口:自然:=3;
宽度\u端口:自然:=3
);
端口(时钟,复位:在标准逻辑中;
更新:标准逻辑;
in_数据:in-STD_逻辑_向量(7到0);
led:输出标准逻辑向量(2到0);
out_数据:out标准_逻辑_向量(7到0);
d_big,d_mini,d_opo:inout标准逻辑向量(25到0);
w_大,w_小,w_opo:inout标准逻辑向量(25到0);
结束延迟;
延迟增量的体系结构fsm
类型状态类型为(空闲、信道、d_或w、延迟信道、延迟信道、宽度信道、宽度信道);
类型delay_file_类型为std_逻辑_向量(25向下至0)的数组(delay_端口-1向下至0);
类型width_file_type是std_逻辑_向量(25向下到0)的数组(width_端口-1向下到0);
信号d_reg,d_next,d_succ:delay_file_type;
信号w_reg,w_next,w_succ:width_file_type;
信号状态\注册,状态\下一步:状态\类型;
信号哪个信道,哪个信道下一个:自然;
开始
--------------------------------------
--国家登记册
--------------------------------------
过程(时钟、复位)
开始
如果reset='1',则
州(注册号“0”);
w_reg(其他=>0');

当所列信号之一发生变化时,每次评估哪个通道过程。因此,该列表称为“敏感度列表”

有两种类型的流程:
-连续的(带有时钟信号)和
-组合的(只是简单的逻辑)

第一种类型只需要灵敏度列表中的时钟信号,后一种类型需要每个右手边信号,否则仿真将显示实际硬件以外的其他结果

因此,每次输入信号发生变化('event=true),都会从
begin
开始对过程进行评估<代码>结束进程

因此,关于默认部分,每个信号都会得到一个默认值,并且不可能用这种编码方式生成锁存。通常状态_next未设置为空闲。它被设置为state_reg

免费翻译:保持当前状态,直到另行通知

您的代码:

...
elsif (update'event and update='1') then
  d_next <= d_succ;
  w_next <= w_succ;
else
  d_next <= d_reg;
  w_next <= w_reg;
end if;
。。。
elsif(update'event and update='1'),然后

d_next每次当所列信号之一发生变化时,都会对过程进行评估。因此,该列表称为“敏感度列表”

有两种类型的流程:
-连续的(带有时钟信号)和
-组合的(只是简单的逻辑)

第一种类型只需要灵敏度列表中的时钟信号,后一种类型需要每个右手边信号,否则仿真将显示实际硬件以外的其他结果

因此,每次输入信号发生变化('event=true),都会从
begin
开始对过程进行评估<代码>结束进程

因此,关于默认部分,每个信号都会得到一个默认值,并且不可能用这种编码方式生成锁存。通常状态_next未设置为空闲。它被设置为state_reg

免费翻译:保持当前状态,直到另行通知

您的代码:

...
elsif (update'event and update='1') then
  d_next <= d_succ;
  w_next <= w_succ;
else
  d_next <= d_reg;
  w_next <= w_reg;
end if;
。。。
elsif(update'event and update='1'),然后

d_next每次当所列信号之一发生变化时,都会对过程进行评估。因此,该列表称为“敏感度列表”

有两种类型的流程:
-连续的(带有时钟信号)和
-组合的(只是简单的逻辑)

第一种类型只需要灵敏度列表中的时钟信号,后一种类型需要每个右手边信号,否则仿真将显示实际硬件以外的其他结果

因此,每次输入信号发生变化('event=true),都会从
begin
开始对过程进行评估<代码>结束进程

因此,关于默认部分,每个信号都会得到一个默认值,并且不可能用这种编码方式生成锁存。通常状态_next未设置为空闲。它被设置为state_reg

免费翻译:保持当前状态,直到另行通知

您的代码:

...
elsif (update'event and update='1') then
  d_next <= d_succ;
  w_next <= w_succ;
else
  d_next <= d_reg;
  w_next <= w_reg;
end if;
。。。
elsif(update'event and update='1'),然后

d_next每次当所列信号之一发生变化时,都会对过程进行评估。因此,该列表称为“敏感度列表”

有两种类型的流程:
-连续的(带有时钟信号)和
-组合的(只是简单的逻辑)

第一种类型只需要灵敏度列表中的时钟信号,后一种类型需要每个右手边信号,否则仿真将显示实际硬件以外的其他结果

因此,每次输入信号发生变化('event=true),都会从
begin
开始对过程进行评估<代码>结束进程

因此,关于默认部分,每个信号都会得到一个默认值,并且不可能用这种编码方式生成锁存。通常状态_next未设置为空闲。它被设置为state_reg