用VHDL实现有限状态机
只是想知道我是否在用VHDL实现一个有限状态机,我是否需要声明所有的输出都处于每种可能的状态?即使我知道一些输出不会从一个状态改变到另一个状态,并且我知道状态的顺序也会是相同的顺序 例如,在此(强制)示例中:用VHDL实现有限状态机,vhdl,fsm,Vhdl,Fsm,只是想知道我是否在用VHDL实现一个有限状态机,我是否需要声明所有的输出都处于每种可能的状态?即使我知道一些输出不会从一个状态改变到另一个状态,并且我知道状态的顺序也会是相同的顺序 例如,在此(强制)示例中: 实体测试不可用 港口( clk:标准逻辑中; 答:标准逻辑; b:输出标准逻辑; c:输出标准逻辑; ); 结束试验; 行为测试的体系结构是 执行阶段类型为(s1、s2、s3); 信号当前状态,下一个状态:executionStage; 开始 过程(clk) 开始 如果(上升沿(clk))
实体测试不可用
港口(
clk:标准逻辑中;
答:标准逻辑;
b:输出标准逻辑;
c:输出标准逻辑;
);
结束试验;
行为测试的体系结构是
执行阶段类型为(s1、s2、s3);
信号当前状态,下一个状态:executionStage;
开始
过程(clk)
开始
如果(上升沿(clk)),则
currentstate是的,如果您仅在流程的某些分支中驱动组合信号,您将推断锁存
但是,您可以通过在case
语句之前(但在相同的过程中)为信号指定一个值来定义“默认”状态。例如:
process(currentstate, a)
begin
b <= '1';
c <= '1';
case currentstate is
when s1 =>
if (a = '1') then
c <= '0';
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
c <= '0';
end if;
nextstate <= s3;
when s3 =>
if (a = '1') then
b <= '0';
c <= '0';
end if;
nextstate <= s1;
end case;
end process;
进程(当前状态,a)
开始
示例代码有三个问题:
端口列表中的最后一个端口不应有分号:
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic -- no semicolon here!!!
);
在注册过程中,不应该有“else”语句。虽然这些工具可能会接受这一点,但它会让您的VHDL设计同事感到困惑
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
end if;
end process;
过程(clk)
开始
如果(上升沿(clk)),则
当前状态<代码>进程(clk)
开始
如果(上升沿(clk)),则
currentstate请注意Philippe的回答(不能直接评论吗?)
我更喜欢用双进程风格编写状态机。它非常清楚地表明了你在哪里期待推断的触发器,在哪里不期待。这也有点像
描述硬件-例如,想象一下使用板级逻辑构建状态机。
注册的设备与状态匹配以下VHDL代码是级别敏感状态机。
本例中的电平敏感过程将使“out1”与“clk”不同步,“out2”与“clk”同相
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_level_sensitive : process (clk)
begin
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end process state_process_level_sensitive;
end Behavioral;
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_edge_sensitive : process (clk)
begin
if rising_edge (clk) then
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end if;
end process state_process_edge_sensitive;
end Behavioral;
实体主代码为
端口(时钟:在标准逻辑中;
in1:标准逻辑;
in2:in标准逻辑;
out1:out标准逻辑;
out2:out标准逻辑);
结束主代码;
主要_代码的体系结构是
--以下是用于间接关联或分配输出(out1和out2)值的温度信号
信号输出1温度:标准逻辑:='0';
信号输出2_温度:标准逻辑:='0';
--计数器寄存器
信号计数器:整数范围0到255:=0;
信号计数器时钟:整数范围0至255:=0;
--状态机定义
类型状态机器类型为(s0,s1);
信号状态:状态机类型=s0;
开始
--同时作业
out1以下VHDL代码是边缘敏感状态机。
本例中的边缘敏感处理将使“out1”和“out2”与“clk”同相
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_level_sensitive : process (clk)
begin
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end process state_process_level_sensitive;
end Behavioral;
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_edge_sensitive : process (clk)
begin
if rising_edge (clk) then
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end if;
end process state_process_edge_sensitive;
end Behavioral;
实体主代码为
端口(时钟:在标准逻辑中;
in1:标准逻辑;
in2:in标准逻辑;
out1:out标准逻辑;
out2:out标准逻辑);
结束主代码;
主要_代码的体系结构是
--以下是用于间接关联或分配输出(out1和out2)值的温度信号
信号输出1温度:标准逻辑:='0';
信号输出2_温度:标准逻辑:='0';
--计数器寄存器
信号计数器:整数范围0到255:=0;
信号计数器时钟:整数范围0至255:=0;
--状态机定义
类型状态机器类型为(s0,s1);
信号状态:状态机类型=s0;
开始
--同时作业
谢谢Tomi!所以在我的例子中,我可以设置b,基本上我想知道我可以设置一个默认值,它可以被第一个case语句中的所有其他case/if语句“继承”。或者我是否需要在所有case/if语句中设置一个新的默认值?您只需要确保为分支的每个分支中的信号分配了一个值(即,在整个过程中没有未为信号分配值的路径)。这是通过在case语句之外指定一个合理的默认值来实现的。在case语句中没有这样做的方法。我更新了我的响应以包含一个示例。这样做,我意识到我可能误解了你的评论。是的,可以在when
语句内赋值,但在该语句中包含的if
语句外赋值。当时,不需要在中只有一条语句(这在您的代码中已经很明显了,因为您在if
语句之外指定了nextstate
。谢谢Philipe!非常感谢您提供的信息。:)
entity main_code is
Port ( clk : in STD_LOGIC;
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
out1 : out STD_LOGIC;
out2 : out STD_LOGIC);
end main_code;
architecture Behavioral of main_code is
-- here are temp signals to associate or assign output (out1 and out2) values indirectly
signal out1_temp : std_logic := '0';
signal out2_temp : std_logic := '0';
-- counter registers
signal counter : integer range 0 to 255 := 0;
signal counter_8th_clk : integer range 0 to 255 := 0;
-- state machines definition
type state_machine_type is (s0,s1);
signal state : state_machine_type := s0;
begin
-- concurrent assignments
out1 <= out1_temp;
out2 <= out2_temp;
--half clock generator process
half_clock : process (clk) is
begin
if rising_edge(clk) then
--out1_temp <= not out1_temp;
end if;
end process half_clock;
-- max counter = ndiv -1; here ndiv=4; counter starts from zero;
one_fourth_clock : process (clk)
begin
if rising_edge(clk) then
counter <= counter + 1;
if (counter >= 3) then
counter <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_fourth_clock;
one_eighth_clock : process (clk)
begin
if rising_edge(clk) then
counter_8th_clk <= counter_8th_clk + 1;
if (counter_8th_clk>=7) then
counter_8th_clk <= 0;
-- out2_temp <= not out2_temp;
end if;
end if;
end process one_eighth_clock;
-- state_process creates two half clock (speed) with out1 out of phase with clk
-- and out2 in-phase with clk
-- following process is sensitive to clk level not edge
state_process_edge_sensitive : process (clk)
begin
if rising_edge (clk) then
case state is
when s0 =>
out1_temp <= not out1_temp;
state <= s1;
when s1 =>
out2_temp <= not out2_temp;
state <= s0;
end case;
end if;
end process state_process_edge_sensitive;
end Behavioral;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY my_test_bench IS
END my_test_bench;
ARCHITECTURE behavior OF my_test_bench IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT main_code
PORT(
clk : IN std_logic;
in1 : IN std_logic;
in2 : IN std_logic;
out1 : OUT std_logic;
out2 : OUT std_logic
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal in1 : std_logic := '0';
signal in2 : std_logic := '0';
--Outputs
signal out1 : std_logic;
signal out2 : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: main_code PORT MAP (
clk => clk,
in1 => in1,
in2 => in2,
out1 => out1,
out2 => out2
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
-- wait for 100 ns;
--
-- wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;