VHDL 在执行期间重置
VHDL reset during execution
我正在开发一个安全序列检测器,它是一个 FSM,使用 3 个不同的过程。它的输入 num_in(8 位)代表输入数字,还有一个 first 输入(1 位)必须是仅在第一个数字期间为“1”,否则 FSM 进入固定输出状态。如果用户插入 3 个错误的输入序列,这种情况可能会再次发生。输出由 unlock 信号(如果序列正确则等于'1')和 warning 信号(等于'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;
在这个 FSM 中,我收到每个时钟一个 8 位的数字,我必须检查它是否在正确的序列中,如果不是,在从 beginnig 的 5 个周期后我设置一个错误。当 error = 3 时,FSM 进入另一种状态,其中 unlock 固定为 0,warning 固定为 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;
我想插入类似的内容 when 14=> rst_tb <= '0', '1' after T_RESET; to reset我的飞行管理系统。我该怎么做?谢谢
您目前 rst_tb
在多个位置驾驶,这是一个冲突。从 d_process
之外删除它,并从您的敏感列表中删除 rst_tb
。那么您的 if 语句将是:
if rising_edge(clk_tb) then ...
您可以在执行重置的 t
变量上创建一个 when 0 =>
子句:
when 0 =>
num_in_tb <= (others=>'0');
first_tb <= '0';
t := 0;
rst_tb <= '0', '1' after T_RESET;
然后您可以在 when 14 =>
子句中再次驱动 rst_tb
。
...
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;
我正在开发一个安全序列检测器,它是一个 FSM,使用 3 个不同的过程。它的输入 num_in(8 位)代表输入数字,还有一个 first 输入(1 位)必须是仅在第一个数字期间为“1”,否则 FSM 进入固定输出状态。如果用户插入 3 个错误的输入序列,这种情况可能会再次发生。输出由 unlock 信号(如果序列正确则等于'1')和 warning 信号(等于'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;
在这个 FSM 中,我收到每个时钟一个 8 位的数字,我必须检查它是否在正确的序列中,如果不是,在从 beginnig 的 5 个周期后我设置一个错误。当 error = 3 时,FSM 进入另一种状态,其中 unlock 固定为 0,warning 固定为 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;
我想插入类似的内容 when 14=> rst_tb <= '0', '1' after T_RESET; to reset我的飞行管理系统。我该怎么做?谢谢
您目前 rst_tb
在多个位置驾驶,这是一个冲突。从 d_process
之外删除它,并从您的敏感列表中删除 rst_tb
。那么您的 if 语句将是:
if rising_edge(clk_tb) then ...
您可以在执行重置的 t
变量上创建一个 when 0 =>
子句:
when 0 =>
num_in_tb <= (others=>'0');
first_tb <= '0';
t := 0;
rst_tb <= '0', '1' after T_RESET;
然后您可以在 when 14 =>
子句中再次驱动 rst_tb
。
...
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;