2016-02-03 3 views
0

Я пытался записать код VHDL для FSM блока управления моего проекта. Я выбрал 2 процесса с одним процессом для регистра состояния, а другой - для следующей логики состояния и вывода. Во всяком случае, у меня возникают проблемы с настройкой решения, поскольку некоторые сигналы дают предупреждение о блокировке синтеза (я знаю, почему они появляются). Единственное найденное мной решение (без использования одного процесса для логики состояния и выходной логики и без добавления еще 3 состояний) заключалось в том, чтобы добавить некоторую логику вывода в процесс, управляющий логикой состояния.Процесс FSM 2 VHDL

С большим удивлением оно работает, но это концептуально правильно? Я имею в виду, правильно ли загрязнять код процесса регистра состояния с помощью некоторой логики вывода или я нарушаю 2 шаблона процесса?

Это код моего рабочего и контрольного устройства без фиксации. Во всяком случае защелка включала сигнал sel_mode, как я не знаю, как указать в другом отделении государственного IDLE что-то вроде «сохранить предыдущее значение„sel_mode“(без защелки предупреждения).

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 
entity control_unit is 
Port (clock : in STD_LOGIC; 
     reset_n_in : in STD_LOGIC; 
     primo_operando : in STD_LOGIC; 
     secondo_operando : in STD_LOGIC; 
     add_sub : in STD_LOGIC; 
      ov : in STD_LOGIC; 
      subtract_in : in STD_LOGIC; 
      led_ov : out STD_LOGIC; 
      reset_n_out : out STD_LOGIC; 
     subtract_out : out STD_LOGIC; 
      en_w_primo_op : out STD_LOGIC; 
      en_w_secondo_op : out STD_LOGIC; 
      en_w_risultato : out STD_LOGIC; 
      sel_mode : out STD_LOGIC_VECTOR(1 downto 0) 
     ); 
end control_unit; 

architecture Behavioral of control_unit is 

type state is (IDLE, PRIMO_OP, SECONDO_OP, RISULTATO); 
signal curr, nxt : state := IDLE; 

begin 

change_state : process(clock, reset_n_in) 
begin 
    if reset_n_in = '0' then 
     curr <= IDLE; 
-- in the following lines I mix the state register logic with output logic 
    elsif rising_edge(clock) then 
     if curr = PRIMO_OP then 
      sel_mode <= "10"; 
     elsif curr = SECONDO_OP then 
      sel_mode <= "01"; 
     elsif curr = RISULTATO then 
      sel_mode <= "00"; 
     end if; 
     curr <= nxt; 
    end if; 
end process; 

fsm: process(curr, reset_n_in, primo_operando, secondo_operando, add_sub) 
begin 
    if reset_n_in = '0' then 
     reset_n_out <= '0'; 
    else 
     reset_n_out <= '1'; 
    end if; 
    en_w_primo_op <= '0'; 
    en_w_secondo_op <= '0'; 
    en_w_risultato <= '0'; 
    case curr is 
     when IDLE => 
      if primo_operando = '1' then 
      -- sel_mode <= "10"; 
       nxt <= PRIMO_OP; 
      elsif secondo_operando = '1' then 
      -- sel_mode <= "01"; 
       nxt <= SECONDO_OP; 
      elsif add_sub = '1' then 
      -- sel_mode <= "00"; 
       nxt <= RISULTATO; 
      else 
       nxt <= IDLE; 
      -- how to specify keep sel_mode to the previous value?? 
      end if; 
     when PRIMO_OP => 
     -- sel_mode <= "10"; 
      en_w_primo_op <= '1'; 
      nxt <= IDLE; 
     when SECONDO_OP => 
     -- sel_mode <= "01"; 
      en_w_secondo_op <= '1'; 
      nxt <= IDLE; 
     when RISULTATO => 
     -- sel_mode <= "00"; 
      en_w_risultato <= '1'; 
      nxt <= IDLE; 
    end case; 
end process; 

led_ov <= ov; 
subtract_out <= subtract_in; 

end Behavioral; 
+1

*** С большим удивлением он работает, но это концептуально правильно? Я имею в виду, правильно ли загрязнять код процесса регистрации состояния с помощью некоторой логики вывода или я нарушаю 2 шаблона процесса? *** У вас есть вопрос программирования, или это все о стиле? Что произойдет, если 'sel_mode' недействителен до первой ветки из IDLE? (И синтезируется в двоичном представлении перед сопоставлением значения по умолчанию для 'sel_mode', скорее всего,« 00 »). Вы имитируете свой дизайн? – user1155120

ответ

3

Добавлено:

с большим удивлением он работает, но это концептуально правильно я имею в виду, это правильно запачкать код процесса государственного регистра с какой-то выходной логикой или я ломать паттерн 2 процесса

