2011-05-01 46 views
0

我有下面的代碼是我的數字時鐘的一部分:如何使VHDL輸出信號無國籍

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

-- Seconds counter 
entity SecCounter is 
    port( 
      s_enable: in std_logic; 
      s_load: in std_logic; -- When high, sets this counter to the value in the  data inputs 
      s_clk: in std_logic; -- Clock 
      s_input: in std_logic_vector(5 downto 0); -- Data inputs 
      s_output: out std_logic_vector(5 downto 0); --Outputs 
      s_wrap: out std_logic 
     ); 
    end SecCounter; 

architecture imp of SecCounter is 
    -- Intermediate signal to mainpulate the seconds as integer 
    signal sec: integer range 0 to 60 := 22; 

    begin 
     s_output <= std_logic_vector(to_unsigned(sec,6)); -- Assign the input to the binary  value of sec 

     process(s_clk, s_load, s_enable) -- If clk, enable, or load is changed 
     begin 
      s_wrap <= '0'; -- Clear the wrap 

      if (s_enable = '0' and s_load = '1') then -- Set the clock 
       sec <= to_integer(unsigned(s_input)); 
      elsif (s_enable = '1' and rising_edge(s_clk)) then -- Increment the counter 
       sec <= sec + 1; 
      end if; 

      if sec = 60 then -- Restart counter and toggle the next counter 
       sec <= 0; 
       s_wrap <= '1'; 
      end if; 
     end process; 
end imp; 

s_wrap充當使下一個櫃檯。我想要做的是,如果這個計數器等於60,我想爲單個時鐘邊緣啓用下一個計數器。我試圖通過將s_wrap設置爲true,然後在下一個時鐘邊沿將其設置爲false;但是,它不會改變。有沒有辦法讓is_wrap無狀態?如果不是,我該如何解決這個問題?

+0

您正在使用'ieee.std_logic_unsigned .all',這有幾個問題。此外,它與您正在使用的'numeric_std'衝突。只要刪除'std_logic_unsigned'使用條款。 – Philippe 2011-05-02 07:48:29

回答

2

你是秒rising_edge(CLK)條款以外的分配值。如果s_enable = 0且s_load = 0,則不會將任何內容分配給sec。這些事實都使秒成爲異步信號。如果你解決了這兩個問題,那麼描述的問題應該消失。

而奧利查爾斯沃斯有一個關於檢查59而不是60的好處。那麼你不必在你的範圍內人爲地包含不存在的60。並且將sec初始化爲一個值是沒有意義的。您應該在重置條款中初始化它。

由於您正在異步讀取s_enable,s_load和s_input,您可能還有其他問題。這通常只對復位信號完成。

+2

糾正點:信號的初始化**是有意義的**,前提是得到綜合工具的支持。我建議在聲明時初始化信號,不要使用復位,特別是如果不需要復位。這可以在地圖和P&R期間導致更好的邏輯利用率。在Xilinx器件的世界中,在器件配置/引導中,所有FF都有一個已知狀態,可以使用信號初始化進行配置。在此參考中搜索「初始化」:http://www.xilinux.com/support/documentation/sw_manuals/xilinx13_1/xst_v6s6.pdf – Josh 2011-05-02 19:49:16

1

[免責聲明:我不是偉大的VHDL,所以我不能對語法建議]

我想你想斷言s_wrapsec達到,不。這樣,在下一個時鐘邊沿,分鐘計數器將看到s_wrap = 1並遞增,同時該計數器輸出再次變爲0。

你想要的東西,這樣我覺得

process(s_clk, s_load, s_enable) -- If clk, enable, or load is changed 
begin 

    if (s_enable = '0' and s_load = '1') then -- Set the clock 
     sec <= to_integer(unsigned(s_input)); 
    elsif (s_wrap = '1') then -- Wrap 
     sec <= 0; 
    elsif (s_enable = '1' and rising_edge(s_clk)) then -- Increment the counter 
     sec <= sec + 1; 
    end if; 

end process; 

s_wrap <= '1' when sec = 59 else '0'; 
0

我會做的是申報秒作爲過程變量,作爲變量立即更新:

process(s_clk, s_load, s_enable) 
variable v_sec : integer range 0 to 60; 
begin 
if reset = '1' then 
    v_sec := 0; 
    s_sec <= (others => '0'); 
    s_wrap <= '0'; 
elsif rising_edge(s_clk) then 
    s_output <= std_logic_vector(to_unsigned(v_sec,6)); 
    if s_enable = '1' then 
    v_sec := v_sec +1; 
    if v_sec = 60 then 
     v_sec:= 0; 
     s_wrap <= '1'; 
    else 
     s_wrap <= '0'; 
    end if; 
    else 
    s_wrap <= '0'; 
    end if; 
end if; 

如果這個模擬ModelSim中,證券交易委員會將去0,1,2,.. .58,59,0,1,2和s_wrap將等於1,每次秒等於0,除了第一次,當復位條件將其設置爲0.