좋아, 내가 알테라 DE2 FPGA 보드와 함께 사용하기 위해 키보드 컨트롤러를 구현하려고하는데, 몇 가지 문제가 있습니다. quartus 시뮬레이터에서이 코드를 실행했는데 모든 것이 제대로 수행되어야한다고 생각합니다. 그러나 FPGA에 프로그램하려고하면 아무 것도 작동하지 않습니다. 나는 ps/2 클럭을 시뮬레이트하는 방식으로 그것을 목표로 삼았고 시스템 클럭은 실제로 실행되는 방식으로 보이지 않는다.ps/2 키보드 인터페이스 VHDL
나는 시스템 클록을 50MHz, 20ns, 그리고 ps2clock을 90ns로 시뮬레이션했다. 시뮬레이션을 통해 ps2 데이터를 임의의 값으로 설정하면 올바른 비트가 8 비트 스캔 코드로로드됩니다. 문제는 보드에 프로그래밍 할 때 상태 시스템이 유휴 상태를 벗어나지 않는다는 것입니다. 상태 머신은 데이터 비트가 0 일 때 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;