Программируемая логика - это не так уж и сложно. Разберемся вместе.
Ответить

Необходима помощь с ps/2 клавиатура VHDL

Чт май 16, 2013 11:18:16

Здравствуйте. Я недавно начал изучать VHDL, поэтому испытываю множество трудностей. В данный момент, мне необходимо реализовать ввод с клавиатуры для Altera Cyclone II, модель платы значения, вроде, не имеет. Мне необходимо реализовать только ввод, обрабатывая 17 различных кнопок, но в качестве примера достаточно одной. На форуме нашел только одну тему http://radiokot.ru/forum/viewtopic.php?t=13341, но она оказалось не особо полезна, так как очень много лишнего кода и я не смог понять, где и как обрабатывается считанная клавиша. На других ресурсах находил что-то немного похожее, но не смог в этом разобраться. Не поможете примерами кода, желательно с комментариями?

Вот с чем я сейчас пытаюсь разобраться:
Спойлер
Код:
LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY key IS
   PORT(   keyboard_clk, keyboard_data, clock_25Mhz ,
         reset, read      : IN STD_LOGIC;
         scan_code      : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
         scan_ready      : OUT STD_LOGIC);
END key;

ARCHITECTURE a OF key IS
SIGNAL INCNT                     : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL SHIFTIN                     : STD_LOGIC_VECTOR(8 downto 0);
SIGNAL READ_CHAR                  : STD_LOGIC;
SIGNAL INFLAG, ready_set          : STD_LOGIC;
SIGNAL keyboard_clk_filtered       : STD_LOGIC;
SIGNAL filter                    : STD_LOGIC_VECTOR(7 downto 0);
SIGNAL lower_code_buf            : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL high_code_buf            : STD_LOGIC_VECTOR(3 downto 0);      
   
BEGIN

PROCESS (read, ready_set)
BEGIN
  IF read = '1' THEN scan_ready <= '0';
  ELSIF ready_set'EVENT and ready_set = '1' THEN
   scan_ready <= '1';
  END IF;
END PROCESS;


--This process filters the raw clock signal coming from the keyboard using a shift register and two AND gates
Clock_filter: PROCESS
BEGIN
   WAIT UNTIL clock_25Mhz'EVENT AND clock_25Mhz= '1';
   filter (6 DOWNTO 0) <= filter(7 DOWNTO 1) ;
   filter(7) <= keyboard_clk;
   
   IF filter = "11111111" THEN      -- If 0hFF set keyboard_clk_filtered
      keyboard_clk_filtered <= '1';
   ELSIF  filter= "00000000" THEN
      keyboard_clk_filtered <= '0';
   END IF;

END PROCESS Clock_filter;

--This process reads in serial data coming from the terminal
PROCESS
BEGIN

WAIT UNTIL (KEYBOARD_CLK_filtered'EVENT AND KEYBOARD_CLK_filtered='1');
IF RESET='1' THEN
   INCNT <= "0000";
   READ_CHAR <= '0';
ELSE
  IF KEYBOARD_DATA='0' AND READ_CHAR='0' THEN
        READ_CHAR<= '1';
        ready_set<= '0';
  ELSE

    -- Shift in next 8 data bits to assemble a scan code
    IF READ_CHAR = '1' THEN

        IF INCNT < "1001" THEN   -- If less than 9-bits keep shifting in data from keyboard
            INCNT <= INCNT + 1;
            SHIFTIN(7 DOWNTO 0) <= SHIFTIN(8 DOWNTO 1);
            SHIFTIN(8) <= KEYBOARD_DATA;
             ready_set <= '0';
   -- End of scan code character, so set flags and exit loop
        ELSE
     scan_code <= SHIFTIN(7 DOWNTO 0);
     READ_CHAR <='0';
     ready_set <= '1';
     INCNT <= "0000";
     
   END IF;
     END IF;
   END IF;
 END IF;
END PROCESS;

END a;


UPD С кодом чутка разобрался, как теперь это можно эмулировать в тестбенче?

Re: Необходима помощь с ps/2 клавиатура VHDL

Чт май 16, 2013 22:57:02

ketron писал(а):как теперь это можно эмулировать в тестбенче?

Тестбэнч лучше кодить опираясь на проект. Берём ту часть, где описаны порты, копируем три раза.
Первую часть переназываем (я привык добавлять к назанию _test), затем переносим входные порты в тело архитектуры, дописывая слово signal.
Из второй копии делаем компонент. Дописываем после компонента слово Begin
Из третьей копии делаем "поле портов", удаляя всё лишнее
Код:
ENTITY key_test IS
   PORT(   
         scan_code      : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
         scan_ready      : OUT STD_LOGIC);
END key_test;

Architecture test of key_test is

signal keyboard_clk, keyboard_data, clock_25Mhz , reset, read: STD_LOGIC:='0';

Component key IS
   PORT(   keyboard_clk, keyboard_data, clock_25Mhz ,
         reset, read      : IN STD_LOGIC;
         scan_code      : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
         scan_ready      : OUT STD_LOGIC);
END component;
Begin
D: key
   PORT MAP(   
keyboard_clk=>keyboard_clk,
keyboard_data=>keyboard_data,
clock_25Mhz =>clock_25Mhz,
reset=>reset,
read=>read,
scan_code=>scan_code,
scan_ready=>scan_ready
);
--Тут должны быть процессы, соответствующие входным сигналам!
end test;

Вот в этот шаблон, надо написать процессы генерации тактовой частоты, сброса, чтения и т.д.
Далее подпихиваем тестбэнч с компилированным проектом каком-нибудь ModelSim'у и наслаждаемся!
Ответить