Сброс VHDL во время исполнения - PullRequest
0 голосов
/ 05 декабря 2018

Я разрабатываю безопасный детектор последовательностей, который является автоматическим автоматом, используя 3 различных процесса.Он имеет в качестве входа num_in (8 бит), который представляет номер входа, и первый вход (1 бит), который должен быть '1' только во время первого числа, в противном случае FSMпереходит в состояние с фиксированным выходом.Это условие может повториться, если пользователь введет 3 неправильные последовательности ввода.Выход состоит из сигнала unlock (равного '1', если последовательность правильная) и сигнала предупреждение (равного '1', если последовательность неверна),и они оба должны обновляться каждые 5 тактов, поскольку последовательность состоит из 5 чисел, даже если один из входных данных неправильный.Первый процесс:

state_register_p : process(rst, clk)
        begin 
            if rst = '0' then   -- initial state, asynchronous rst
                current_state <= S0;
            elsif (clk'EVENT and clk = '1') then
                if(rst = '0') then
                    current_state <= S0;
                    --errors <= -1;
                else
                    current_state <= next_state;
                    five_cycles <= std_logic_vector(to_unsigned((to_integer(unsigned(five_cycles)) + 1), five_cycles'length));
                    if to_integer(unsigned(five_cycles)) = 5 then
                        five_cycles <= "001";
                    end if;
                 end if;
            end if;
    end process state_register_p;

В этом автомате я получаю каждый такт по 8 бит, и мне нужно проверить, находится ли он в правильной последовательности, если нет, после 5 циклов с началаЯ установил ошибку.Когда ошибка = 3, FSM переходит в другое состояние, в котором разблокировка зафиксирована на 0, а предупреждение на 1, пока сброс не будет передан в качестве входа снова и FSM не запуститсяиз исходного состояния S0.Мой код тестового стенда такой:

clk_tb <= (not(clk_tb) and end_sim) after T_CLK / 2; 
rst_tb <= '1' after T_RESET;

d_process: process(clk_tb, rst_tb)
    variable t : integer := 0; 
  begin
    if(rst_tb = '0') then
      num_in_tb <= (others => '0');
      first_tb <= '0';
      t := 0;
    elsif(rising_edge(clk_tb)) then
      case(t) is 
        -- correct
        when 1 => num_in_tb <= "00100100"; first_tb <= '1';  --36
        when 2 => num_in_tb <= "00010011"; first_tb <= '0';  --19
        when 3 => num_in_tb <= "00111000"; first_tb <= '0';  --56
        when 4 => num_in_tb <= "01100101"; first_tb <= '0';  --101
        when 5 => num_in_tb <= "01001001"; first_tb <= '0';  --73

        --invalid because of the num_in (error = 1, but still < 3)
        when 6 => num_in_tb <= "00100100"; first_tb <= '1';  --36
        when 7 => num_in_tb <= "00010011"; first_tb <= '0';  --19
        when 8 => num_in_tb <= "00111000"; first_tb <= '0';  --56
        when 9 => num_in_tb <= "01100100"; first_tb <= '0';  --100
        when 10 => num_in_tb <= "01001001"; first_tb <= '0';  --73

        --invalid because of the two first (blocking condition) 
        when 11=> num_in_tb <= "00100101"; first_tb <= '0';  --37
        when 12=> num_in_tb <= "00100110"; first_tb <= '1';  --38
        when 13=> num_in_tb <= "00100111"; first_tb <= '1';  --39

        --reset is needed
        when 14=> rst_tb <= '0', '1' after T_RESET;  --unknown behavior here

        -- correct
        when 15 => num_in_tb <= "00100100"; first_tb <= '1';  --36
        when 16 => num_in_tb <= "00010011"; first_tb <= '0';  --19
        when 17 => num_in_tb <= "00111000"; first_tb <= '0';  --56
        when 18 => num_in_tb <= "01100101"; first_tb <= '0';  --101
        when 19 => num_in_tb <= "01001001"; first_tb <= '0';  --73

        when 20 => end_sim <= '0';
        when others => null; -- Specifying that nothing happens in the other cases 

      end case;
      t := t + 1;
    end if;
  end process;

Я хотел бы вставить что-то подобное когда 14 => rst_tb <= '0', '1' после T_RESET; </em> для сброса моегоFMS.Как мне это сделать?Спасибо

1 Ответ

0 голосов
/ 05 декабря 2018

В настоящее время у вас есть rst_tb в нескольких местах, что является конфликтом.Удалите его снаружи d_process и удалите rst_tb из списка чувствительности.Тогда ваш оператор if будет:

if rising_edge(clk_tb) then ...

Вы можете создать предложение when 0 => для переменной t, в которой вы выполняете сброс:

when 0 =>
  num_in_tb <= (others=>'0');
  first_tb <= '0';
  t := 0;
  rst_tb <= '0', '1' after T_RESET;

Тогда вы можете иметь rst_tb снова указано в предложении when 14 =>.

...

when 14 =>
  rst_tb <= '0', '1' after T_RESET;

...

Вы должны будете сделать T_RESET короче периода clk_tb, иначе процесс state_register_p начнет пропускать стимул с d_process.

РЕДАКТИРОВАТЬ:

library IEEE;
use IEEE.std_logic_1164.all;
library STD;
use STD.textio.all;

entity tb is
end tb;

architecture arch of tb is

constant T_RESET : time := 5 ns;
constant T_CLK   : time := 10 ns;

signal clk_tb    : std_logic := '0';
signal rst_tb    : std_logic := '0';
signal trig_rst  : std_logic := '0';
signal num_in_tb : std_logic_vector(7 downto 0);
signal first_tb  : std_logic := '0';
signal end_sim   : std_logic := '1';

begin

--  rst_tb <= '0','1' after T_RESET;
clk_tb <= (not(clk_tb) and end_sim) after T_CLK / 2; 

--d_process: process(clk_tb, rst_tb)
d_process: process(clk_tb)
  variable t : integer := 0; 
begin
--    if(rst_tb = '0') then
--      num_in_tb <= (others => '0');
--      first_tb <= '0';
--      t := 0;
--    elsif(rising_edge(clk_tb)) then
  if(rising_edge(clk_tb)) then
    case(t) is 
    when 0 =>
      num_in_tb <= (others=>'0');
      first_tb <= '0';
      rst_tb <= '0', '1' after T_RESET;
    -- correct
    when 1 => num_in_tb <= "00100100"; first_tb <= '1';  --36
    when 2 => num_in_tb <= "00010011"; first_tb <= '0';  --19
    when 3 => num_in_tb <= "00111000"; first_tb <= '0';  --56
    when 4 => num_in_tb <= "01100101"; first_tb <= '0';  --101
    when 5 => num_in_tb <= "01001001"; first_tb <= '0';  --73

    --invalid because of the num_in (error = 1, but still < 3)
    when 6 => num_in_tb <= "00100100"; first_tb <= '1';  --36
    when 7 => num_in_tb <= "00010011"; first_tb <= '0';  --19
    when 8 => num_in_tb <= "00111000"; first_tb <= '0';  --56
    when 9 => num_in_tb <= "01100100"; first_tb <= '0';  --100
    when 10 => num_in_tb <= "01001001"; first_tb <= '0';  --73

    --invalid because of the two first (blocking condition) 
    when 11 => num_in_tb <= "00100101"; first_tb <= '0';  --37
    when 12 => num_in_tb <= "00100110"; first_tb <= '1';  --38
    when 13 => num_in_tb <= "00100111"; first_tb <= '1';  --39

    --reset is needed
    when 14 => rst_tb <= '0', '1' after T_RESET;  --unknown behavior here

    -- correct
    when 15 => num_in_tb <= "00100100"; first_tb <= '1';  --36
    when 16 => num_in_tb <= "00010011"; first_tb <= '0';  --19
    when 17 => num_in_tb <= "00111000"; first_tb <= '0';  --56
    when 18 => num_in_tb <= "01100101"; first_tb <= '0';  --101
    when 19 => num_in_tb <= "01001001"; first_tb <= '0';  --73

    when 20 => end_sim <= '0';
    when others => null; -- Specifying that nothing happens in the other cases 

    end case;
    t := t + 1;
  end if;
end process d_process;

end arch;
...