我正在做一个项目。 该项目的目标是使用FPGA板将USB键盘和HDMI显示器相互连接。这意味着我们想在按下键时在显示屏上显示键盘的每个字母和字符。
对于该项目,我选择了Digilent基于FPGA Xilinx Spartan6构建的Altys板。
目前,我已经将键盘与FPGA板相连,并且可以从键盘接收数据。这意味着当我按电路板上的字母LED时,它们会点亮。 我还为每个字母实现了led序列。
现在,我尝试将键盘上的字母发送到具有HDMI输出端口的显示器,但是遇到了一些麻烦。
是否有人有任何想法或代码可以通过FPGA板的HDMI端口显示某些内容?
感谢您的帮助
键盘连接的代码
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
entity main is
port(
k_clk: in std_logic;
k_d: inout std_logic;
Led: out std_logic_vector(7 downto 0);
clk: in std_logic;
char: out std_logic_vector(7 downto 0)
);
end main;
architecture Behavioral of main is
signal s_k_clk: std_logic :='0';
signal ch: std_logic_vector(7 downto 0) :=(others=>'0');
signal k_clk1: std_logic;
--signal pulseInternal : std_logic;
signal makeCodeTemp : std_logic_vector(7 downto 0);
signal makeCode : std_logic_vector(7 downto 0);
signal data : std_logic_vector(21 downto 0);
signal charTemp :std_logic_vector(7 downto 0);
--signal char :std_logic_vector(7 downto 0);
begin
--------------------------------------------------------------
makeCodeTemp <= data(9 downto 2); -- Scan code window
makeCode(7) <= makeCodeTemp(0);
makeCode(6) <= makeCodeTemp(1);
makeCode(5) <= makeCodeTemp(2);
makeCode(4) <= makeCodeTemp(3);
makeCode(3) <= makeCodeTemp(4);
makeCode(2) <= makeCodeTemp(5);
makeCode(1) <= makeCodeTemp(6);
makeCode(0) <= makeCodeTemp(7);
--------------------------------------------------------------
Led(7 downto 0) <= ch(7 downto 0);
k_clk1<=k_clk xor s_k_clk;
p0:process(clk)
begin
if rising_edge(clk)then
s_k_clk<=k_clk;
end if;
end process;
p1:process(clk)
begin
if rising_edge(clk)then
if (k_clk1='1') then
data(21 downto 1) <= data(20 downto 0);
data(0) <= k_d;
--ch<=ch+1;
end if;
end if;
end process;
p2:process(clk)
begin
if rising_edge(clk) then
if data(20 downto 13) = x"0F" then char <= charTemp;
end if;
end if;
end process;
p3:process(clk)
begin
if rising_edge(clk) then
if charTemp=x"41" then
ch(0)<='1';
elsif charTemp=x"42" then
ch(1)<='1';
elsif charTemp=x"43" then
ch(2)<='1';
elsif charTemp=x"44" then
ch(3)<='1';
elsif charTemp=x"45" then
ch(4)<='1';
end if;
end if;
end process;
charTemp <= x"41" when makeCode = x"1C" else --A
x"42" when makeCode = x"32" else --B
x"43" when makeCode = x"21" else --C
x"44" when makeCode = x"23" else --D
x"45" when makeCode = x"24" else --E
x"46" when makeCode = x"2B" else --F
x"47" when makeCode = x"34" else --G
x"48" when makeCode = x"33" else --H
x"49" when makeCode = x"43" else --I
x"4A" when makeCode = x"3B" else --J
x"4B" when makeCode = x"42" else --K
x"4C" when makeCode = x"4B" else --L
x"4D" when makeCode = x"3A" else --M
x"4E" when makeCode = x"31" else --N
x"4F" when makeCode = x"44" else --O
x"50" when makeCode = x"4D" else --P
x"51" when makeCode = x"15" else --Q
x"52" when makeCode = x"2D" else --R
x"53" when makeCode = x"1B" else --S
x"54" when makeCode = x"2C" else --T
x"55" when makeCode = x"3C" else --U
x"56" when makeCode = x"2A" else --V
x"57" when makeCode = x"1D" else --W
x"58" when makeCode = x"22" else --X
x"59" when makeCode = x"35" else --Y
x"5A" when makeCode = x"1A" else --Z
x"30" when makeCode = x"45" else --0
x"31" when makeCode = x"16" else --1
x"32" when makeCode = x"1E" else --2
x"33" when makeCode = x"26" else --3
x"34" when makeCode = x"25" else --4
x"35" when makeCode = x"2E" else --5
x"36" when makeCode = x"36" else --6
x"37" when makeCode = x"3D" else --7
x"38" when makeCode = x"3E" else --8
x"39" when makeCode = x"46" else --9
x"2F" when makeCode = x"5A" else --ENTER
x"5C" when makeCode = x"66" else --Backspace
x"00"; --Null
end Behavioral;
** HDMI显示代码:**
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;
entity dvid is
Port ( clk_tmds0 : in STD_LOGIC;
clk_tmds90 : in STD_LOGIC;
clk_pixel : in STD_LOGIC;
red_p : in STD_LOGIC_VECTOR (7 downto 0);
green_p : in STD_LOGIC_VECTOR (7 downto 0);
blue_p : in STD_LOGIC_VECTOR (7 downto 0);
blank : in STD_LOGIC;
hsync : in STD_LOGIC;
vsync : in STD_LOGIC;
red_s : out STD_LOGIC;
green_s : out STD_LOGIC;
blue_s : out STD_LOGIC;
clock_s : out STD_LOGIC);
end dvid;
architecture Behavioral of dvid is
COMPONENT TDMS_encoder
PORT(
clk : IN std_logic;
data : IN std_logic_vector(7 downto 0);
c : IN std_logic_vector(1 downto 0);
blank : IN std_logic;
encoded : OUT std_logic_vector(9 downto 0)
);
END COMPONENT;
COMPONENT qdr
PORT(
clk0 : IN std_logic;
clk90 : IN std_logic;
data : IN std_logic_vector(3 downto 0);
qdr : OUT std_logic
);
END COMPONENT;
signal encoded_r, encoded_g, encoded_b : std_logic_vector(9 downto 0);
-- for the control frames (blanking)
constant c_red : std_logic_vector(1 downto 0) := (others => '0');
constant c_green : std_logic_vector(1 downto 0) := (others => '0');
signal c_blue : std_logic_vector(1 downto 0);
signal latched_r : std_logic_vector(9 downto 0) := (others => '0');
signal latched_g : std_logic_vector(9 downto 0) := (others => '0');
signal latched_b : std_logic_vector(9 downto 0) := (others => '0');
signal buffer_r : std_logic_vector(9 downto 0) := (others => '0');
signal buffer_g : std_logic_vector(9 downto 0) := (others => '0');
signal buffer_b : std_logic_vector(9 downto 0) := (others => '0');
-- one hot encoded. Initial Value is important to sync with pixel chantges!
signal state : std_logic_vector(4 downto 0) := "10000";
signal bits_r : std_logic_vector(3 downto 0) := (others => '0');
signal bits_g : std_logic_vector(3 downto 0) := (others => '0');
signal bits_b : std_logic_vector(3 downto 0) := (others => '0');
signal bits_c : std_logic_vector(3 downto 0) := (others => '0');
-- output shift registers
signal sr_r : std_logic_vector(11 downto 0):= (others => '0');
signal sr_g : std_logic_vector(11 downto 0):= (others => '0');
signal sr_b : std_logic_vector(11 downto 0):= (others => '0');
signal sr_c : std_logic_vector(9 downto 0) := "0111110000";
-- Gives a startup delay to allow the fifo to fill
signal delay_ctr : std_logic_vector(3 downto 0) := (others => '0');
begin
c_blue <= vsync & hsync;
TDMS_encoder_red: TDMS_encoder PORT MAP(clk => clk_pixel, data => red_p, c => c_red, blank => blank, encoded => encoded_r);
TDMS_encoder_green: TDMS_encoder PORT MAP(clk => clk_pixel, data => green_p, c => c_green, blank => blank, encoded => encoded_g);
TDMS_encoder_blue: TDMS_encoder PORT MAP(clk => clk_pixel, data => blue_p, c => c_blue, blank => blank, encoded => encoded_b);
qdr_r: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_r(3 downto 0), qdr => red_s);
qdr_g: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_g(3 downto 0), qdr => green_s);
qdr_b: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_b(3 downto 0), qdr => blue_s);
qdr_c: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_c(3 downto 0), qdr => clock_s);
process(clk_pixel)
begin
-- Just sample the encoded pixel data, to give a smooth transition to high speed domain
if rising_edge(clk_pixel) then
buffer_r <= encoded_r;
buffer_g <= encoded_g;
buffer_b <= encoded_b;
end if;
end process;
process(clk_tmds0)
begin
if rising_edge(clk_tmds0) then
bits_r <= sr_r(3 downto 0);
bits_g <= sr_g(3 downto 0);
bits_b <= sr_b(3 downto 0);
bits_c <= sr_c(3 downto 0);
case state is
when "00001" =>
sr_r <= "00" & latched_r;
sr_g <= "00" & latched_g;
sr_b <= "00" & latched_b;
when "00010" =>
sr_r <= "0000" & sr_r(sr_r'high downto 4);
sr_g <= "0000" & sr_g(sr_g'high downto 4);
sr_b <= "0000" & sr_b(sr_b'high downto 4);
when "00100" =>
sr_r <= latched_r & sr_r(5 downto 4);
sr_g <= latched_g & sr_g(5 downto 4);
sr_b <= latched_b & sr_b(5 downto 4);
when "01000" =>
sr_r <= "0000" & sr_r(sr_r'high downto 4);
sr_g <= "0000" & sr_g(sr_g'high downto 4);
sr_b <= "0000" & sr_b(sr_b'high downto 4);
when others =>
sr_r <= "0000" & sr_r(sr_r'high downto 4);
sr_g <= "0000" & sr_g(sr_g'high downto 4);
sr_b <= "0000" & sr_b(sr_b'high downto 4);
end case;
-- Move on to the next state
state <= state(state'high-1 downto 0) & state(state'high);
-- Move the TMDS clock signal shift register
sr_c <= sr_c(3 downto 0) & sr_c(sr_c'high downto 4);
if delay_ctr(delay_ctr'high) = '0' then
delay_ctr <= delay_ctr +1;
end if;
-- Move the encoded pixel data into the fast clock domain
latched_r <= buffer_r;
latched_g <= buffer_g;
latched_b <= buffer_b;
end if;
end process;
end Behavioral;
答案 0 :(得分:0)
请参阅本用户指南,该指南涵盖了在atlys板上实现HDMI作为参考设计。 https://www.xilinx.com/support/documentation/application_notes/xapp495_S6TMDS_Video_Interface.pdf