我的有限状态机遇到了一个小问题 最近用VHDL编写。我试图创造“智能”计数器 由频率为2 Hz的时钟触发。 此计数器构建在一个FSM状态,并通过按a启动 DE2板上的按钮。
首先,整个系统处于IDLE状态,如果按下此按钮,状态为 改为COUNTING,计数器开始增加和他的当前 值显示在LED显示屏上。在达到模数值后,状态 COUNTING返回IDLE,计数器设置为零。
我的问题是计数器无法正常工作 - 计数 价值太大了。所以我尝试用这种结构解决它:如果 (clk_tick'event和clk_tick = 1)然后....,有一些错误 合成: 错误(10822):Citac_FSM.vhd(57)的HDL错误:无法实现 寄存器用于此时钟边沿的分配
错误(10821):Citac_FSM.vhd(62)处的HDL错误:无法推断注册 “AUTOMAT:flg”因为它的行为与任何支持的寄存器都不匹配 模型
拜托,有人有想法解决它吗?什么是正确的方式 用两个(或更多)时钟源写时钟触发的FSM?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
ENTITY Counter_FSM IS
GENERIC (
REGSIZE : integer := 8; -- range of counter
MODULO : natural := 50 -- modulo value
);
PORT (
CLK : IN STD_LOGIC; -- puls 50 MHz
CLK_tick : IN STD_LOGIC; -- puls 2 Hz
RESET : IN STD_LOGIC; -- reset
READY : OUT STD_LOGIC; -- counter is ready to start
START_C : IN STD_LOGIC; -- start of counting
DOUT : OUT STD_LOGIC_VECTOR(REGSIZE - 1 downto 0) --out
);
END Counter_FSM;
ARCHITECTURE Behavior OF Counter_FSM is
type counterState is (IDLE, COUNTING); -- states of FSM
signal currCounterState : counterState; -- current state
signal nextCounterState : counterState; -- next state
signal cnt : std_logic_vector(REGSIZE - 1 downto 0); -- counter
begin
UPDATE: process(RESET, CLK)
begin
if (RESET = '0') then
currCounterState <= IDLE;
elsif (CLK'event and CLK = '1') then
currCounterState <= nextCounterState;
end if;
end process;
COMBI: process (clk_tick, start_c, currCounterState)
variable flg : std_logic := '0';
begin
if (clk_tick'event and clk_tick = '1') then
flg := '1';
end if;
case currCounterState is
when IDLE =>
cnt <= (others => '0'); -- counter value = zero
READY <= '1'; -- we can start
if (start_c = '1') then -- if button is pushed
nextCounterState <= COUNTING; -- go to COUNTING
end if;
when COUNTING =>
READY <= '0';
if (flg = '1') then -- Was there impuls of 2 Hz?
cnt <= cnt + 1; -- yes -> incrementing
flg := '0';
if (cnt = MODULO) then -- if cnt = MODULO
cnt <= (others => '0'); -- then cnt = zero
nextCounterState <= IDLE;
end if;
end if;
when others =>
nextCounterState <= IDLE;
end case;
-- OUTPUT
douT <= cnt;
end process;
end Behavior;
非常感谢。
米雷克
P.S。:对不起,我的英语不太好。
答案 0 :(得分:0)
首先,你不应该使用clk_tick作为第二个时钟信号。 您应该做的是保存clk_tick的先前值,然后将clk_tick的当前值与先前的值进行比较以检测冲洗边缘。根据clk_tick的生成方式,您可能需要将clk_tick与CLK的时钟域同步。
你可以这样写:
when COUNTING =>
nextCounterState <= COUNTING;
READY <= '0';
if (prev_clk_tick = '0' and clk_tick = '1') then
next_cnt <= cnt + 1; -- yes -> incrementing
if (cnt = MODULO) then
next_cnt <= (others => '0');
nextCounterState <= IDLE;
end if;
end if;
我会留给你添加额外的寄存器。
答案 1 :(得分:0)
我已经解决了我的问题:-)。我已经将计数器移动到单独的过程中,然后将女巫信号附加到FSM。所以,它运作良好。
通过阅读按钮,我正在使用两个D触发器来同步它。
我必须对VHDL编程的风格进行观察 - 它与C语言的“普通”编程有太大不同:-D
美好的一天!