如何在XILINX FPGA (Artix-7)上实现HDMI直通

问题描述 投票:0回答:2

我想在配备 Artix-7 FPGA 和 HDMI 接收器/源端口的 Nexys 视频板上实现我自己的 HDMI 直通。我的设置是:PC HDMI 端口连接到接收端口,而 LED 显示器连接到源 HDMI 端口。

由于板上没有 TDMS 编码器/解码器,接下来我还需要实现它们(我不想只获取互联网上现成的闭源实现之一)。但现在,我只需要通过 FPGA 连接接收器/源端口,这样我就可以在显示器上显示视频。然而,我还没有成功。没有显示图像,显示器显示“无信号”。我有点担心误用 FGPA 端口可能会导致主板永久损坏。因此,我并没有尝试所有想到的事情。我期待建议来纠正/完成我的代码。

我按照以下代码和原理图连接了 HDMI 信号:

module HDMI_Top(RSTN, CLK, BTN, SW, LED,
            HDMIR_TXEN, HDMIR_HPA, HDMIT_HPD, 
            HDMIR_SCL, HDMIR_SDA, HDMIT_SCL, HDMIT_SDA,
            HDMIR_CLK_P, HDMIR_CLK_N, HDMIR_DATA_P, HDMIR_DATA_N,
            HDMIT_CLK_P, HDMIT_CLK_N, HDMIT_DATA_P, HDMIT_DATA_N);

input RSTN;
input CLK;
input [4:0] BTN;
input [7:0] SW;
output [7:0] LED;

output HDMIR_TXEN;
output HDMIR_HPA;
input HDMIT_HPD;
inout HDMIR_SCL;
inout HDMIR_SDA;
inout HDMIT_SCL;
inout HDMIT_SDA;

input HDMIR_CLK_P;
input HDMIR_CLK_N;
input [2:0] HDMIR_DATA_P;
input [2:0] HDMIR_DATA_N;
output HDMIT_CLK_P;
output HDMIT_CLK_N;
output [2:0] HDMIT_DATA_P;
output [2:0] HDMIT_DATA_N;

wire [2:0] HDMI_DATA;
wire HDMI_CLK;
wire w0, w1, w2;

assign LED = SW;
//assign HDMIR_HPA = HDMIT_HPD;
assign HDMIR_TXEN = 1'b1;
assign HDMIT_SCL = HDMIR_SCL;
assign HDMIT_SDA = HDMIR_SDA;

// IBUFDS: Differential Input Buffer
IBUFDS #(
    .DIFF_TERM("FALSE"), // Differential Termination
    .IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUFDS_hdmir_clk (
    .O(HDMI_CLK), // Buffer output
    .I(HDMIR_CLK_P), // Diff_p buffer input (connect directly to top-level port)
    .IB(HDMIR_CLK_N) // Diff_n buffer input (connect directly to top-level port)
);

OBUFDS #(
    .IOSTANDARD("DEFAULT") // Specify the output I/O standard
) OBUFDS_hdmit_clk (
    .O(HDMIT_CLK_P), // Diff_p output (connect directly to top-level port)
    .OB(HDMIT_CLK_N), // Diff_n output (connect directly to top-level port)
    .I(HDMI_CLK) // Buffer input
);

// IBUFDS: Differential Input Buffer
IBUFDS #(
    .DIFF_TERM("FALSE"), // Differential Termination
    .IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUFDS_hdmir_data [2:0] (
    .O(HDMI_DATA), // Buffer output
    .I(HDMIR_DATA_P), // Diff_p buffer input (connect directly to top-level port)
    .IB(HDMIR_DATA_N) // Diff_n buffer input (connect directly to top-level port)
);

OBUFDS #(
    .IOSTANDARD("DEFAULT") // Specify the output I/O standard
) OBUFDS_hdmit_data [2:0] (
    .O(HDMIT_DATA_P), // Diff_p output (connect directly to top-level port)
    .OB(HDMIT_DATA_N), // Diff_n output (connect directly to top-level port)
    .I(HDMI_DATA) // Buffer input
);endmodule

这里是代码对应的原理图

谢谢;

verilog xilinx hdmi pass-through
2个回答
0
投票

我终于成功了。现在我的 Nexys 显卡可以播放全高清视频。详情如下:

  1. HPA 和 TXEN 引脚都必须设置为“1”。在我的例子中,我将源端口的 HPD 引脚分配给接收端口的 HPA 引脚。检查电路板原理图,HPD 引脚连接到开漏 MOSFET,因此在分配之前必须将其反转。

分配 HDMIR_HPA = ~HDMIT_HPD;

  1. 此外,经过彻底的谷歌搜索后,我发现将接收器端口的 DDC SCL 和 SDA 引脚桥接到源端口似乎是不可能的,因为两个双向引脚无法(简单地)连接到 FPGA 上。所以解决这个问题的办法是在sink端添加一个EDID ROM仿真器。然后 FPGA 本身充当视频源设备(即我设置中的 PC)的监视器。

