Я установил связь между клавиатурой USB HID и Nexys 4 ddr. Мне удалось вывести буквы, которые я нажимаю (путем их декодирования и перекодирования в буквы, которые я хочу вывести), однако я хочу сделать еще один шаг вперед и сделать так, чтобы при нажатии двух букв у меня был вывод "000000AB ", для другой введенной буквы" 00000ABC "и т. д.
Я попытался реализовать эту идею, используя вектор, который я сдвигаю, когда мой флаг (конечный бит от передачи данных) равен 1 (означает, что передача завершилась) и кодирую анод. Однако мой вывод остается прежним, весь сегмент отображает одну и ту же букву.
Мой ps2receiver.
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PS2Receiver is
Port ( clk : in STD_LOGIC;
kclk : in STD_LOGIC;
kdata : in STD_LOGIC;
outData : out STD_LOGIC_VECTOR (31 downto 0);
flg: out std_logic);
end PS2Receiver;
architecture Behavioral of PS2Receiver is
signal kclkf: std_logic;
signal kdataf: std_logic;
signal datacur: std_logic_vector(7 downto 0);
signal dataprev: std_logic_vector(7 downto 0);
signal cnt: std_logic_vector(3 downto 0):="0000";
signal keycode: std_logic_vector(31 downto 0):= (Others => '0');
signal flag: std_logic:='0';
component debouncer is
port(CLK: in std_logic;
I0: in std_logic;
I1: in std_logic;
O0: out std_logic;
O1:out std_logic );
end component;
begin
Deb: debouncer port map(clk=>clk,I0=>kclk,I1=>kdata,O0=>kclkf,O1=>kdataf);
--process(clk)
--begin
-- if falling_edge(kclkf) then
-- case cnt is
-- when "0000" => null ; --do nothing is the starting bit--0
-- when "0001" => datacur<="0000000" & kdataf;--1
-- when "0010" => datacur<="000000" & kdataf &"0";--2
-- when "0011" => datacur<="00000" & kdataf & "00";--3
-- when "0100" => datacur<="0000" & kdataf & "000";--4
-- when "0101" => datacur<="000" & kdataf & "0000";--5
-- when "0110" => datacur<="00" & kdataf & "00000";--6
-- when "0111" => datacur<="0" & kdataf & "000000";--7
--- when "1000" => datacur<= kdataf & "0000000";--8
-- when "1001" => flag<='1';--9
-- when "1010" => flag<='0';--10
-- when others=> NULL;
-- end case;-
-- if(cnt <= 9) then cnt<= cnt+1;
-- elsif cnt=10 then cnt<=(Others => '0');
-- end if;
-- end if;
--end process;
process(clk)
begin
if falling_edge(kclkf) then
case cnt is
when "0000" => null ; --do nothing is the starting bit--0
when "0001" => datacur<=datacur(7 downto 1) & kdataf;--1
when "0010" => datacur<=datacur(7 downto 2) & kdataf & datacur(0);--2
when "0011" => datacur<=datacur(7 downto 3) & kdataf & datacur(1 downto 0);--3
when "0100" => datacur<=datacur(7 downto 4) & kdataf & datacur(2 downto 0);--4
when "0101" => datacur<=datacur(7 downto 5) & kdataf & datacur(3 downto 0);---5
when "0110" => datacur<=datacur(7 downto 6) & kdataf & datacur(4 downto 0);--6
when "0111" => datacur<=datacur(7) & kdataf & datacur(5 downto 0);--7
when "1000" => datacur<= kdataf & datacur(6 downto 0);--8
when "1001" => flag<='1';--9
when "1010" => flag<='0';--10
when others=> NULL;
end case;
if(cnt <= 9) then cnt<= cnt+1;
elsif cnt=10 then cnt<=(Others => '0');
end if;
end if;
end process;
process(flag)
begin
if rising_edge(flag) then
if NOT(dataprev = datacur) then
keycode(31 downto 24)<= keycode(23 downto 16);
keycode(23 downto 16)<= keycode(15 downto 8);
keycode(15 downto 8)<= dataprev;
keycode(7 downto 0)<= datacur;
dataprev<= datacur;
end if;
end if;
end process;
flg<= flag;
outData<=keycode;
end Behavioral;
Моя основная функция
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity top is
Port (
Clk: in std_logic;
Rst: in std_logic;
PS2_clk: in std_logic;
PS2_data: in std_logic;
SEG: out std_logic_vector(7 downto 0);
AN: out std_logic_vector(7 downto 0);
DP: out std_logic;
UART_TXD: out std_logic
);
end top;
architecture Behavioral of top is
signal smallerCLK:std_logic:='0';
signal keycode: std_logic_vector(31 downto 0);
--signal PS2_clk: std_logic;
--signal PS2_data: std_logic;
component PS2RECEIVER is
Port ( clk : in STD_LOGIC;
kclk : in STD_LOGIC;
kdata : in STD_LOGIC;
outData : out STD_LOGIC_VECTOR (31 downto 0);
flg: out std_logic);
end component;
component DCD is
Port (
input: in std_logic_vector(7 downto 0);
CLK: in std_logic;
output: out std_logic_vector(31 downto 0)
);
end component DCD;
signal output: std_logic_vector(31 downto 0);
signal flag: std_logic;
begin
process(clk)
begin
if(rising_edge(clk)) then smallerCLK<=NOT smallerCLK;
end if;
end process;
PS2: PS2RECEIVER port map (smallerCLK,PS2_CLK,PS2_DATA,keycode,flag);
--DC:DCD port map(keycode(7 downto 0),smallerCLK,output);
display: entity WORK.displ7seg
port map(Clk => Clk,
Rst => Rst,
Data => keycode,
An => An,
Seg => Seg,
Dp=>Dp,
flag=> flag);
end Behavioral;
И дисплей:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity displ7seg is
Port ( Clk : in STD_LOGIC;
Rst : in STD_LOGIC;
Data : in STD_LOGIC_VECTOR (31 downto 0); -- datele pentru 8 cifre (cifra 1 din stanga: biti 31..28)
An : out STD_LOGIC_VECTOR (7 downto 0); -- selectia anodului activ
Seg : out STD_LOGIC_VECTOR (7 downto 0); -- selectia catozilor (segmentelor) cifrei active
Dp: out std_logic;
flag: in std_logic);
end displ7seg;
architecture Behavioral of displ7seg is
constant CNT_100HZ : integer := 2**20; -- divizor pentru rata de reimprospatare de ~100 Hz (cu un ceas de 100 MHz)
signal Num : integer range 0 to CNT_100HZ - 1 := 0;
signal NumV : STD_LOGIC_VECTOR (19 downto 0) := (others => '0');
signal LedSel : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
signal Hex : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal AUX : std_logic_vector(7 downto 0);
signal anod : std_logic_vector(7 downto 0);
signal bufferBuffer: std_logic_vector(7 downto 0):="00000000";
signal MUX : std_logic_vector(2 downto 0) := (others => '0');
signal REG1, REG2, REG3, REG4,REG5,REG6,REG7,REG8 : std_logic_vector(7 downto 0) := (others => '1');
SIGNAL registerdisplay: std_logic_vector(31 downto 0):=(others=>'1');
SIGNAL date: std_logic_vector(63 downto 0):=(others=>'0');
--signal vet: std_logic_vector(7 downto 0) of std_logic_vector(7 downto 0);
begin
Dp <='1';
-- Proces pentru divizarea ceasului
divclk: process (Clk)
begin
if (rising_edge(clk)) then
if (Rst = '1') then
Num <= 0;
elsif (Num = CNT_100HZ - 1) then
Num <= 0;
else
Num <= Num + 1;
end if;
end if;
end process;
NumV <= CONV_STD_LOGIC_VECTOR (Num, 20);
LedSel <= NumV (19 downto 17);
-- Selectia anodului activ
Anod <= "11111110" when LedSel = "000" else
"11111101" when LedSel = "001" else
"11111011" when LedSel = "010" else
"11110111" when LedSel = "011" else
"11101111" when LedSel = "100" else
"11011111" when LedSel = "101" else
"10111111" when LedSel = "110" else
"01111111" when LedSel = "111" else
"11111111";
-- Selectia cifrei active
Hex <= Date (7 downto 0) when LedSel = "000" else
Date (15 downto 8) when LedSel = "001" else
Date (23 downto 16) when LedSel = "010" else
Date (31 downto 24) when LedSel = "011" else
Date (39 downto 32) when LedSel = "100" else
Date (47 downto 40) when LedSel = "101" else
Date (55 downto 48) when LedSel = "110" else
Date (63 downto 56) when LedSel = "111" else
"00000000";
-- Activarea/dezactivarea segmentelor cifrei active
process(clk)
begin
case HEX is
----gfedcba----
when "01000101"=> AUX <="11000000"; --0
when "00010110"=> AUX <="11111001"; --1
when "00011110"=> AUX <="10100100"; --2
when "00100110"=> AUX <="10110000"; --3
when "00100101"=> AUX <="10011011"; --4
when "00101110"=> AUX <="10010010"; --5
when "00110110"=> AUX <="10000010"; --6
when "00111101"=> AUX <="11111000"; --7
when "00111110"=> AUX <="10000000"; --8
when "01000110"=> AUX <="10010000"; --9
when "00011100"=> AUX <="10001000"; --A
when "00110010"=> AUX <="10000011"; --b
when "00100001"=> AUX <="11000110"; --C
when "00100011"=> AUX <="10100001"; --d
when "00100100"=> AUX <="10000110"; --E
when "00101011"=> AUX <="10001110"; --F
when "00110100"=> AUX <="10000010"; --G
when "00110011"=> AUX <="10001001"; --H
when "01000011"=> AUX <="11001111"; --I
when "00111011"=> AUX <="11110001"; --J
when "01000010"=> AUX <="10001111"; --K
when "01001011"=> AUX <="11000111"; --L
when "00111010"=> AUX <="11001000"; --M
when "00110001"=> AUX <="10101011"; --N
when "01000100"=> AUX <="11000000"; --O
when "01001101"=> AUX <="10001100"; --P
when "00010101"=> AUX <="10100001"; --Q
when "00101101"=> AUX <="10101111"; --r
when "00011011"=> AUX <="10010010"; --S
when "00101100"=> AUX <="10000111"; --t
when "00111100"=> AUX <="11000001"; --U
when "00101010"=> AUX <="11010101"; --V
when "00011101"=> AUX <="10011001"; --Y
when "00011010"=> AUX <="10100100"; --Z
when "00101001"=> AUX <="01110111"; -- Spaceend case
when others=> NULL;
end case;
end process;
PROCESS(CLK)-
BEGIN
if(rising_edge(clk)) then
if(flag=='1')then
Date (63 downto 56)<=Date(55 downto 48);
Date (55 downto 48) <= Date(47 downto 40);
Date (47 downto 40)<=Date(39 downto 32);
Date (39 downto 32)<= Date(31 downto 24);
Date (31 downto 24)<= Date(23 downto 16);
Date (23 downto 16) <=Date(15 downto 8);
Date (15 downto 8) <= Date(7 downto 0);
Date (7 downto 0) <=data(7 downto 0);
end if;
end if;
END PROCESS;
AN<=aNOD;
Seg<= AUX;
end Behavioral;
На данный момент это: https://imgur.com/a/kgfGnr2
Я хочу, чтобы я мог видеть клавиши, которые я нажимал ранее, и не иметь ту же клавишу на всем экране.
Может кто-нибудь помочь мне разобраться?