2015-09-26 62 views
-1

我試圖設計一個兩位數的計數器,計數在00和99之間以循環的方式向上和向下。然而,無論我嘗試什麼,我都無法使十位數字與第一位數字保持同步。我的成績,現在給我這樣的東西:級聯計數器的十進制數字增量太晚

08 - > 09 - > 00 - > 11 ... 18 - > 19 - > 10 - > 21

21 - > 20 - > 29 - > 18 ... 11 - > 10 - > 19 - > 08

由此看來,第一個數字的溢出延遲達到十位數。我嘗試了幾件事來嘗試解決這個問題。提供任何有利結果的唯一方法是添加一個額外的if語句,以便儘早將溢出狀態發送給一個狀態,但這只是一個表面修復。如果我在第一個數字是8或0的時候停下了計數器,並再次啓動它,我會回到以前的同樣的問題。

我也嘗試製作一個額外的「同步器」模塊,我想也許我可以設置它,所以即使它們不同步,它們也會顯示爲好像它們是同步的,但它沒有改變一切。

我一直在努力解決這個問題超過兩個星期,我在我的智慧結束。

這是我的代碼櫃檯和同步器,如果有人想檢查出來,任何和所有的幫助表示讚賞。

**我使用VHDL,與Vivado 2015.2

計數器模塊爲單個數字編程Zybo Digilent公司董事會,溢出成爲使十年位數。

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use ieee.numeric_std.all; 

entity counter is 
    generic(N  : positive := 4); 
    port(
     AR  : in STD_LOGIC; 
     clk  : in STD_LOGIC; 
     ld  : in STD_LOGIC; 
     en  : in STD_LOGIC; 
     up_dn : in STD_LOGIC; 
     D  : in STD_LOGIC_VECTOR(N - 1 downto 0); 
     overflow : out STD_LOGIC; 
     Q  : out STD_LOGIC_VECTOR(N - 1 downto 0); 
     sync_in : in STD_LOGIC; 
     sync_out : out STD_LOGIC 
    ); 
end counter; 

architecture counter of counter is 
    signal Qt : std_logic_vector(N - 1 downto 0); 
    signal OvrFlw : std_logic; 
    signal sync : std_logic; 

