只是想知道我是否在VHDL中实现有限状态机是否需要说明所有输出是否处于各种可能的状态?即使我知道某些输出不会从一个状态改变到另一个状态,我知道状态的顺序也会是相同的顺序吗?
例如,在此(强制)示例中:
entity test is
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic;
);
end test;
architecture Behavioral of test is
type executionStage is (s1,s2,s3);
signal currentstate, nextstate: executionStage;
begin
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
else
currentstate <= currentstate;
end if;
end process;
process(currentstate)
begin
case currentstate is
when s1 =>
if (a = '1') then
b <= '1';
c <= '0';
else
b <= '1';
c <= '1';
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
b <= '1';
c <= '1';
else
b <= '1';
c <= '0';
end if;
nextstate <= s3;
when s3 =>
if (a = '1') then
b <= '0';
c <= '0';
else
b <= '1';
c <= '1';
end if;
nextstate <= s1;
end case;
end process;
end Behavioral;
根据我的理解,如果我不这样做,那么会创建锁存器吗?
这个例子不是什么大问题,但是如果我有一台超过10个输出且超过10个状态的机器,那么我的VHDL文件开始看起来非常混乱,我确信复制一定是不好的做法并反复粘贴相同的东西。有没有更好的方法呢?
编辑:我可以为输出定义'默认'状态吗? IE将b设置为在所有进程之外的1,然后只定义它在case语句中的0是什么?那会有用吗?
答案 0 :(得分:7)
是的,如果您只是在过程的某些分支中驱动要组合的信号,您将推断锁存器。
但是,您可以通过在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;
答案 1 :(得分:7)
您的示例代码有三个问题:
端口列表中的最后一个端口不应该有分号:
port (
clk : in std_logic;
a : in std_logic;
b: out std_logic;
c: out std_logic -- no semicolon here!!!
);
在您的注册过程中,您不应该有“其他”声明。虽然这可能会被工具所接受,但它会让你的VHDL设计人员感到困惑。
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
end if;
end process;
在组合逻辑中,灵敏度列表应包含您阅读的所有信号:process(a, currentstate)
。在这种特殊情况下(再次),事情可能会很好,但如果您的敏感度列表不正确,您必然会推断锁存或导致其他问题。
至于你的问题:
答案 2 :(得分:3)
请注意Philippe的回复(不能直接评论?)..
我更喜欢以两种流程样式编写状态机。它非常清楚地表明您期望推断的触发器在哪里以及您不在哪里。它也有点多了 描述硬件 - 想象一下如何构建具有板级逻辑的状态机。 注册的设备匹配状态&lt; = next_state进程, case语句映射到状态寄存器前面的和/或数组。
话虽如此,我通常使用一个进程状态机来处理小型简单任务,然后转移到两个处理机器来处理更大的任务。 我甚至有时会使用第三个过程将状态输出组织到不同的“任务”组中......但不经常。一个非常大的状态机倾向于告诉我架构需要工作..
答案 3 :(得分:0)
process (clk)
begin
if(rising_edge(clk)) then
currentstate <= nextstate;
end if;
end process;
您好
上述过程存在问题,但不是由于灵敏度列表。只需为顺序进程声明clk即可。仿真和综合工具都不会有问题。 clk是代码中最快的变化/转换信号。
但是,您应该使用(最好)异步重置。当然,现在的供应商表示,对于FPGA设计,甚至不需要复位;它们发生在启动时。或者他们提出同步重置。
但是,异步复位对于基于电路板的环境很有价值。
简而言之:为您的设计添加重置并正确修复其行为。
亲切的问候 Nikolaos Kavvadias
答案 4 :(得分:0)
以下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;
这是测试台
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;
答案 5 :(得分:0)
以下VHDL代码是边缘敏感状态机。 在此示例中,边缘敏感过程将使“ out1”和“ out2”与“ clk”同相。
RandomForestRegressor()
这是测试台
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;