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