improved hpd

added hpd fsm. not sure if compliant with the standard.

hdmi_in is the only allowed to srst the fsm.
on lock loss (e.g.  resolution change)

hdmi_out is checked only after hdmi_in is locked, just once
so, if hdmi_out is disconnected, design will continue tx

design requires both FPGA .bit and PS7 .elf, to work correctly
previous commit needs both FPGA and PS7 as well.
master
neyko3 2024-05-24 18:11:21 +09:00
parent 176f5ba788
commit 7a183c9aee
7 changed files with 302 additions and 21 deletions

Binary file not shown.

View File

@ -38,8 +38,9 @@
"v_tpg_0": "",
"rgb2dvi_0": "",
"CONST_0": "",
"rgb_op0_0": "",
"xlconcat_1": ""
"xlconcat_1": "",
"system_ila_0": "",
"rgb_op0_0": ""
},
"processing_system7_0": "",
"processing_system7_0_axi_periph": {
@ -977,6 +978,9 @@
"direction": "I",
"left": "0",
"right": "0"
},
"tx_hpd_0": {
"direction": "I"
}
},
"components": {
@ -1142,6 +1146,41 @@
}
}
},
"xlconcat_1": {
"vlnv": "xilinx.com:ip:xlconcat:2.1",
"xci_name": "design_1_xlconcat_1_0",
"xci_path": "ip/design_1_xlconcat_1_0/design_1_xlconcat_1_0.xci",
"inst_hier_path": "hier_1/xlconcat_1"
},
"system_ila_0": {
"vlnv": "xilinx.com:ip:system_ila:1.1",
"xci_name": "design_1_system_ila_0_0",
"xci_path": "ip/design_1_system_ila_0_0/design_1_system_ila_0_0.xci",
"inst_hier_path": "hier_1/system_ila_0",
"parameters": {
"C_MON_TYPE": {
"value": "NATIVE"
},
"C_NUM_OF_PROBES": {
"value": "5"
},
"C_PROBE0_TYPE": {
"value": "0"
},
"C_PROBE1_TYPE": {
"value": "0"
},
"C_PROBE2_TYPE": {
"value": "0"
},
"C_PROBE3_TYPE": {
"value": "0"
},
"C_PROBE4_TYPE": {
"value": "0"
}
}
},
"rgb_op0_0": {
"vlnv": "xilinx.com:module_ref:rgb_op0:1.0",
"xci_name": "design_1_rgb_op0_0_0",
@ -1215,14 +1254,40 @@
"value_src": "ip_prop"
}
}
},
"hdmi_in_aPixelClkLckd": {
"direction": "I"
},
"hdmi_out_aPixelClkLckd": {
"direction": "I"
},
"hdmi_in_arst": {
"direction": "O"
},
"hdmi_out_arst": {
"direction": "O"
},
"clk": {
"type": "clk",
"direction": "I",
"parameters": {
"FREQ_HZ": {
"value": "200000000",
"value_src": "user_prop"
},
"CLK_DOMAIN": {
"value": "design_1_processing_system7_0_0_FCLK_CLK2",
"value_src": "default_prop"
}
}
},
"tx_hpd": {
"direction": "I"
},
"rx_hpd": {
"direction": "O"
}
}
},
"xlconcat_1": {
"vlnv": "xilinx.com:ip:xlconcat:2.1",
"xci_name": "design_1_xlconcat_1_0",
"xci_path": "ip/design_1_xlconcat_1_0/design_1_xlconcat_1_0.xci",
"inst_hier_path": "hier_1/xlconcat_1"
}
},
"interface_nets": {
@ -1290,12 +1355,21 @@
"nets": {
"CONST1_dout": {
"ports": [
"CONST1/dout",
"rgb_op0_0/rx_hpd",
"v_vid_in_axi4s_0/aclken",
"v_vid_in_axi4s_0/aresetn",
"v_vid_in_axi4s_0/axis_enable",
"hdmi_rx_hpd"
]
"hdmi_rx_hpd",
"system_ila_0/probe0"
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
},
"MARK_DEBUG": {
"value": "true"
}
}
},
"CONST1_dout_1": {
"ports": [
@ -1320,7 +1394,9 @@
"ports": [
"RefClk",
"dvi2rgb_0/RefClk",
"rst_processing_system7_0_100M1/slowest_sync_clk"
"rst_processing_system7_0_100M1/slowest_sync_clk",
"system_ila_0/clk",
"rgb_op0_0/clk"
]
},
"TMDS_Clk_n_1_1": {
@ -1358,8 +1434,19 @@
"ports": [
"dvi2rgb_0/aPixelClkLckd",
"aPixelClkLckd_0",
"v_vid_in_axi4s_0/vid_io_in_ce"
]
"v_vid_in_axi4s_0/vid_io_in_ce",
"system_ila_0/probe1",
"rgb_op0_0/hdmi_in_aPixelClkLckd",
"rgb_op0_0/hdmi_out_aPixelClkLckd"
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
},
"MARK_DEBUG": {
"value": "true"
}
}
},
"dvi2rgb_0_pLocked": {
"ports": [
@ -1398,6 +1485,36 @@
"TMDS_Data_p_0"
]
},
"rgb_op0_0_hdmi_in_arst": {
"ports": [
"rgb_op0_0/hdmi_in_arst",
"dvi2rgb_0/aRst",
"system_ila_0/probe2"
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
},
"MARK_DEBUG": {
"value": "true"
}
}
},
"rgb_op0_0_hdmi_out_arst": {
"ports": [
"rgb_op0_0/hdmi_out_arst",
"rgb2dvi_0/aRst",
"system_ila_0/probe3"
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
},
"MARK_DEBUG": {
"value": "true"
}
}
},
"rst_processing_system7_0_100M1_peripheral_reset": {
"ports": [
"rst_processing_system7_0_100M2/peripheral_reset",
@ -1435,6 +1552,21 @@
"xlconcat_1/In1"
]
},
"tx_hpd_0_1": {
"ports": [
"tx_hpd_0",
"system_ila_0/probe4",
"rgb_op0_0/tx_hpd"
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
},
"MARK_DEBUG": {
"value": "true"
}
}
},
"v_axi4s_vid_out_0_sof_state_out": {
"ports": [
"v_axi4s_vid_out_0/sof_state_out",
@ -4557,8 +4689,14 @@
"hdmi_tx_hpd_1": {
"ports": [
"hdmi_tx_hpd",
"leds_4bits_tri_o_2"
]
"leds_4bits_tri_o_2",
"hier_1/tx_hpd_0"
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
}
}
},
"hier_1_TMDS_Clk_n_0": {
"ports": [
@ -4588,14 +4726,24 @@
"ports": [
"hier_1/aPixelClkLckd_0",
"leds_4bits_tri_o_0"
]
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
}
}
},
"hier_1_hdmi_rx_hpd": {
"ports": [
"hier_1/hdmi_rx_hpd",
"hdmi_rx_hpd",
"leds_4bits_tri_o_3"
]
],
"hdl_attributes": {
"DEBUG": {
"value": "true"
}
}
},
"hier_1_pLocked_0": {
"ports": [

View File

@ -0,0 +1,90 @@
#include <stdio.h>
//#include "platform.h"
#include "xil_printf.h"
#include "xv_tpg.h"
#include "xvtc.h"
int main()
{
//init_platform();
int Status;
XV_tpg tpg_inst; // Instance of the TPG core
XVtc VtcInst; // Instance of the VTC core
print("--- hdmi-in-test ---\n\r");
//--( TPG Initialization
print("TPG Initialization\n\r");
Status = XV_tpg_Initialize(&tpg_inst, XPAR_XV_TPG_0_DEVICE_ID);
if(Status!= XST_SUCCESS)
{
xil_printf("TPG configuration failed\r\n");
return(XST_FAILURE);
}
// Set Resolution to 1280x720
XV_tpg_Set_height(&tpg_inst, 720);
XV_tpg_Set_width(&tpg_inst, 1280);
// Set Color Space to RGB
XV_tpg_Set_colorFormat(&tpg_inst, 0x0);
//Set pattern to color bar
XV_tpg_Set_bckgndId(&tpg_inst, XTPG_BKGND_COLOR_BARS);
//Start the TPG
XV_tpg_EnableAutoRestart(&tpg_inst);
XV_tpg_Start(&tpg_inst);
xil_printf("TPG started!\r\n");
//--)
//--( VTC Initialization
print("VTC Initialization\n\r");
XVtc_Config *Config;
XVtc_Timing ti;
XVtc_Signal si;
XVtc_HoriOffsets ho;
XVtc_Polarity po;
//Initialize the VTC driver so that it's ready to use look up
//configuration in the config table, then initialize it.
Config = XVtc_LookupConfig(XPAR_VTC_0_DEVICE_ID);
if (NULL == Config) {
return (XST_FAILURE);
}
//Initialize the VTC core
Status = XVtc_CfgInitialize(&VtcInst, Config, Config->BaseAddress);
if (Status != (XST_SUCCESS)) {
return (XST_FAILURE);
}
//Perform a self-test
Status = XVtc_SelfTest(&VtcInst);
if (Status != (XST_SUCCESS)) {
return (XST_FAILURE);
}
//Set our configuration as 1280x720
XVtc_ConvVideoMode2Timing(&VtcInst, XVTC_VMODE_720P, &ti);
XVtc_ConvTiming2Signal(&VtcInst, &ti, &si, &ho, &po);
XVtc_SetGenerator(&VtcInst, &si);
//Enable the vtc
XVtc_Enable(&VtcInst);
xil_printf("VTC enabled!\r\n");
//--)
xil_printf("\r\nInstructions:\r\n");
xil_printf("1. connect HDMI_OUT to HDMI_IN\r\n");
xil_printf("2. Check LD1,LD0 are on\r\n");
xil_printf("3. open ila_1 on vivado (connected to hdmi input after tmds2rgb conversion\r\n");
xil_printf("4. trigger it and compare results with logs/hdmi-loop-test-ila.png \r\n");
while(1){
}
cleanup_platform();
return 0;
}

View File

@ -101,12 +101,12 @@
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
<CompFileExtendedInfo CompFileName="design_1.bd" FileRelPathName="ip/design_1_rgb2dvi_0_0/design_1_rgb2dvi_0_0.xci">
<Proxy FileSetName="design_1_rgb2dvi_0_0"/>
</CompFileExtendedInfo>
<CompFileExtendedInfo CompFileName="design_1.bd" FileRelPathName="ip/design_1_dvi2rgb_0_0/design_1_dvi2rgb_0_0.xci">
<Proxy FileSetName="design_1_dvi2rgb_0_0"/>
</CompFileExtendedInfo>
<CompFileExtendedInfo CompFileName="design_1.bd" FileRelPathName="ip/design_1_rgb2dvi_0_0/design_1_rgb2dvi_0_0.xci">
<Proxy FileSetName="design_1_rgb2dvi_0_0"/>
</CompFileExtendedInfo>
<CompFileExtendedInfo CompFileName="design_1.bd" FileRelPathName="ip/design_1_rgb_op0_0_0/design_1_rgb_op0_0_0.xci">
<Proxy FileSetName="design_1_rgb_op0_0_0"/>
</CompFileExtendedInfo>

View File

@ -12,6 +12,18 @@ module rgb_op0(
(* X_INTERFACE_INFO = "xilinx.com:interface:vid_io:1.0 oV DATA" *) output wire [23:0]oRGB_DATA ,
(* X_INTERFACE_INFO = "xilinx.com:interface:vid_io:1.0 oV HSYNC" *) output wire oRGB_HSYNC ,
(* X_INTERFACE_INFO = "xilinx.com:interface:vid_io:1.0 oV VSYNC" *) output wire oRGB_VSYNC
,
input wire hdmi_in_aPixelClkLckd,
input wire hdmi_out_aPixelClkLckd,
output wire hdmi_in_arst ,
output wire hdmi_out_arst,
input wire clk,
input wire tx_hpd,
output wire rx_hpd
);
@ -26,4 +38,35 @@ assign oRGB_DATA[8*2+:8] =(isel[0])? ~iRGB_DATA[8*2+:8] : iRGB_DATA[8*2+:8];
assign oRGB_HSYNC = iRGB_HSYNC ;
assign oRGB_VSYNC = iRGB_VSYNC ;
reg [ 7:0] r_hpd_fsm0=0;
always@(posedge clk) begin
r_hpd_fsm0 <=
//delay done. check if hdmi_in is still locked
(&r_hpd_fsm0 && hdmi_in_aPixelClkLckd )? r_hpd_fsm0:
//if not locked goto 0 (retry)
(&r_hpd_fsm0 )? 0:
//start
(r_hpd_fsm0==0 )? 1:
//waits for hdmi_in
(r_hpd_fsm0==1 && hdmi_in_aPixelClkLckd )? 2:
//waits for hdmi_out
(r_hpd_fsm0==2 && hdmi_out_aPixelClkLckd && tx_hpd)? 3:
//delay, so that retry is not so quick
(r_hpd_fsm0>=3 )? r_hpd_fsm0+1:
r_hpd_fsm0;
end
assign hdmi_in_arst = (r_hpd_fsm0>=1)? 0: 1;
assign rx_hpd = (r_hpd_fsm0>=1)? 1: 0;
assign hdmi_out_arst = (r_hpd_fsm0>=2)? 0: 1;
endmodule