begin 
    process(clk, AR) 
    begin 
     if (AR = '1') then 
      Qt  <= (others => '0'); 
      OvrFlw <= '0'; 
      sync <= sync_in; 
     elsif (clk = '1' and clk'event) then 
      if ld = '1' then 
       Qt <= D; 
       sync <= sync_in; 
      elsif en = '1' then 
       if up_dn = '0' then  -- if counting down 
        if (unsigned(Qt) = 0) then 
         Qt  <= "1001";--(others => '1'); 
         OvrFlw <= '1'; 
         sync <= sync_in and en; 
        --elsif (unsigned(Qt) = 1) then 
        -- Qt  <= std_logic_vector(unsigned(Qt) - 1); 
        -- OvrFlw <= '1'; 
        else 
         Qt  <= std_logic_vector(unsigned(Qt) - 1); 
         OvrFlw <= '0'; 
         sync <= sync_in and en; 
        end if; 
       else     -- if counting up 
        if (unsigned(Qt) = 2**N-7) then 
         Qt  <= (others => '0'); 
         OvrFlw <= '1'; 
         sync <= sync_in and en; 
        --elsif (unsigned(Qt) = 2**N-8) then 
        -- Qt  <= std_logic_vector(unsigned(Qt) + 1); 
        -- OvrFlw <= '1'; 
        else 
         Qt  <= std_logic_vector(unsigned(Qt) + 1); 
         OvrFlw <= '0'; 
         sync <= sync_in and en; 
        end if; 
       end if; 
      end if; 
     end if; 
    end process; 

    sync_out <= sync; 
    Q <= Qt; 
    overflow <= OvrFlw; 
end counter; 

下面是我試圖放在一起的同步器的代碼。不知道它是否真的相關,但我想我會把它放在以防萬一。

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity Synchronizer is 
    generic(N  : positive := 4); 
    Port ( 
      MSB_Sync : in STD_LOGIC; 
      LSB_Sync : in STD_LOGIC; 
      MSB_Q : in STD_LOGIC_VECTOR(N-1 downto 0); 
      LSB_Q : in STD_LOGIC_VECTOR(N-1 downto 0); 
      MSB_Out : out STD_LOGIC_VECTOR(N-1 downto 0); 
      LSB_Out : out STD_LOGIC_VECTOR(N-1 downto 0)); 
end Synchronizer; 

architecture Behavioral of Synchronizer is 

begin 
process (MSB_Sync, LSB_Sync) 
    begin 
    if ((MSB_Sync and LSB_Sync) = '1') then 
     MSB_Out <= MSB_Q; 
     LSB_Out <= LSB_Q; 
    end if; 
end process; 

end Behavioral; 
+1

什麼是if(無符號(Qt)= 2 ** N-7)那麼當N設置爲4以外時,應該這樣做? –

回答

0

您已經導致同步的東西表觀基本的問題是你的「溢出」信號被註冊,它的if語句在時鐘上升沿有條件的發現任務。

我甩同步的東西,並在下面的例子中除去溢出寄存器:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity bcd_ud_ctr is 
    port (
     AR:   in std_logic; 
     clk:  in std_logic; 
     ld:   in std_logic; 
     en:   in std_logic; 
     up_dn:  in std_logic; 
     D:   in std_logic_vector (3 downto 0); 
     overflow: out std_logic; 
     Q:   out std_logic_vector (3 downto 0) 
    ); 
end entity; 

architecture off of bcd_ud_ctr is 
    signal Qt:  unsigned (3 downto 0); 
    signal nine: std_logic; 
    signal zero: std_logic; 

begin 
    -- Count recognizers 
    nine <= '1' when Qt = "1001" else 
      '0'; 
    zero <= '1' when Qt = "0000" else 
      '0'; 
COUNT: 
    process (clk, AR) 
    begin 
     if AR = '1' then 
      Qt <= (others => '0'); 
     elsif rising_edge(clk) then 
      if ld = '1' then 
       Qt <= unsigned(D); 
      elsif en = '1' then 
       if up_dn = '0' then -- up 
        if nine = '1' then 
         Qt <= (others => '0'); 
        else 
         Qt <= Qt + 1; 
        end if; 
       else     -- down 
        if zero = '1' then 
         Qt <= "1001"; 
        else 
         Qt <= Qt - 1; 
        end if; 
       end if; 
      end if; 
     end if; 
    end process; 

BUFFERED_OUT:  
    Q <= std_logic_vector(Qt); 

CARRY_BORROW: 
    overflow <= (en and  up_dn and zero) or 
       (en and not up_dn and nine); 
end architecture; 

通知我也與運算使能進入溢流信號,從而它可以被用作使能到下一階段:

library ieee; 
use ieee.std_logic_1164.all; 

entity bcd_2digit_tb is 
end entity; 

architecture foo of bcd_2digit_tb is 
    signal AR:   std_logic; 
    signal clk:   std_logic := '0'; 
    signal ld:   std_logic := '0'; 
    signal en:   std_logic := '0'; 
    signal up_dn:  std_logic := '1'; 
    signal rollover: std_logic; 
    signal Q:   std_logic_vector (7 downto 0); 

    constant DIG_PAR: std_logic_vector(3 downto 0) := "0010"; -- 2 
    constant TEN_PAR: std_logic_vector(3 downto 0) := "0100"; -- 4 (42) 
begin 

CLOCK: 
    process 
    begin 
     wait for 10 ns; 
     clk <= not clk; 
     if Now > 500 ns then 
      wait; 
     end if; 
    end process; 

DIGITS: 
    entity work.bcd_ud_ctr 
     port map (
      AR => AR, 
      clk => clk, 
      ld => ld, 
      en => en, 
      up_Dn => up_dn, 
      D => DIG_PAR, 
      overflow => rollover, 
      Q => Q(3 downto 0) 
     ); 
TENS: 
    entity work.bcd_ud_ctr 
     port map (
      AR => AR, 
      clk => clk, 
      ld => ld, 
      en => rollover, 
      up_Dn => up_dn, 
      D => TEN_PAR, 
      overflow => open, 
      Q => Q(7 downto 4) 
     ); 
STIMULUS: 
    process 
    begin 
     wait for 10 ns; 
     AR <= '1'; 
     wait for 10 ns; 
     AR <= '0'; 
     up_dn <= '0'; -- up 
     en <= '1'; 
     wait for 260 ns; 
     up_dn <= '1'; 
     wait; 
    end process; 
end architecture; 

這給:

bcd_2digit.png (點擊)

雖然這只是簡單地顯示了人的位數翻轉,然後向下計數和在測試平臺下滾動可以擴展。

+0

謝謝!它的工作原理與它應有的一樣!我知道這個問題與時鐘敲擊發生的變化有關,但我無法弄清楚如何解決這個問題。我非常感謝幫助! – sfagin