Я должен сделать проект в университете, который представляет собой интерфейс для клавиатуры PS2 с использованием платы FPGA (nexys2). Я пишу код на VHDL, и проблема у меня заключается в том, что где-то в компоненте управления, куда отправляются пакеты из 11 битов, процесс застревает в состоянии GETBYTE3, когда я нажимаю клавишу вместо перехода в состояние START после всех биты принимаются правильно и смещаются в регистр FIFO, он проходит через другое состояние и никогда не попадает в START должным образом. Но когда я сбрасываю его вручную, переключая CLR на 1 после каждого нажатия любой клавиши на клавиатуре, он работает нормально.
Система работает следующим образом: когда код сканирования получен, он перемещается в память FIFO, из которой в другом компоненте декодируется и отображается на 7-сегментном дисплее.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ps2_src is
Port ( PS2C : in STD_LOGIC;
PS2D : in STD_LOGIC;
CLR : in STD_LOGIC;
FIFO : out STD_LOGIC_VECTOR (31 downto 0);
scan : out STD_LOGIC_VECTOR (7 downto 0);
deb : out STD_LOGIC_VECTOR (7 downto 0));
end ps2_src;
architecture Behavioral of ps2_src is
type STATE_TYPE is (START, WCLKLO1, GETBYTE1, WCLKLO2, GETBYTE2, CHECK, WCLKLO3, GETBYTE3);
signal state: STATE_TYPE := START;
signal tfifo: STD_LOGIC_VECTOR(31 downto 0) := X"11111111";
begin
control: process(CLR, PS2C)
variable keyv1_temp, keyv2_temp, keyv3_temp: STD_LOGIC_VECTOR(7 downto 0);
variable shift1, shift2, shift3: STD_LOGIC_VECTOR(10 downto 0);
variable parity: STD_LOGIC;
variable bit_cnt: NATURAL := 0;
begin
if CLR = '1' then
state <= START;
bit_cnt := 0;
elsif PS2C'EVENT and PS2C = '0' then
case state is
when START =>
if PS2D = '0' then
state <= START;
else
state <= WCLKLO1;
end if;
deb <= "00000000";
when WCLKLO1 =>
shift1 := PS2D & shift1(10 downto 1);
bit_cnt := bit_cnt + 1;
if (bit_cnt = 11) then
state <= GETBYTE1;
end if;
deb <= "00000010";
when GETBYTE1 =>
keyv1_temp := shift1(8 downto 1);
parity := keyv1_temp(0) xor keyv1_temp(1) xor keyv1_temp(2) xor keyv1_temp(3) xor keyv1_temp(4) xor keyv1_temp(5) xor keyv1_temp(6) xor keyv1_temp(7);
bit_cnt := 0;
state <= WCLKLO2;
deb <= "00000100";
when WCLKLO2 =>
shift2 := PS2D & shift2(10 downto 1);
bit_cnt := bit_cnt + 1;
if (bit_cnt = 11) then
state <= GETBYTE2;
end if;
deb <= "00001000";
when GETBYTE2 =>
keyv2_temp := shift2(8 downto 1);
bit_cnt := 0;
state <= CHECK;
scan <= keyv2_temp;
deb <= "00010000";
when CHECK =>
if keyv2_temp = X"F8" then
deb <= "00100000";
state <= WCLKLO3;
tfifo <= tfifo(23 downto 0) & keyv1_temp;
else
if keyv1_temp = X"E0" then
deb <= "01000000";
state <= WCLKLO1;
tfifo <= tfifo(23 downto 0) & keyv2_temp;
else
deb <= "10000000";
state <= WCLKLO2;
tfifo <= tfifo(23 downto 0) & keyv1_temp;
end if;
end if;
when WCLKLO3 =>
shift3 := PS2D & shift2(10 downto 1);
bit_cnt := bit_cnt + 1;
if (bit_cnt = 11) then
state <= GETBYTE3;
end if;
deb <= "11000000";
when GETBYTE3 => keyv3_temp := shift3(8 downto 1);
bit_cnt := 0;
state <= START;
deb <= "10100000";
end case;
end if;
end process control;
FIFO <= tfifo;
end Behavioral;