簡體   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