2013-03-25 205 views
2

好吧,所以我試圖實現鍵盤控制器與altera DE2 FPGA板一起使用,並遇到一些問題。我已經在quartus模擬器中運行了這些代碼,並且一切似乎都在做我認爲應該做的事情。但是,當我嘗試將其編程到FPGA上時,沒有任何工作。我將其目標鎖定在我模擬ps/2時鐘的方式,而系統時鐘看起來並不像它們實際運行的方式。ps/2鍵盤接口VHDL

我模擬了系統時鐘在50 mhz,20ns週期和ps2clock週期爲90ns。當將ps2data設置爲整個仿真中的隨機值時,正確的位被加載到8位掃描代碼中。問題在於,當編程到板上時,狀態機永遠不會離開空閒狀態。當數據位爲零時,狀態機應在ps2時鐘的下降沿保持空閒狀態,這似乎永遠不會發生。我有ps2data和ps2clock引腳連接到正確的輸入,但似乎無法找出問題。

我沒有添加測試此功能的頂級實體,但它只是輸出keyCode並將其發送到7seg顯示中的一個。我覺得這個答案與ps2clock有關,我只是不確定究竟是什麼。

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity keyboard is 
    Port (Clk   : in std_logic; --system clock 
      ps2Clk  : in std_logic; --keyboard clock 
      ps2Data  : in std_logic; --keyboard data 
      reset  : in std_logic; --system reset 
      keyReady  : out std_logic; 
      DoRead  : in std_logic; -- when to read 
      keyCode  : out std_logic_vector(7 downto 0); 
      pFalling  : out std_logic; --debugging 
      pFixedClk : out std_logic_vector(1 downto 0); --debugging 
      divClock_out : out std_logic; --debugging 
      clockCount_out : out std_logic_vector(9 downto 0); --debugging 
      testDiv_out  : out std_logic; 
      bitCount_out : out std_logic_vector(3 downto 0); 
      shiftIn_out : out std_logic_vector(8 downto 0)); --debugging 
end keyboard; 

architecture Behavioral of keyboard is 

component div_counter is 
    Port(clk, reset : in std_logic; 
       Q : out std_logic_vector(9 downto 0)); 
end component div_counter; 

signal shiftIn    : std_logic_vector(8 downto 0); -- shifted in data 
signal ps2fixedClock  : std_logic_vector(1 downto 0); -- 2 bit shift register 
signal divClock    : std_logic ; -- main clock/512 
signal clockCount   : std_logic_vector(9 downto 0); -- debugging 
signal ps2falling   : std_logic ; 
signal bitCount    : std_logic_vector(3 downto 0); 
signal keyReady_sig   : std_logic; 

type state_type is (idle, shift, ready); 
signal state : state_type; 
begin 

keyReady <= keyReady_sig; 

------------------------------- 
--- counter to divide the main clock by 512 
------------------------------- 
counter : div_counter 
    Port map(clk => Clk, 
      reset => reset, 
       Q => clockCount); 

clockCount_out <= clockCount;    
divided_clock : process (clockCount) 
begin 
    if clockCount = "1000000001" then 
     divClock <= '1'; 
    else 
     divClock <= '0'; 
    end if; 
end process divided_clock;     

testDiv_out <= divClock; 
------------------------------------ 
------ 2 bit shift register to sync clocks 
------------------------------------ 
ps2fixed_Clock : process (reset, divClock) 
begin 
    if reset = '1' then 
     ps2fixedClock <= "00"; 
    elsif (divClock'event and divClock = '1') then 
     ps2fixedClock(0) <= ps2fixedClock(1); 
     ps2fixedClock(1) <= ps2Clk; 
    end if; 
end process ps2fixed_Clock; 

pFixedClk <= ps2fixedClock; 
----------------------------------- 
-------- edge detector 
----------------------------------- 
process (ps2fixedClock) 
begin 
    if ps2fixedClock = "01" then 
     ps2falling <= '1'; 
     else 
     ps2falling <= '0'; 
    end if; 
end process; 

pFalling <= ps2falling; 
bitCount_out <= bitCount; 

-------------------------------- 
------- state machine 
-------------------------------- 
state_machine : process (divClock, reset) 
begin 
    if (reset = '1') then 
     state <= idle; 
     bitCount <= "0000"; 
     shiftIn <= (others => '0'); 
     keyCode <= (others => '0'); 
     keyReady_sig <= '0'; 
    elsif (divClock'event AND divClock = '1') then 

     if DoRead='1' then 
      keyReady_sig <= '0'; 
     end if; 

     case state is 
     when idle => 
      bitCount <= "0100"; 
      if ps2falling = '1' and ps2Data = '0' then 
       state <= shift; 
      end if;   
     when shift => 
       if bitCount >= 9 then 
        if ps2falling = '1' then -- stop bit 
         keyReady_sig <= '1'; 
         keyCode <= shiftIn(7 downto 0); 
         state <= idle; 
        end if; 
       elsif ps2falling='1' then 
        bitCount <= bitCount + 1; 
        shiftIn(7 downto 0) <= shiftIn(8 downto 1); 
        shiftIn(8) <= ps2Data; 
       end if; 
     when others => 
      state <= idle; 
    end case; 
    end if; 
end process;  

shiftIn_out <= shiftIn; 
end Behavioral; 

回答

0

您嘗試將ps2clock同步到您的divClock。然而,divClock是一個使能信號而不是時鐘。它並不經常活躍。

我建議你在ps2fixed_Clock過程中使用CLK

ps2fixed_Clock : process (reset, clk) 
begin 
    if reset = '1' then 
     ps2fixedClock <= "00"; 
    elsif (rising_edge(clk)) then 
     ps2fixedClock(0) <= ps2fixedClock(1); 
     ps2fixedClock(1) <= ps2Clk; 
    end if; 
end process ps2fixed_Clock; 

另外,如果你想用一個時鐘分頻器(divided_clock過程),你應該在你的state_machine過程

state_machine : process (clk, reset) 
begin 
    if (reset = '1') then 
     ... 
    elsif (rising_edge(clk)) then 
     ... 

使用CLK,你可以生成使能信號(如您所做的那樣),並在之後使用它您同步了時鐘,例如在狀態機中!

1

說回回答這個有點晚....

事實證明爲什麼這是不工作是因爲我使用的是USB的原因 - > PS2適配器,而不是原來的PS2接口鍵盤。