Я новичок в VHDL и следую этому руководству, чтобы реализовать следующий конечный автомат Мили:
и написали следующий код на VHDL:
library ieee;
use ieee.std_logic_1164.all;
entity fsm is
port(clk, rst, in1 : in std_logic; o1 : out std_logic);
end fsm;
architecture mealy of fsm is
type state is (state1, state2);
signal current_state, next_state : state;
begin
comb: process(current_state, in1) begin
next_state <= current_state; -- default case
case current_state is
when state1 =>
o1 <= '0';
if in1 = '1' then
o1 <= '1';
next_state <= state2;
end if;
when state2 =>
o1 <= '1';
if in1 = '0' then
o1 <= '0';
next_state <= state1;
end if;
end case;
end process;
mem: process(clk, rst) begin
if rst = '1' then
current_state <= state1;
else
current_state <= next_state;
end if;
end process;
end mealy;
Однако при применении следующего тестового стенда:
library ieee;
use ieee.std_logic_1164.all;
entity fsm_tb is
end fsm_tb;
architecture sim of fsm_tb is
constant clockperiod : time := 10 ns; -- 100 Mhz clock
signal clk : std_logic := '0';
signal rst : std_logic;
signal in1, o_mealy : std_logic;
begin
uut_mealy : entity work.fsm(mealy) port map( clk => clk, rst => rst, in1 => in1, o1 => o_mealy);
clk <= not clk after clockperiod/2;
process begin
-- initial reset
in1 <= '0';
rst <= '1';
wait until rising_edge(clk);
-- take device out of reset
rst <= '0';
-- apply same inputs to both the devices
in1 <= '0'; wait for 23 ns;
in1 <= '1'; wait for 32 ns;
in1 <= '0'; wait for 7 ns;
in1 <= '1'; wait for 15 ns;
wait;
end process;
end sim;
формы сигналов, которые я получил, не имеют для меня смысла:
Как вы можете видеть, вывод o_mealy
меняется даже без перепада тактовых импульсов. Кажется, что он просто следует только вводу. Напротив, я реализовал эквивалентную машину Мура, и, похоже, она работает нормально:
Если кто-то может указать, что я делаю неправильно, это будет высоко оценено. Опять же, я использовал это видео для справки. Я использую GHDL с GTKWave.
Взгляните на вашу параллельную логику:
case current_state is
when state1 =>
o1 <= '0';
if in1 = '1' then
o1 <= '1';
next_state <= state2;
end if;
when state2 =>
o1 <= '1';
if in1 = '0' then
o1 <= '0';
next_state <= state1;
end if;
end case;
В любом из двух состояний, если in1 = '1', на выходе 1, если in1 = '0', на выходе 0. Таким образом, FSM работает нормально, но, глядя снаружи внутрь, вы просто не видите разницы между два состояния.
С точки зрения того, что вы делаете неправильно: я думаю, что это правильно, на самом деле, глядя на ваш рисунок. В мучной машине вывод зависит от текущего состояния и текущего ввода, что здесь и происходит.
Спасибо. Больше всего меня беспокоило то, почему выходные данные менялись, даже если не было фронта тактового сигнала. Выход в мучной машине зависит от текущего состояния и ввода - да, но не должно ли это изменение вывода быть отложено до следующего тактового цикла?
Глядя на фактический код, почему вы ожидаете, что это будет так? Часы не играют никакой роли в настройке o1, o1 является прямым результатом in1. Если изменяется in1, следует o1. Если вам нужно, чтобы часы были задействованы, вам нужно каким-то образом связать это изменение с восходящим_краем (clk) (или, конечно, с падением_края).
Может быть, вы ожидаете, что параллельная логика будет запускаться один раз после каждого изменения состояния? Но это не то, как параллельная логика в VHDL работает, вы описываете некую постоянную реальность, а не какой-то набор последовательных шагов.
Используя формат файла дампа GHDL GHW, чтобы позволить gtkwave отображать значения перечисляемого типа, мы видим:
где в current_state обновляется по обоим фронтам часов (способ, который вряд ли поддерживается для синтеза).
Это можно исправить, оценив один фронт тактового сигнала способом, способствующим синтезу:
mem: process(clk, rst) begin
if rst = '1' then
current_state <= state1;
elsif rising_edge(clk) then -- evaluate clock edge
current_state <= next_state;
end if;
end process;
И это дает нам
current_state переходит только на одном фронте тактового сигнала.
Это характеристика машины Мили в отличие от машины Мура. Если бы вход не зависел напрямую от входов, это была бы машина Мура.