我为Mealy机器编写了一个VHDL程序,可以检测模式1011,如下所示:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY mealy_detector_1011 IS
PORT(
rst_n : IN STD_LOGIC;
clk : IN STD_LOGIC;
data : IN STD_LOGIC;
result : OUT STD_LOGIC);
END ENTITY;
ARCHITECTURE beh OF mealy_detector_1011 IS
TYPE state IS (IDLE, GOT1, GOT10, GOT101);
SIGNAL current_state : state;
SIGNAL next_state : state;
BEGIN
REG: PROCESS(clk, rst_n)
BEGIN
IF rst_n = '0' THEN
current_state <= IDLE;
ELSIF rising_edge(clk) THEN
current_state <= next_state;
END IF;
END PROCESS REG;
NEXTSTATE: PROCESS(data, current_state)
BEGIN
CASE current_state IS
WHEN IDLE =>
IF data = '1' THEN
next_state <= GOT1;
ELSE next_state <= IDLE;
END IF;
WHEN GOT1 =>
IF data = '0' THEN
next_state <= GOT10;
ELSE next_state <= GOT1;
END IF;
WHEN GOT10 =>
IF data = '1' THEN
next_state <= GOT101;
ELSE next_state <= IDLE;
END IF;
WHEN GOT101 =>
IF data = '1' THEN
next_state <= GOT1;
ELSE
next_state <= GOT10;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS NEXTSTATE;
result <= '1' WHEN (current_state = GOT101 and data = '1') ELSE '0';
END beh;
并将.do模拟为以下
vcom mealy_detector_1011.vhd
vsim mealy_detector_1011
add wave -r /*
force -freeze /clk 1 0, 0 50 -r 100
force -freeze /rst_n 0 0, 1 10
force -freeze /data 0 0, 1 80, 0 180, 1 230, 0 330, 1 470, 0 530, 1 570, 0 620
run 800 ns
但是,我的模拟结果并不正确。你能帮我解决这个问题吗?谢谢!
答案 0 :(得分:3)
您不断从似乎认为result
出现问题的人那里得到答案。
问题是data
与clk
不同步。你在整个地方都有过渡,粉状输出正在做它应该做的事情。
它是组合输出,不应用作时钟。它可以用作clk
上运行的寄存器的使能或输入。
对于我们这些没有Modelsim的人来说,这是一个测试平台:
library ieee;
use ieee.std_logic_1164.all;
entity mealy_1011_tb is
end entity;
architecture foo of mealy_1011_tb is
signal rst_n: std_logic := '0';
signal clk: std_logic := '1';
signal data: std_logic := '0';
signal result: std_logic;
begin
DUT:
entity work.mealy_detector_1011
port map (
rst_n => rst_n,
clk => clk,
data => data,
result => result
);
CLOCK:
process
begin
wait for 50 ns;
clk <= not clk;
if Now > 799 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 10 ns;
rst_n <= '1';
wait for 70 ns;
data <= '1'; -- 80 ns
wait for 100 ns;
data <= '0'; -- 180 ns
wait for 50 ns;
data <= '1'; -- 230 ns
wait for 100 ns;
data <= '0'; -- 330 ns
wait for 140 ns;
data <= '1'; -- 470 ns
wait for 60 ns;
data <= '0'; -- 530 ns
wait for 40 ns;
data <= '1'; -- 570 ns
wait for 50 ns;
data <= '0'; -- 620 ns
wait;
end process;
end architecture;
它给出了与模拟相同的答案:
您不希望在result
上看到额外的延迟,使data
时钟同步。你的状态机正在做它应该做的事情。
如果data
是时钟同步的,您可以使用result
使用clk
来not clk nand result
并生成结果事件时钟。
答案 1 :(得分:0)
您只需将Mealy输出写入流程的if-then-else转换分支。
NEXTSTATE: PROCESS(data, current_state)
BEGIN
-- default assignments
next_state <= state; -- so your code won't create latches
result <= '0'; -- result is always 0, except of transition GOT101 to GOT1
CASE current_state IS
WHEN IDLE =>
IF data = '1' THEN
next_state <= GOT1;
ELSE next_state <= IDLE;
END IF;
WHEN GOT1 =>
IF data = '0' THEN
next_state <= GOT10;
ELSE next_state <= GOT1;
END IF;
WHEN GOT10 =>
IF data = '1' THEN
next_state <= GOT101;
ELSE next_state <= IDLE;
END IF;
WHEN GOT101 =>
IF data = '1' THEN
result <= '1';
next_state <= GOT1;
ELSE
next_state <= GOT10;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS NEXTSTATE;