FSM Mealy 机器序列检测器。如何使用多个触发器?
FSM Mealy Machine Sequence Detector. How to use multiple flip flops?
现在我正在 Vivado 中做一个小项目,一个 Mealy FSM。该程序必须检测到一个 6 位序列 001011,并在检测到该序列时输出“1”。
关于序列检测的代码做的很好,但除此之外,它还必须使用三个触发器:JK、D和T。
关于如何添加它们有什么意见或建议吗?
感谢您的宝贵时间。
这是 FSM 代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity sequence is
port(
clk : in std_logic;
reset : in std_logic;
x: in std_logic;
z : out std_logic;
a : out std_logic;
b : out std_logic;
c : out std_logic;
d : out std_logic;
e : out std_logic;
f : out std_logic);
end sequence;
architecture behavioral of sequence is
type state_type is (Q0, Q1, Q2, Q3, Q4, Q5);
signal state, next_state : state_type;
begin
state_register: process (clk, reset)
begin
if (reset = '1') then --if reset is high, goto state Q0
state <= Q0;
elsif (clk'event and clk = '1') then --if not, and rising
state <= next_state; --edge, go to next state
end if;
end process;
next_state_func: process (x, state)
begin
case state is
when Q0 =>
if x = '0' then
next_state <= Q1;
else
next_state <= Q0;
end if;
when Q1 =>
if x = '0' then
next_state <= Q2;
else
next_state <= Q0;
end if;
when Q2 =>
if x = '1' then
next_state <= Q3;
else
next_state <= Q2;
end if;
when Q3 =>
if x ='0' then
next_state <= Q4;
else
next_state <= Q0;
end if;
when Q4 =>
if x = '1' then
next_state <= Q5;
else
next_state <= Q2;
end if;
when Q5 =>
if x = '1' then
next_state <= Q0;
else
next_state <= Q1;
end if;
end case;
end process;
-- This process controls the output of the sequence detector.
-- Each state has it's own output along with 'z' which indicates
-- the entire sequence 001011 has been detected.
output_func: process (x, state)
begin
case state is
when Q0 => z <= '0';
a <= '1';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
when Q1 => z <= '0';
a <= '0';
b <= '1';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
when Q2 => z <= '0';
a <= '0';
b <= '0';
c <= '1';
d <= '0';
e <= '0';
f <= '0';
when Q3 => z <= '0';
a <= '0';
b <= '0';
c <= '0';
d <= '1';
e <= '0';
f <= '0';
when Q4 => z <= '0';
a <= '0';
b <= '0';
c <= '0';
d <= '0';
e <= '1';
f <= '0';
when Q5 => z <= '1';
a <= '0';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '1';
end case;
end process;
end behavioral;
[1]: https://i.stack.imgur.com/pVwxL.jpg - 这是包含 FSM 状态图 Table 的 table。
您的代码有误。看看output_func
过程;这是组合的,只是解码当前状态,而不 查看x
。 a
到 f
输出不是必需的,只是当前状态的 6 位解码 - 为什么? z
输出在当前状态为 Q5
时设置,这不是您想要的 - 整个过程是多余的。您需要在主 FSM 中设置 z
,当当前状态为 Q5
时, 和 x
为 1 - 即。在 next_state <= Q0
过渡期。
关于你的实际问题 - 你不能用这段代码强制选择任何特定的 F/F 类型 - 合成器会做任何它想做的事情,这意味着它将以 D 类型实现整个事情,因为 JKs 在过去 20 年里已经过时了。 T类型可能也是如此。你需要重新开始,假装你有技术,有T、D、JK的库。自己将它们编写为单独的实体,并重新编写代码以实例化这些组件,而不是让合成器推断它们。重写您的 FSM 以使用 JK——您提供的图表向您展示了如何操作。换句话说,导出每个 F/F 的 J 和 K 输入。 z
输出可以是 D 型。你应该能够在某个地方穿上 T 型——我把它留给你作为练习。
现在我正在 Vivado 中做一个小项目,一个 Mealy FSM。该程序必须检测到一个 6 位序列 001011,并在检测到该序列时输出“1”。
关于序列检测的代码做的很好,但除此之外,它还必须使用三个触发器:JK、D和T。
关于如何添加它们有什么意见或建议吗?
感谢您的宝贵时间。
这是 FSM 代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity sequence is
port(
clk : in std_logic;
reset : in std_logic;
x: in std_logic;
z : out std_logic;
a : out std_logic;
b : out std_logic;
c : out std_logic;
d : out std_logic;
e : out std_logic;
f : out std_logic);
end sequence;
architecture behavioral of sequence is
type state_type is (Q0, Q1, Q2, Q3, Q4, Q5);
signal state, next_state : state_type;
begin
state_register: process (clk, reset)
begin
if (reset = '1') then --if reset is high, goto state Q0
state <= Q0;
elsif (clk'event and clk = '1') then --if not, and rising
state <= next_state; --edge, go to next state
end if;
end process;
next_state_func: process (x, state)
begin
case state is
when Q0 =>
if x = '0' then
next_state <= Q1;
else
next_state <= Q0;
end if;
when Q1 =>
if x = '0' then
next_state <= Q2;
else
next_state <= Q0;
end if;
when Q2 =>
if x = '1' then
next_state <= Q3;
else
next_state <= Q2;
end if;
when Q3 =>
if x ='0' then
next_state <= Q4;
else
next_state <= Q0;
end if;
when Q4 =>
if x = '1' then
next_state <= Q5;
else
next_state <= Q2;
end if;
when Q5 =>
if x = '1' then
next_state <= Q0;
else
next_state <= Q1;
end if;
end case;
end process;
-- This process controls the output of the sequence detector.
-- Each state has it's own output along with 'z' which indicates
-- the entire sequence 001011 has been detected.
output_func: process (x, state)
begin
case state is
when Q0 => z <= '0';
a <= '1';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
when Q1 => z <= '0';
a <= '0';
b <= '1';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
when Q2 => z <= '0';
a <= '0';
b <= '0';
c <= '1';
d <= '0';
e <= '0';
f <= '0';
when Q3 => z <= '0';
a <= '0';
b <= '0';
c <= '0';
d <= '1';
e <= '0';
f <= '0';
when Q4 => z <= '0';
a <= '0';
b <= '0';
c <= '0';
d <= '0';
e <= '1';
f <= '0';
when Q5 => z <= '1';
a <= '0';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '1';
end case;
end process;
end behavioral;
[1]: https://i.stack.imgur.com/pVwxL.jpg - 这是包含 FSM 状态图 Table 的 table。
您的代码有误。看看output_func
过程;这是组合的,只是解码当前状态,而不 查看x
。 a
到 f
输出不是必需的,只是当前状态的 6 位解码 - 为什么? z
输出在当前状态为 Q5
时设置,这不是您想要的 - 整个过程是多余的。您需要在主 FSM 中设置 z
,当当前状态为 Q5
时, 和 x
为 1 - 即。在 next_state <= Q0
过渡期。
关于你的实际问题 - 你不能用这段代码强制选择任何特定的 F/F 类型 - 合成器会做任何它想做的事情,这意味着它将以 D 类型实现整个事情,因为 JKs 在过去 20 年里已经过时了。 T类型可能也是如此。你需要重新开始,假装你有技术,有T、D、JK的库。自己将它们编写为单独的实体,并重新编写代码以实例化这些组件,而不是让合成器推断它们。重写您的 FSM 以使用 JK——您提供的图表向您展示了如何操作。换句话说,导出每个 F/F 的 J 和 K 输入。 z
输出可以是 D 型。你应该能够在某个地方穿上 T 型——我把它留给你作为练习。