?

Состояние вашего дизайна всегда составлено из все регистры в вашем дизайне, а не только регистр curr в вашем дизайне. Вы можете думать об этом так:

  • (частичное) состояние автомата определяются по curr. Это описано с использованием двухпроцессной формы.

  • Регистр sel_mode в вашем опубликованном коде является регистром пути передачи данных и, таким образом, определяет состояние части пути передачи данных. Вы описали его с использованием однопроцессорной формы. Альтернативное решение, использующее двухпроцессную форму, я опишу ниже.


Во всяком случае защелка включала сигнал «sel_mode», как я не знаю, как указать в другое отделение государственного IDLE что-то вроде «сохранить предыдущее значение„sel_mode“(без предупреждения защелки).

чтобы предотвратить вывод защелки, вы должны сохранить текущее значение sel_mode в тактовых края срабатывающего регистр и присвоить значение регистра каждый раз, когда вы хотите вывести предыдущее значение . Поскольку регистр представляет предыдущее значение, я назвал его sel_mode_prev. Присвоение регистра происходит в синхронизированном процессе вместе с некоторой логикой сброса:

change_state : process(clock, reset_n_in) 
begin 
    if reset_n_in = '0' then 
     curr <= IDLE; 
     sel_mode_prev <= "00"; -- or some other value 
    elsif rising_edge(clock) then 
     curr <= nxt; 
     sel_mode_prev <= sel_mode_i; -- save current value 
    end if; 
end process; 

Выхода sel_mode назначается в комбинационной части. Но, поскольку вы не можете прочитать значение вывода при назначении sel_mode_prev выше, вы должны назначить требуемое значение для sel_mode промежуточному значению, которое я назвал sel_mode_i. Комбинационный процесс fsm затем назначает этот сигнал.Назначение вывода sel_mode <= sel_mode_i; выполняется комбинационным под процессом вместе с другими выходными назначениями.

Здесь представлен модифицированный архитектура с комментариями:

architecture Behavioral of control_unit is 

type state is (IDLE, PRIMO_OP, SECONDO_OP, RISULTATO); 
signal curr, nxt : state := IDLE; 

signal sel_mode_i : std_logic_vector(1 downto 0); -- internal version of output 
signal sel_mode_prev : std_logic_vector(1 downto 0); -- previous version of sel_mode 

begin 

change_state : process(clock, reset_n_in) 
begin 
    if reset_n_in = '0' then 
     curr <= IDLE; 
     sel_mode_prev <= "00"; -- or some other value 
    elsif rising_edge(clock) then 
     curr <= nxt; 
     sel_mode_prev <= sel_mode_i; -- save current value 
    end if; 
end process; 

fsm: process(curr, reset_n_in, primo_operando, secondo_operando, add_sub, 
      sel_mode_prev) -- also add sel_mode_prev here 
begin 
    if reset_n_in = '0' then 
     reset_n_out <= '0'; 
    else 
     reset_n_out <= '1'; 
    end if; 
    en_w_primo_op <= '0'; 
    en_w_secondo_op <= '0'; 
    en_w_risultato <= '0'; 
    case curr is 
     when IDLE => 
      if primo_operando = '1' then 
       sel_mode_i <= "10"; -- assign internal signal 
       nxt <= PRIMO_OP; 
      elsif secondo_operando = '1' then 
       sel_mode_i <= "01"; -- assign internal signal 
       nxt <= SECONDO_OP; 
      elsif add_sub = '1' then 
       sel_mode_i <= "00"; -- assign internal signal 
       nxt <= RISULTATO; 
      else 
       sel_mode_i <= sel_mode_prev; -- output old value at default 
       nxt <= IDLE; 
      end if; 
     when PRIMO_OP => 
      sel_mode_i <= "10"; -- assign internal signal 
      en_w_primo_op <= '1'; 
      nxt <= IDLE; 
     when SECONDO_OP => 
      sel_mode_i <= "01"; -- assign internal signal 
      en_w_secondo_op <= '1'; 
      nxt <= IDLE; 
     when RISULTATO => 
      sel_mode_i <= "00"; -- assign internal signal 
      en_w_risultato <= '1'; 
      nxt <= IDLE; 
    end case; 
end process; 

sel_mode <= sel_mode_i; -- assign internal signal to output 
led_ov <= ov; 
subtract_out <= subtract_in; 

end Behavioral; 
+0

Спасибо, Мартин. Так ли решение я нашел не так? – Mazzola

+0

@Mazzola Нет, ваше решение правильное, если 'sel_mode' соответствует вашей спецификации. Вы просто смешивали шаблоны кода. Я расширил свой ответ, чтобы обсудить этот вопрос. –