[英]Counter inside FSM in VHDL
我最近用VHDL编写的有限状态机有一个小问题。 我试图创建由频率为2 Hz的时钟触发的“智能”计数器。 该计数器以FSM的一种状态构建,并通过按DE2板上的按钮启动。
首先,整个系统处于“空闲”状态,如果按此按钮,状态将更改为“计数”,计数器开始增加,并且其当前值显示在LED显示屏上。 达到模值后,状态COUNTING退回到IDLE,并将计数器设置为零。
我的问题是计数器无法正常工作-计数值太大。 因此,我尝试使用这种结构来解决它:如果(clk_tick´event和clk_tick = 1)则...。,综合存在一些错误:错误(10822):Citac_FSM.vhd(57)处的HDL错误:无法t在此时钟沿实现寄存器分配
错误(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;
非常感谢你。
米雷克
PS:对不起,我的英语不太好。
首先,您不应将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;
我将留给您添加额外的寄存器。
我已经解决了我的问题:-)。 我将计数器移到单独的过程中,然后将巫婆信号附加到FSM。 因此,它运作良好。
通过读取按钮,我现在使用两个D触发器对其进行同步。
我必须对VHDL编程的样式进行观察-它与“常规”编程(如C语言:-D)太不同了
美好的一天!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.