// (C) 2001-2021 Intel Corporation. All rights reserved. // Your use of Intel Corporation's design tools, logic functions and other // software and tools, and its AMPP partner logic functions, and any output // files from any of the foregoing (including device programming or simulation // files), and any associated documentation or information are expressly subject // to the terms and conditions of the Intel Program License Subscription // Agreement, Intel FPGA IP License Agreement, or other applicable // license agreement, including, without limitation, that your use is for the // sole purpose of programming logic devices manufactured by Intel and sold by // Intel or its authorized distributors. Please refer to the applicable // agreement for further details. `define DEBUG_EN 1 module hdmi_rx_top #( parameter SUPPORT_DEEP_COLOR = 1, parameter SUPPORT_AUXILIARY = 1, parameter SYMBOLS_PER_CLOCK = 2, parameter SUPPORT_AUDIO = 1, parameter EDID_RAM_ADDR_WIDTH = 8, parameter BITEC_DAUGHTER_CARD_REV = 6, parameter HPD_POLARITY = 0 ) ( // Clock, reset and PLL locked signals input wire reset, input wire reset_xcvr_powerup, input wire mgmt_clk, input wire fr_clk, input wire tmds_clk_in, output wire vid_clk_out, output wire ls_clk_out, output wire iopll_locked, output wire sys_init, // GXB RX signals input wire [2:0] rx_serial_data, output wire gxb_rx_ready, // HDMI RX signals output wire TMDS_Bit_clock_Ratio, output wire audio_de, output wire [255:0] audio_data, output wire [47:0] audio_info_ai, output wire [19:0] audio_N, output wire [19:0] audio_CTS, output wire [164:0] audio_metadata, output wire [4:0] audio_format, output wire [71:0] aux_pkt_data, output wire [6:0] aux_pkt_addr, output wire aux_pkt_wr, output wire [5:0] gcp, output wire [111:0] info_avi, output wire [60 :0] info_vsi, output wire [71:0] aux_data, output wire aux_sop, output wire aux_eop, output wire aux_valid, output wire aux_error, output wire [1:0] colordepth_mgmt_sync, output wire locked, output wire [SYMBOLS_PER_CLOCK*48-1:0] vid_data, output wire [SYMBOLS_PER_CLOCK-1:0] vid_vsync, output wire [SYMBOLS_PER_CLOCK-1:0] vid_hsync, output wire [SYMBOLS_PER_CLOCK-1:0] vid_de, output wire vid_lock, input wire in_5v_power, inout wire hdmi_rx_hpd_n, input wire user_pb_0, output wire mode, output wire [SYMBOLS_PER_CLOCK*6-1:0] ctrl, // Reconfig mgmt signals output wire [23:0] measure, output wire measure_valid, output wire os, // I2C signals inout wire hdmi_rx_i2c_sda, inout wire hdmi_rx_i2c_scl, input wire i2c_clk, output wire reconfig_mgmt_write, output wire reconfig_mgmt_read, output wire [11:0] reconfig_mgmt_address, output wire [31:0] reconfig_mgmt_writedata, input wire [31:0] reconfig_mgmt_readdata, input wire reconfig_mgmt_waitrequest, output wire [2:0] gxb_rx_cal_busy_out, output wire rx_reconfig_en, input wire[2:0] gxb_reconfig_write, input wire[2:0] gxb_reconfig_read, input wire [29:0] gxb_reconfig_address, input wire [95:0] gxb_reconfig_writedata, output wire [95:0] gxb_reconfig_readdata, output wire[2:0] gxb_reconfig_waitrequest, input wire [2:0] gxb_rx_cal_busy_in, input wire edid_ram_access, input wire [EDID_RAM_ADDR_WIDTH-1:0] edid_ram_address, input wire edid_ram_write, input wire edid_ram_read, input wire [7:0] edid_ram_writedata, output wire [7:0] edid_ram_readdata, output wire edid_ram_waitrequest ); wire mgmt_clk_reset_sync; wire i2c_clk_reset_sync; wire [31:0] edid_addr; reg [3:0] sys_init_count = 4'd0; always @ (posedge mgmt_clk) begin if (sys_init_count < 4'd11) begin sys_init_count <= sys_init_count + 1'b1; end end assign sys_init = sys_init_count > 4'd5 && sys_init_count < 4'd10; wire [SYMBOLS_PER_CLOCK*10-1:0] r,g,b; wire clk_r, clk_g, clk_b; wire [2:0] rx_clk; wire [SYMBOLS_PER_CLOCK*10*3-1:0] rx_parallel_data_aligned; generate if (BITEC_DAUGHTER_CARD_REV==11) begin: BITEC_RX_MAP assign {b,r,g} = rx_parallel_data_aligned; assign {clk_b, clk_r, clk_g} = rx_clk; end else if (BITEC_DAUGHTER_CARD_REV==4 || BITEC_DAUGHTER_CARD_REV==6) begin assign {r,b,g} = ~rx_parallel_data_aligned; assign {clk_r, clk_b, clk_g} = rx_clk; end else begin assign {r,g,b} = rx_parallel_data_aligned; assign {clk_r, clk_g, clk_b} = rx_clk; end endgenerate // Rx Native PHY Transceiver wire mgmt_clk_core_reset_sync; wire reset_xcvr; wire reset_pll; wire reset_pll_reconfig; wire [2:0] rx_analogreset; wire [2:0] rx_digitalreset; wire [2:0] rx_set_locktoref; wire [2:0] rx_freqlocked; wire [2:0] rx_is_lockedtoref; wire [59:0] rx_data; wire cdr_refclk1; wire [3:0] color_depth; wire [3:0] color_depth_sync; wire [SYMBOLS_PER_CLOCK*10*3-1:0] rx_parallel_data_i; wire [14:0] rx_std_bitslipboundarysel; wire reconfig_pcs_in_progress; gxb_rx u_gxb_rx ( /* I */ .reconfig_write (gxb_reconfig_write), /* I */ .reconfig_read (gxb_reconfig_read), /* I */ .reconfig_address (gxb_reconfig_address), /* I */ .reconfig_writedata (gxb_reconfig_writedata), /* O */ .reconfig_readdata (gxb_reconfig_readdata), /* O */ .reconfig_waitrequest (gxb_reconfig_waitrequest), /* I */ .reconfig_clk ({3{mgmt_clk}}), /* I */ .reconfig_reset ({3{mgmt_clk_reset_sync}}), /* I */ .rx_analogreset (rx_analogreset), /* O */ .rx_cal_busy (gxb_rx_cal_busy_out), /* I */ .rx_cdr_refclk0 (fr_clk), /* I */ .rx_cdr_refclk1 (cdr_refclk1), /* O */ .rx_clkout (rx_clk), /* I */ .rx_coreclkin (rx_clk), /* I */ .rx_digitalreset (rx_digitalreset | {3{reconfig_pcs_in_progress}}), /* O */ .rx_is_lockedtodata (rx_freqlocked), /* O */ .rx_is_lockedtoref (rx_is_lockedtoref), /* O */ .rx_parallel_data (rx_parallel_data_i), /* I */ .rx_serial_data (rx_serial_data), /* I */ .rx_set_locktodata (3'd0), /* I */ .rx_set_locktoref (rx_set_locktoref), /* O */ .unused_rx_parallel_data (), /* O */ .rx_patterndetect (), /* O */ .rx_syncstatus (), /* I */ .rx_std_wa_patternalign (3'b000), /* O */ .rx_std_bitslipboundarysel (rx_std_bitslipboundarysel) ); wire [2:0] rx_datalock; wire tkn_detected; symbol_aligner #( .SYMBOLS_PER_CLOCK (SYMBOLS_PER_CLOCK) ) u_symbol_aligner ( /* I */ .reset (reset), /* I */ .mgmt_clk (mgmt_clk), /* I */ .rx_clk (rx_clk), /* I */ .rx_parallel_data (rx_parallel_data_i), /* I */ .rx_std_bitslipboundarysel (rx_std_bitslipboundarysel), /* I */ .rx_ready (rx_datalock), /* I */ .rx_reconfig_pcs_in_progress (reconfig_pcs_in_progress), /* O */ .token_detected (tkn_detected), /* O */ .rx_parallel_data_aligned (rx_parallel_data_aligned) ); // Rx Transceiver Reset Controller wire [2:0] rx_reset_is_lockedtodata; assign rx_reset_is_lockedtodata = &rx_set_locktoref ? rx_is_lockedtoref : rx_freqlocked; gxb_rx_reset u_gxb_rx_reset ( /* I */ .clock (mgmt_clk), /* I */ .reset (reset_xcvr | reset_xcvr_powerup), /* O */ .rx_analogreset (rx_analogreset), /* I */ .rx_cal_busy (gxb_rx_cal_busy_in), /* O */ .rx_digitalreset (rx_digitalreset), /* I */ .rx_is_lockedtodata (rx_reset_is_lockedtodata), /* O */ .rx_ready (rx_datalock) ); assign gxb_rx_ready = &rx_datalock; // HDMI Rx core wire ls_clk; wire vid_clk; wire reset_core; wire rx_core_ready_sync; clock_crosser #(.W(1)) cc_ready_sync (.in(gxb_rx_ready & ~reset_core),.out(rx_core_ready_sync),.in_clk(mgmt_clk),.out_clk(ls_clk),.in_reset(1'b0),.out_reset(1'b0)); wire rx_hpd_req; output_buf_i2c u_rx_hpd_buf ( /* I */ .datain (HPD_POLARITY), /* B */ .dataio (hdmi_rx_hpd_n), /* I */ .oe (rx_hpd_req), /* O */ .dataout () ); hdmi_rx u_hdmi_rx ( /* I */ .reset (mgmt_clk_core_reset_sync), /* I */ .reset_vid (reset_vid), /* I */ .clk_b (clk_b), /* I */ .clk_g (clk_g), /* I */ .clk_r (clk_r), /* I */ .ls_clk (ls_clk), /* I */ .vid_clk (vid_clk), /* I */ .os (os), /* I */ .in_b (b), /* I */ .in_g (g), /* I */ .in_r (r), /* I */ .in_lock (rx_core_ready_sync), /* O */ .aux_data (aux_data), /* O */ .aux_valid (aux_valid), /* O */ .aux_sop (aux_sop), /* O */ .aux_eop (aux_eop), /* O */ .aux_error (aux_error), /* O */ .gcp (gcp), /* O */ .info_avi (info_avi), /* O */ .info_vsi (info_vsi), /* O */ .aux_pkt_addr (aux_pkt_addr), /* O */ .aux_pkt_data (aux_pkt_data), /* O */ .aux_pkt_wr (aux_pkt_wr), /* O */ .audio_CTS (audio_CTS), /* O */ .audio_N (audio_N), /* O */ .audio_data (audio_data), /* O */ .audio_de (audio_de), /* O */ .audio_metadata (audio_metadata), /* O */ .audio_format (audio_format), /* O */ .audio_info_ai (audio_info_ai), /* O */ .locked (locked), /* O */ .vid_data (vid_data), /* O */ .vid_de (vid_de), /* O */ .vid_hsync (vid_hsync), /* O */ .vid_vsync (vid_vsync), /* O */ .vid_lock (vid_lock), /* I */ .in_5v_power (in_5v_power & user_pb_0 & ~edid_ram_access), /* O */ .rx_hpd_req(rx_hpd_req), /* O */ .mode (mode), /* O */ .ctrl (ctrl), /* I */ .i2c_clk (i2c_clk), /* I */ .i2c_scl (hdmi_rx_i2c_scl), /* B */ .i2c_sda (hdmi_rx_i2c_sda), /* I */ .edid_ram_access (edid_ram_access), /* I */ .edid_ram_address (edid_ram_address), /* I */ .edid_ram_read (edid_ram_read), /* I */ .edid_ram_write (edid_ram_write), /* I */ .edid_ram_writedata (edid_ram_writedata), /* O */ .edid_ram_waitrequest (edid_ram_waitrequest), /* O */ .edid_ram_readdata (edid_ram_readdata), /* O */ .tmds_config_trans_det (tmds_config_trans_det), /* O */ .tmds_bit_clock_ratio (TMDS_Bit_clock_Ratio) ); // GPLL to generate HDMI clocks wire iopll_outclk0; clock_control u_clock_control1 ( /* I */ .inclk (iopll_outclk0), /* O */ .outclk (cdr_refclk1) ); // The IO PLL is defaulted to the following settings to ease timing constraint/analysis // The default setting is not optimum for real time run, reconfig to the right value per incoming // stream rate will be performed (taken care by state machine in multi-rate operation) upon power-up. // refclk = 300MHz (for rate detect 24-bit counter) // outclk_0 = 600MHz (for GXB to generate output clock of 300MHz in 2-symbol mode) // outclk_1 = 300MHz (ls clk) // outclk_2 = 300MHz (vid clk) //wire pll_locked; wire [63:0] reconfig_to_pll; wire [63:0] reconfig_from_pll; pll_hdmi u_iopll ( /* I */ .refclk (tmds_clk_in), /* I */ .rst (reset_pll), /* O */ .outclk_0 (iopll_outclk0), /* O */ .outclk_1 (ls_clk), /* O */ .outclk_2 (vid_clk), /* O */ .locked (iopll_locked), /* I */ .reconfig_to_pll (reconfig_to_pll), /* O */ .reconfig_from_pll (reconfig_from_pll) ); assign vid_clk_out = vid_clk; assign ls_clk_out = ls_clk; // PLL reconfig controller wire pll_reconfig_waitrequest; wire [8:0] pll_reconfig_address; wire pll_reconfig_write; wire [31:0] pll_reconfig_writedata; pll_hdmi_reconfig u_iopll_reconfig ( /* I */ .mgmt_clk (mgmt_clk), /* I */ .mgmt_reset (reset_pll_reconfig), /* O */ .mgmt_waitrequest (pll_reconfig_waitrequest), /* I */ .mgmt_read (), /* I */ .mgmt_write (pll_reconfig_write), /* O */ .mgmt_readdata (), /* I */ .mgmt_address (pll_reconfig_address), /* I */ .mgmt_writedata (pll_reconfig_writedata), /* O */ .reconfig_to_pll (reconfig_to_pll), /* I */ .reconfig_from_pll (reconfig_from_pll) ); assign color_depth = gcp[3:0]; clock_crosser #(.W(4)) cc_cd (.in(color_depth), .out(color_depth_sync), .in_clk(ls_clk),.out_clk(mgmt_clk),.in_reset(1'b0),.out_reset(1'b0)); assign colordepth_mgmt_sync = color_depth_sync[1:0]; // only bit 1 and 0 used by CPU wire measure_valid_reconfig_mgmt; mr_reconfig_mgmt #( .FAST_SIMULATION (0) ) u_mr_reconfig_mgmt ( /* I */ .clock (mgmt_clk), /* I */ .reset (mgmt_clk_reset_sync), /* I */ .refclock (tmds_clk_in), /* I */ .rx_is_20 (TMDS_Bit_clock_Ratio), /* I */ .rx_hdmi_locked (locked), /* I */ .rx_color_depth (color_depth_sync), /* I */ .rx_ready (gxb_rx_ready), /* I */ .pll_locked (iopll_locked), /* O */ .reset_core (reset_core), /* O */ .reset_vid (reset_vid), /* O */ .reset_xcvr (reset_xcvr), /* O */ .reset_pll (reset_pll), /* O */ .reset_pll_reconfig (reset_pll_reconfig), /* O */ .rx_set_locktoref (rx_set_locktoref), /* O */ .measure (measure), /* O */ .measure_valid (measure_valid_reconfig_mgmt), /* I */ .rx_cal_busy (gxb_rx_cal_busy_in), /* I */ .rx_reconfig_waitrequest (reconfig_mgmt_waitrequest), /* I */ .rx_reconfig_readdata (reconfig_mgmt_readdata), /* O */ .rx_reconfig_write (reconfig_mgmt_write), /* O */ .rx_reconfig_read (reconfig_mgmt_read), /* O */ .rx_reconfig_address (reconfig_mgmt_address), /* O */ .rx_reconfig_writedata (reconfig_mgmt_writedata), /* I */ .pll_reconfig_waitrequest (pll_reconfig_waitrequest), /* O */ .pll_reconfig_write (pll_reconfig_write), /* O */ .pll_reconfig_address (pll_reconfig_address), /* O */ .pll_reconfig_writedata (pll_reconfig_writedata), /* O */ .rx_reconfig_en (rx_reconfig_en), /* I */ .tkn_detected (tkn_detected), /* O */ .reconfig_pcs_in_progress (reconfig_pcs_in_progress) ); assign os = &rx_set_locktoref; wire locked_sync; clock_crosser #(.W(1)) cc_hdmi_rx_locked (.in(locked), .out(locked_sync), .in_clk(ls_clk),.out_clk(mgmt_clk),.in_reset(1'b0),.out_reset(1'b0)); assign measure_valid = measure_valid_reconfig_mgmt & locked_sync; // // Reset synchronizers // altera_reset_controller #( .NUM_RESET_INPUTS (3), .SYNC_DEPTH (3), .RESET_REQ_WAIT_TIME (1), .MIN_RST_ASSERTION_TIME (3), .RESET_REQ_EARLY_DSRT_TIME (1) ) u_mgmt_clk_reset_sync_sync ( /* I */ .reset_in0 (reset), /* I */ .reset_in1 (sys_init), /* I */ .reset_in2 (edid_ram_access), /* I */ .clk (mgmt_clk), /* O */ .reset_out (mgmt_clk_reset_sync) ); altera_reset_controller #( .NUM_RESET_INPUTS (2), .SYNC_DEPTH (3), .RESET_REQ_WAIT_TIME (1), .MIN_RST_ASSERTION_TIME (3), .RESET_REQ_EARLY_DSRT_TIME (1) ) u_mgmt_clk_core_reset_sync ( /* I */ .reset_in0 (reset), /* I */ .reset_in1 (sys_init), /* I */ .clk (mgmt_clk), /* O */ .reset_out (mgmt_clk_core_reset_sync) ); altera_reset_controller #( .NUM_RESET_INPUTS (1), .SYNC_DEPTH (3), .RESET_REQ_WAIT_TIME (1), .MIN_RST_ASSERTION_TIME (3), .RESET_REQ_EARLY_DSRT_TIME (1) ) u_i2c_clk_reset_sync ( /* I */ .reset_in0 (reset), /* I */ .clk (i2c_clk), /* O */ .reset_out (i2c_clk_reset_sync) ); ////////////////////////////////////////////////////// // Measure circuitry for clock `ifdef DEBUG_EN mr_rate_detect #( .CYC_MEASURE_CLK_IN_10_MSEC (1000000) ) u_rate_detect_tmds_clk ( /* I */ .refclock (tmds_clk_in), /* I */ .measure_clk (mgmt_clk), /* I */ .reset (reset), /* I */ .enable (1'b1), /* O */ .refclock_measure (), /* O */ .valid () ); mr_rate_detect #( .CYC_MEASURE_CLK_IN_10_MSEC (1000000) ) u_rate_detect_rx_clkout ( /* I */ .refclock (rx_clk[0]), /* I */ .measure_clk (mgmt_clk), /* I */ .reset (reset), /* I */ .enable (1'b1), /* O */ .refclock_measure (), /* O */ .valid () ); mr_rate_detect #( .CYC_MEASURE_CLK_IN_10_MSEC (1000000) ) u_rate_detect_rx_ls_clk ( /* I */ .refclock (ls_clk), /* I */ .measure_clk (mgmt_clk), /* I */ .reset (reset), /* I */ .enable (1'b1), /* O */ .refclock_measure (), /* O */ .valid () ); mr_rate_detect #( .CYC_MEASURE_CLK_IN_10_MSEC (1000000) ) u_rate_detect_rx_vid_clk ( /* I */ .refclock (vid_clk), /* I */ .measure_clk (mgmt_clk), /* I */ .reset (reset), /* I */ .enable (1'b1), /* O */ .refclock_measure (), /* O */ .valid () ); endmodule