VHDL与有限状态机的反应时间?
这是我经常遇到的问题-希望有人能向我澄清正确的思考方式 我基本上可以把我的问题简化为:我有一个模块,输入VHDL与有限状态机的反应时间?,vhdl,fsm,Vhdl,Fsm,这是我经常遇到的问题-希望有人能向我澄清正确的思考方式 我基本上可以把我的问题简化为:我有一个模块,输入p\u in,输出p\u out和时钟clk。其功能是,无论何时in变低-out都应产生持续时间为一个时钟周期的高脉冲;这个“负边缘检测器”被实现为一个具有四种状态的FSM:resetwt_in_lo(等待输入低)采样信号(在检测到输入转换为零时,在输出时生成高信号)wt_in_hi(采样信号升高后,等待输入高电平) 代码如下所示,isim模拟器中的结果如下所示(这是行为模拟,因此不应有任何特
p\u in
,输出p\u out
和时钟clk
。其功能是,无论何时in
变低-out
都应产生持续时间为一个时钟周期的高脉冲;这个“负边缘检测器”被实现为一个具有四种状态的FSM:reset
wt_in_lo
(等待输入低)<代码>采样信号(在检测到输入转换为零时,在输出时生成高信号)wt_in_hi
(采样信号升高后,等待输入高电平)
代码如下所示,isim
模拟器中的结果如下所示(这是行为模拟,因此不应有任何特定于平台的翻译影响):
基本上,状态确实会像我期望的那样发生变化-第一个时钟posedge,FSM识别中的为低,因此它会转换为采样信号
;第二个时钟边缘,我们处于采样信号
状态
- 然而,这是我的问题-我希望
out
在进入sample\u信号
状态后立即变高(或者至少,这是我试图实现的);然而,out
在进入下一个状态(wt\u in\u hi
)之前不会执行高脉冲李>
然后我通常尝试围绕这一点进行编码(即,在同步fsm部分设置out
,这可能是个坏主意),最终让合成器和我自己都感到困惑:)
因此,简言之,是否有可能在进入第二种状态时(以及在第二种状态的持续时间内),我立即得到一个输出
信号;正确的编码方法是什么
非常感谢您的回答,
干杯
守则:
-- file: fsm_react_test_twb.vhd
---------------
-- single file testbench examples - see also;
-- http://www.cs.umbc.edu/portal/help/VHDL/samples/samples.shtml
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- NEVER call port pins "in"; "out": ERROR:HDLCompiler:806 'Syntax error near "in"'!
ENTITY negedgeDetector IS
PORT (
clk: IN STD_LOGIC;
p_in : IN STD_LOGIC;
p_out: OUT STD_LOGIC
);
END negedgeDetector;
ARCHITECTURE structure OF negedgeDetector IS
-- 'dummy signals' - registers
SIGNAL w_in : STD_LOGIC := 'Z';
SIGNAL w_out : STD_LOGIC := 'Z';
-- fsm states
TYPE states_ned IS -- ned: negedgeDetector
(
ned_reset,
ned_wt_in_lo, -- wait for in active low
ned_sample_signal, -- signal for sampling
ned_wt_in_hi -- wait for in active hi
);
-- init fsm state vars
SIGNAL state_ned, next_state_ned: states_ned := ned_reset;
-- implementation:
BEGIN
-- assign 'wire' / registers
w_in <= p_in;
p_out <= w_out;
-- STATE MACHINES CODE =========
sm_ned: PROCESS(state_ned, w_in) -- combinatorial process part
BEGIN
CASE state_ned IS
WHEN ned_reset =>
next_state_ned <= ned_wt_in_lo;
WHEN ned_wt_in_lo =>
IF w_in = '0' THEN
next_state_ned <= ned_sample_signal;
ELSE
next_state_ned <= ned_wt_in_lo;
END IF;
WHEN ned_sample_signal =>
next_state_ned <= ned_wt_in_hi;
WHEN ned_wt_in_hi =>
IF w_in = '0' THEN
next_state_ned <= ned_wt_in_lo;
ELSE
next_state_ned <= ned_wt_in_hi;
END IF;
END CASE;
END PROCESS sm_ned;
out_sm_ned: PROCESS(clk) -- synchronous process part --
BEGIN
IF (rising_edge(clk)) THEN -- returns only valid transitions;
IF state_ned = ned_sample_signal THEN
-- signal for sampling
w_out <= '1';
ELSE
w_out <= '0';
END IF;
state_ned <= next_state_ned;
END IF;
END PROCESS out_sm_ned;
-- END STATE MACHINES CODE =====
END structure; -- ARCHITECTURE
-- #########################
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
ENTITY fsm_react_test_twb IS
END fsm_react_test_twb;
ARCHITECTURE testbench_arch OF fsm_react_test_twb IS
COMPONENT negedgeDetector
PORT(
clk: IN STD_LOGIC;
p_in : IN STD_LOGIC;
p_out: OUT STD_LOGIC
);
END COMPONENT;
-- 'wires'
SIGNAL wCLK : std_logic := '0';
SIGNAL wIN : std_logic := 'Z';
SIGNAL wOUT : std_logic := 'Z';
-- clock parameters
constant PERIODN : natural := 20; -- can be real := 20.0;
constant PERIOD : time := PERIODN * 1 ns;
constant DUTY_CYCLE : real := 0.5;
constant OFFSET : time := 100 ns;
-- implementation of workbench
BEGIN
-- instances of components, and their wiring (port maps)...
UUT : negedgeDetector -- VHDL
PORT MAP(
clk => wCLK,
p_in => wIN,
p_out => wOUT
);
-- PROCESSES (STATE MACHINES) CODE =========
-- clock process for generating CLK
clocker: PROCESS
BEGIN
WAIT for OFFSET;
CLOCK_LOOP : LOOP
wCLK <= '0';
WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
wCLK <= '1';
WAIT FOR (PERIOD * DUTY_CYCLE);
END LOOP CLOCK_LOOP;
END PROCESS clocker;
simulator: PROCESS
BEGIN
WAIT for OFFSET;
WAIT for 10 ns;
-- take 'in' low - out should detect it with a pulse
wIN <= '0';
WAIT for 50 ns;
-- take 'in' high - no out
wIN <= '1';
WAIT for 50 ns;
-- repeat
wIN <= '0';
WAIT for 50 ns;
wIN <= '1';
WAIT for 50 ns;
-- hold
WAIT;
END PROCESS simulator;
-- END PROCESSES (STATE MACHINES) CODE =====
END testbench_arch; -- ARCHITECTURE
-----------------------
-- call with (Xilinx ISE WebPack 13.2 tools):
-- # note: -tclbatch (isim script) _needs_ -view (*.wcfg) to run! (empty *.wcfg ok)
-- # must use isim script to run at start (and setup view)..
-- # first run:
-- echo 'vhdl work "fsm_react_test_twb.vhd"' > fsm_react_test_twb.prj
-- touch fsm_react_test_twb.wcfg
-- echo -e "wave add {/fsm_react_test_twb/wclk}\nwave add {/fsm_react_test_twb/win}\nwave add {/fsm_react_test_twb/wout}\nwave add {/fsm_react_test_twb/UUT/state_ned}\nwave add {/fsm_react_test_twb/UUT/next_state_ned}\nrun 500 ns\n" > fsm_react_test_twb.isim
-- # build sim and run:
-- fuse -o fsm_react_test_twb.exe -prj fsm_react_test_twb.prj work.fsm_react_test_twb
-- ./fsm_react_test_twb.exe -gui -tclbatch fsm_react_test_twb.isim -view fsm_react_test_twb.wcfg
--文件:fsm\u react\u test\u twb.vhd
---------------
--单文件测试台示例-另请参见;
-- http://www.cs.umbc.edu/portal/help/VHDL/samples/samples.shtml
图书馆IEEE;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.ALL;
--切勿将端口引脚称为“in”;“out”:错误:HDLCompiler:806“in”附近的语法错误!
实体NegatedgeDetector为
港口(
clk:标准逻辑中;
p_in:in标准逻辑;
p_out:输出标准逻辑
);
端盖检测器;
NegatedgeDetector的体系结构是
--“虚拟信号”-寄存器
信号w_in:STD_逻辑:='Z';
信号w_out:STD_逻辑:='Z';
--密克罗尼西亚联邦
类型states\u ned为--ned:negatedgedetector
(
ned_重置,
ned_wt_in_lo,--在低电平有效时等待
ned_采样信号,--采样信号
ned_wt_in_hi——在活动hi中等待
);
--初始化fsm状态变量
信号状态,下一个状态:状态:=复位;
--实施:
开始
--分配'wire'/寄存器
在中,问题是您正在同步进程中检查状态的值。即,在下一个上升时钟边缘之前,输出不会改变
如果要保持输出同步,必须检查下一状态的值,例如:
out_sm_ned: PROCESS(clk) -- synchronous process part --
BEGIN
IF (rising_edge(clk)) THEN -- returns only valid transitions;
IF next_state_ned = ned_sample_signal THEN
-- signal for sampling
w_out <= '1';
ELSE
w_out <= '0';
END IF;
state_ned <= next_state_ned;
END IF;
END PROCESS out_sm_ned;
out\u sm\n ned:进程(clk)——同步进程部分--
开始
如果(上升沿(clk)),那么——只返回有效的转换;
如果next\u state\u ned=ned\u sample\u信号,则
--采样信号
我认为这里不需要状态机。我的方法是使用单触发器和与门:
proc_reg: process (clk,reset)
begin
if reset = RESET_ACTIVE_LEVEL then
q_r0 <= '0';
elsif clk'event and clk = '1' then
q_r0 <= p_in;
end if;
end process proc_reg;
p_out <= '1' when p_in = '0' and q_r0 = '1' else '0';
proc_reg:进程(时钟,复位)
开始
如果重置=重置激活水平,则
你可能想用VHDL在谷歌上搜索“时间表”这个词。您计划在下一个时钟上显示输出值(好吧,灵敏度列表中的下一个信号变化)。非常感谢@AaronD.Marasco-一定会读到的!干杯