繁体   English   中英

VHDL中的FSM内部计数器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM