PS/2インタフェースについて一通りのことは分かったので、ためしに実装してみることにした。0111111111
XXXX011111
PXXXXXXXX0
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ps2read is
Port ( clk : in std_logic;
reset : in std_logic;
ps2clk : in std_logic;
ps2data : in std_logic;
scancode : out std_logic_vector(7 downto 0));
end ps2read;
architecture Behavioral of ps2read is
signal ps2clk_last1 : std_logic;
signal ps2clk_last2 : std_logic;
signal shift_reg : std_logic_vector(9 downto 0);
Type State_t is (Idle, Shifting);
signal state : State_t;
begin
process(clk, reset)
begin
if(reset = '1') then
state <= Idle;
scancode <= "00000000";
elsif(clk'event and clk = '1') then
ps2clk_last2 <= ps2clk_last1;
ps2clk_last1 <= ps2clk;
if (ps2clk_last2 = '1' and ps2clk_last1 = '0') then -- ps2clk fall edge
case state is
when Idle =>
if (ps2data = '0') then -- start bit has come
state <= Shifting;
shift_reg <= "0111111111";
end if;
when Shifting =>
if (shift_reg(0) = '0' and ps2data = '1') then -- stop bit has come
scancode <= shift_reg(8 downto 1);
state <= Idle;
else
shift_reg <= ps2data & shift_reg(shift_reg'high downto 1);
end if;
when Others =>
state <= Idle;
end case;
end if;
end if;
end process;
end Behavioral;
### Spartan-3 Clock Oscillator:
NET clk LOC=T9; # CLK - 50MHz oscillator
NET reset LOC=M13; # BTN1 (active high)
### Spartan-3 Discrete LEDs:
NET scancode<7> LOC=P11; # LD7 (active high)
NET scancode<6> LOC=P12; # LD6 (active high)
NET scancode<5> LOC=N12; # LD5 (active high)
NET scancode<4> LOC=P13; # LD4 (active high)
NET scancode<3> LOC=N14; # LD3 (active high)
NET scancode<2> LOC=L12; # LD2 (active high)
NET scancode<1> LOC=P14; # LD1 (active high)
NET scancode<0> LOC=K12; # LD0 (active high)
### Spartan-3 PS/2 Port:
NET ps2clk LOC=M16; # PS/2 port clock
NET ps2data LOC=M15; # PS/2 port data
私も趣味で作ってみようと思います。
私はModelSimは単体で使っています。私のブログでやり方を書こうと思っています。