2014-12-23 57 views
0

接下來的ssd過程就是向我展示我對這兩個用戶所擁有的東西。代碼ATM似乎很好地存儲了這兩個用戶的數據,並且在任何給定的時間內都可以記住它。然而,問題是,我似乎無法改變這樣一個事實,即只要按下其中一個按鈕,就可以通過小數點1-來增加或減少兩位用戶的數字。無論如何,它都會更改第一個用戶的號碼。開關(7)是「1」還是「0」並不重要。另外,我可以選擇第二個用戶,但我也不能對他進行任何更改 - 這些按鈕隻影響第一個用戶。這是我的問題,我不知道爲什麼發生這種情況,但我唯一的直覺是,我在這裏有一個可怕的設計。反正下面是感興趣的和有用的代碼:VHDL one如果在每種情況下都是成立的,另一個不是

process (clk) 

begin 

    if(switch(7) <= '1') then --first user 

     if(rising_edge(clk)) then 
      if(btn(0)='1' and lastButtonState(0) = '0') then--increase by 1 
       user0 <= user0 + "001"; 
      end if; 
      lastButtonState(0) <= btn(0); 
      if(btn(1) = '1' and lastButtonState(1) = '0') then --decrease by 1 
       user0 <= user0 + "111"; 
      end if; 
      lastButtonState(1) <= btn(1); 
     end if; 



    elsif (switch(6) = '1') then --second user 
     if(rising_edge(clk)) then 
      if(btn(0) = '1' and lastButtonState(0) = '0') then 
       user1 <= user1 + "001"; 
      end if; 
     lastButtonState(0) <= btn(0); 

      if(btn(1) = '1' and lastButtonState(1) = '0') then 

       user1 <= user1 + "111"; 

      end if; 
      lastButtonState(1) <= btn(1); 
     end if; 


    end if; 


end process; 
process (user0, user1, switch) 
begin 

    if(switch(7) = '1') then 
     case user0 is 
      when "000" => a_to_g <= "0000001"; 
      when "001" => a_to_g <= "1001111"; 
      when "010" => a_to_g <= "0010010"; 
      when "011" => a_to_g <= "0000110"; 
      when "100" => a_to_g <= "1001100"; 
      when "101" => a_to_g <= "0100100"; 
      when "110" => a_to_g <= "0100000"; 
      when others => a_to_g <= "0001111"; 
     end case; 


    elsif (switch(6) = '1') then 
     case user1 is 
      when "000" => a_to_g <= "0000001"; 
      when "001" => a_to_g <= "1001111"; 
      when "010" => a_to_g <= "0010010"; 
      when "011" => a_to_g <= "0000110"; 
      when "100" => a_to_g <= "1001100"; 
      when "101" => a_to_g <= "0100100"; 
      when "110" => a_to_g <= "0100000"; 
      when others => a_to_g <= "0001111"; 
     end case; 

    end if; 
end process; 
+1

該代碼有幾個問題。然而,目前造成麻煩的具體問題可能是您實際上並不測試開關7 =「1」。小於或等於,是的。等於,不。 –

+0

什麼是ssd進程?固態硬盤還是七段顯示器?請不要使用非常用的縮寫。 – Paebbels

+0

您也可以用VHDL標記任何語句,包括進程語句。哪兩個過程被認爲是ssd?什麼是'代碼atm'?您的兩個進程不包含[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)。 – user1155120

回答

1

一些提示了這段代碼:

  • 你的代碼描述了門控時鐘 - 這是沒有良好的編碼風格!
    把所有東西放在if rising_edge() then(異常:異步復位)
  • 您可以刪除一個7段。解碼器模塊,如果您將您的第二個過程,多路複用器和解碼器:

    process (user0, user1, switch) 
        variable temp : std_logic_vector(2 downto 0); 
    begin 
        if(switch(7) = '1') then 
        temp := user0; 
        elsif (switch(6) = '1') then 
        temp := user1; 
        else 
        temp := "000"; 
        end if; 
    
        case temp is 
        when "000" => a_to_g <= "0000001"; 
        when "001" => a_to_g <= "1001111"; 
        when "010" => a_to_g <= "0010010"; 
        when "011" => a_to_g <= "0000110"; 
        when "100" => a_to_g <= "1001100"; 
        when "101" => a_to_g <= "0100100"; 
        when "110" => a_to_g <= "0100000"; 
        when others => a_to_g <= "0001111"; 
        end case; 
    end process; 
    
  • 我會建議以提取您的按鈕信號的上升沿檢測從你的主要過程。邊緣檢測是一個信號預處理步驟,應與控制邏輯分離。如果您正在進行邊緣檢測:您是否同步並消除了信號?

    -- edge detection in 2 lines 
    btn_d <= btn when rising_edge(clk); -- delay (*_d) all button signals for one cycle 
    btn_re <= not btn_d and btn;   -- calculate rising edge (*_re) strobe signal for every button 
    
  • 爲什麼不使用減號運算符來減1而不是加-1?

編輯1關於評論1:

我想你使用的是標準制定板配備有(推)按鈕和(滑動/ DIP)開關。首先,每個外部異步信號必須與設計的內部時鐘同步,以防止元穩定性問題。這通常通過實現一個雙觸發器同步器(2個D-FF作爲一個鏈,沒有移位寄存器)來完成。

