2

よし、altera DE2 FPGA ボードで使用するキーボード コントローラーを実装しようとしていますが、いくつか問題があります。このコードを quartus シミュレーターで実行しましたが、すべてが実行されるべきだと思うことを実行しているようです。ただし、FPGA にプログラムしようとすると、何も機能しません。私は ps/2 クロックをシミュレートしている方法にターゲットを絞っていますが、システム クロックは実際に実行されているようには見えません。

システム クロックを 50 MHz、20 ns 周期でシミュレートし、ps2clock を 90 ns 周期でシミュレートしました。ps2data をシミュレーション全体でランダムな値に設定すると、正しいビットが 8 ビット スキャン コードにロードされます。問題は、ボードにプログラムされると、ステート マシンが決してアイドル状態を離れないことです。ステート マシンは、データ ビットが 0 のときに ps2 クロックの立ち下がりエッジでアイドル状態を終了する必要がありますが、これは決して起こらないようです。ps2data および ps2clock ピンを正しい入力に接続していますが、問題を特定できないようです。

これをテストする最上位のエンティティは追加しませんでしたが、単純に出力 keyCode を取得して、7seg ディスプレイの 1 つに送信します。これに対する答えは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;
4

2 に答える 2

1

少し後でこれに答えるために戻ってきます....

これが機能しなかった理由は、元の ps2 コネクタ キーボードではなく、usb -> ps2 アダプタを使用していたためであることがわかりました。

于 2016-08-30T21:24:16.977 に答える
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;

また、state_machine プロセスで clk を使用する必要があります

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

クロック分周器 (divided_clock プロセス) を使用する場合は、イネーブル信号を生成し (実際に行ったように) 、クロックを同期したに使用することができます (例: ステート マシン)。

于 2013-03-26T07:10:08.907 に答える