我从这里找到了 EDID ROM 的 VHDL 实现。它模拟 1024 x 768 显示器,但我将其更改为 1920 x 1080。

这是顶层模块的修改后的代码:

module HDMI_Top(
input RSTN,
input CLK,
input [4:0] BTN,
input [7:0] SW,
output [7:0] LED,
output HDMIR_TXEN,
output HDMIR_HPA,
input HDMIT_HPD, 
input HDMIR_SCL,
inout HDMIR_SDA,
output HDMIT_SCL,
inout HDMIT_SDA,
input HDMIR_CLK_P,
input HDMIR_CLK_N,
input [2:0] HDMIR_DATA_P,
input [2:0] HDMIR_DATA_N,
output HDMIT_CLK_P,
output HDMIT_CLK_N,
output [2:0] HDMIT_DATA_P,
output [2:0] HDMIT_DATA_N
);

wire HDMI_CLK;
wire [2:0] HDMI_DATA;

assign LED = SW;

// Whenever a sink is ready and wishes to announce its presence, it connects the 5V0 supply pin to the HPD pin. On
// the Nexys Video, this is done by driving the HPA (Hot Plug Assert) signal high. Note: this should only be done
// after a DDC channel slave has been implemented in the FPGA and is ready to transmit display data.
// FPGA lets the HDMI source (e.g., a PC) connected to its sink port know its presence by setting HPA signal to '1'.
// A monitor connected to the source port sets HPD signal to '0'.
// assign HDMIR_HPA = 1'b1;
assign HDMIR_HPA = ~HDMIT_HPD;

// A pull-down resistor on the TXEN signal makes sure the sink buffer's transmitter facing the FPGA is disabled by default.
// An FPGA design using the sink port needs to actively drive this pin high for the buffer to pass data through.
assign HDMIR_TXEN = 1'b1;

// The Display Data Channel, or DDC, is a collection of protocols that enable communication between the display
// (sink) and graphics adapter (source). The DDC2B variant is based on I2C, the bus master being the source and the
// bus slave the sink. When a source detects high level on the HPD pin, it queries the sink over the DDC bus for video
// capabilities. It determines whether the sink is DVI or HDMI-capable and what resolutions are supported. Only
// afterwards will video transmission begin. Refer to VESA E-DDC specifications for more information.
edid_rom edid_rom_rx0 (.clk(CLK), .sclk_raw(HDMIR_SCL), .sdat_raw(HDMIR_SDA));
    
// IBUFDS: Differential Input Buffer
IBUFDS #(
    .DIFF_TERM("FALSE"), // Differential Termination
    .IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUFDS_hdmir_clk (
    .O(HDMI_CLK), // Buffer output
    .I(HDMIR_CLK_P), // Diff_p buffer input (connect directly to top-level port)
    .IB(HDMIR_CLK_N) // Diff_n buffer input (connect directly to top-level port)
);

OBUFDS #(
    .IOSTANDARD("DEFAULT") // Specify the output I/O standard
) OBUFDS_hdmit_clk (
    .O(HDMIT_CLK_P), // Diff_p output (connect directly to top-level port)
    .OB(HDMIT_CLK_N), // Diff_n output (connect directly to top-level port)
    .I(HDMI_CLK) // Buffer input
);

// IBUFDS: Differential Input Buffer
IBUFDS #(
    .DIFF_TERM("FALSE"), // Differential Termination
    .IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUFDS_hdmir_data [2:0] (
    .O(HDMI_DATA), // Buffer output
    .I(HDMIR_DATA_P), // Diff_p buffer input (connect directly to top-level port)
    .IB(HDMIR_DATA_N) // Diff_n buffer input (connect directly to top-level port)
);

OBUFDS #(
    .IOSTANDARD("DEFAULT") // Specify the output I/O standard
) OBUFDS_hdmit_data [2:0] (
    .O(HDMIT_DATA_P), // Diff_p output (connect directly to top-level port)
    .OB(HDMIT_DATA_N), // Diff_n output (connect directly to top-level port)
    .I(HDMI_DATA) // Buffer input
); endmodule

您可以在这里找到完整的源代码。

我的下一步是将序列化器/解序列化器和 tmds 编码器/解码器添加到项目中。对于那些可能希望做同样事情的人,这里是我的(工作)源代码的最新版本,包括序列化器/反序列化器和 tmds 编码器/解码器。


0
投票

嘿,我实际上正在开发一个非常相似的项目(也有 Nexys Video),想知道你是否可以帮助我完成它?我尝试仅使用 EDID 和 I/O 缓冲区进行直通,但接收器监视器上没有收到任何信息。你到底改变了什么吗?不幸的是,指向您的源代码的链接不起作用......

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.