-- example for a Xilinx ML505 board 
port map (
    -- ... 
    ML505_GPIO_Button_CPU_Reset_n : in STD_LOGIC; 
    ML505_GPIO_Button_West   : in STD_LOGIC; 
    ML505_GPIO_Button_East   : in STD_LOGIC; 
    ML505_GPIO_Switches   : in STD_LOGIC_VECTOR(7 downto 0); 
); 

-- signals 
architecture ... 
    -- signals to convert low-active signals to high-active 
    signal ML505_GPIO_Button_Reset : STD_LOGIC; 

    -- signals for double synchronization 
    signal GPIO_Buttons_async : STD_LOGIC_VECTOR(2 downto 0); 
    signal GPIO_Buttons_meta  : STD_LOGIC_VECTOR(2 downto 0) := (others => '0'); 
    signal GPIO_Buttons_sync  : STD_LOGIC_VECTOR(2 downto 0) := (others => '0'); 
    signal GPIO_Buttons   : STD_LOGIC_VECTOR(2 downto 0); 
    signal GPIO_Buttons_d  : STD_LOGIC_VECTOR(2 downto 0) := (others => '0'); 
    signal GPIO_Buttons_re  : STD_LOGIC_VECTOR(2 downto 0); 

    signal GPIO_Switches_async : STD_LOGIC_VECTOR(7 downto 0); 
    signal GPIO_Switches_meta : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); 
    signal GPIO_Switches_sync : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); 

-- ... 
begin 
    -- source code to pre process external signals 
    -- ============================================= 
    -- convert low-active signals to high-active 
    ML505_GPIO_Button_Reset <= ML505_GPIO_Button_Reset_n; 

    -- input synchronization 
    GPIO_Buttons_async(0) <= ML505_GPIO_Button_Reset; 
    GPIO_Buttons_async(1) <= ML505_GPIO_Button_West; 
    GPIO_Buttons_async(2) <= ML505_GPIO_Button_East; 
    GPIO_Switches_async <= ML505_GPIO_Switches; 

    -- double FF synchronizer 
    GPIO_Buttons_meta <= GPIO_Buttons_async when rising_edge(Clock); 
    GPIO_Switches_meta <= GPIO_Switches_async when rising_edge(Clock); 

    GPIO_Buttons_sync <= GPIO_Buttons_meta when rising_edge(Clock); 
    GPIO_Switches_sync <= GPIO_Switches_meta when rising_edge(Clock); 

下一步是去抖動信號,因爲許多電路板不使用回跳部件(這可以被機械地進行,通過簡單的電容器或一外部反跳電路)。所以如果你不確定或者你的電路板沒有消除用戶輸入信號,你必須自己實現一個特定的電路。揭示出來,你的信號至少在去抖持續時間內是穩定的。這個時間可以是5毫秒。

deb1 : entity PoC.io_Debounce 
    generic map (
    ports => 3 
) 
    port map (
    Clock => Clock, 
    Input => GPIO_Buttons_sync, 
    Output => GPIO_Buttons 
); 

去抖動電路只是一個抑制毛刺的濾波器。結果是'旗'信號(長期高或低)。

在大多數情況下,用戶輸入被饋入FSM或其他東西。這些電路需要選通信號(高有效邏輯:一個週期的高脈衝)。這種「轉換」可以通過邊沿檢測(上升或下降)完成。

-- edge detection 
GPIO_Buttons_d <= GPIO_Buttons when rising_edge(Clock); 
GPIO_Buttons_re <= not GPIO_Buttons_d and GPIO_Buttons; 

-- final renaming after pre processing 
GPIO_Button_Reset <= GPIO_Buttons_re(0); 
GPIO_Button_West <= GPIO_Buttons_re(2); 
GPIO_Button_East <= GPIO_Buttons_re(1); 

現在你可以在你的電路中使用預處理信號。

附錄:

a_d <= a when rising_edge(Clock);爲不使能和復位一個簡單的d-FF的簡寫形式。或者,您可以使用標準流程。行a_re <= not a_d and a;是一個檢查a是零,現在是一個 - >上升沿條件。有關單線拖鞋的更多詳細信息,請參閱其他帖子。 LINK

+0

關於7-seg的想法。太棒了!我沒有想到這一點。我一定會執行它。 雖然我有一個問題。你能詳細解釋一下「從我的主進程中提取按鈕信號的上升沿檢測」,因爲我不明白你寫的按鈕代碼和反彈,因爲按鈕的工作原理是這樣的嗎? – royalgobbal

+0

@Briandrummond我不認爲我明白你的觀點。不是這個條款-if(開關(7)='1')然後檢查開關(7)是否打開或關閉?如果它是1,那麼它繼續執行下面的代碼。我錯了嗎?爲了澄清我的問題,無論開關(7)的輸入如何,開關(7)都執行下面的代碼,令人驚訝的是,我對第二個用戶 - 開關(6)具有完全相同的編碼 - 這不起作用。 – royalgobbal

+0

@royalgobbal:「不是這個子句-if(開關(7)='1')然後檢查開關(7)是否打開或關閉?」是。但是你的問題中的代碼是不同的。 –

相關問題