123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- module video (
- input rst_n,
- input vid_clk,
- input [1:0] pll_locked,
- output [2:0] hdmi_d,
- output hdmi_clk,
- inout hdmi_scl,
- inout hdmi_sda,
- inout hdmi_hpd
- );
- assign hdmi_scl = 1'bz;
- assign hdmi_sda = 1'bz;
- assign hdmi_hpd = 1'bz;
- //
- // 1024x768x60 with a 56 MHz pixel clock
- //
- // Htiming: 1024 48 32 80 = 1184 = 47.297 kHz
- // Vtiming: 768 4 4 12 = 788 = 60.022 Hz
- //
- localparam [10:0] xact = 11'd1024;
- localparam [10:0] xback = 11'd48;
- localparam [10:0] xsync = 11'd32;
- localparam [10:0] xfront = 11'd80;
- localparam [ 9:0] yact = 10'd768;
- localparam [ 9:0] yback = 10'd4;
- localparam [ 9:0] ysync = 10'd4;
- localparam [ 9:0] yfront = 10'd12;
- reg [10:0] x;
- reg [ 9:0] y;
- reg [7:0] r;
- reg [7:0] g;
- reg [7:0] b;
- reg hblank;
- reg hsync;
- reg vblank;
- reg vsync;
- wire [7:0] pixbar = { x[6:0], 1'b0 } ^ {8{y[9]}};
- always @(posedge vid_clk or negedge rst_n)
- if (~rst_n)
- begin
- x <= 11'b0;
- y <= 10'b0;
- r <= 8'b0;
- g <= 8'b0;
- b <= 8'b0;
- hblank <= 1'b0;
- hsync <= 1'b0;
- vblank <= 1'b0;
- vsync <= 1'b0;
- end
- else
- begin
- r <= pixbar & {8{x[9]}};
- g <= pixbar & {8{x[8]}};
- b <= pixbar & {8{x[7]}};
- x <= x + 1'b1;
- if (x >= (xact+xback+xsync+xfront-1'b1))
- begin
- x <= 11'd0;
- y <= y + 1'b1;
- if (y >= (yact+yback+ysync+yfront-1'b1))
- y <= 10'd0;
- end
- hblank <= x >= xact;
- vblank <= y >= yact;
- hsync <= (x >= (xact+xback) && x < (xact+xback+xsync));
- vsync <= (y >= (yact+yback) && y < (yact+yback+ysync));
- end // else: !if(~rst_n)
- wire [7:0] hdmi_data[0:2];
- assign hdmi_data[2] = r;
- assign hdmi_data[1] = g;
- assign hdmi_data[0] = b;
- // hdmi_ctl[4] enables TERC4 encoding
- wire [4:0] hdmi_ctl[0:2];
- assign hdmi_ctl[0][0] = hsync;
- assign hdmi_ctl[0][1] = vsync;
- assign hdmi_ctl[0][4:2] = 3'b0_00;
- assign hdmi_ctl[1] = 5'b0_0000;
- assign hdmi_ctl[2] = 5'b0_0000;
- wire [9:0] hdmi_tmds_data[0:2]; // TMDS encoded data per channel
- generate
- genvar i;
- for (i = 0; i < 3; i = i + 1)
- begin : hdmitmds
- tmdsenc enc (
- .rst_n ( rst_n ),
- .clk ( vid_clk ),
- .den ( ~hblank & ~vblank ),
- .d ( hdmi_data[i] ),
- .c ( hdmi_ctl[i][3:0] ),
- .tercen( hdmi_ctl[i][4] ),
- .q ( hdmi_tmds_data[i] )
- );
- end
- endgenerate
- assign hdmi_scl = 1'bz;
- assign hdmi_sda = 1'bz;
- assign hdmi_hpd = 1'bz;
- //
- // The ALTLVDS_TX megafunctions is MSB-first and in time-major order.
- // However, TMDS is LSB-first, and we have three TMDS words that
- // concatenate in word(channel)-major order.
- //
- wire [29:0] hdmi_to_tx; // TMDS data in the order hdmitx expects
- transpose #(.words(3), .bits(10), .reverse_b(1),
- .reg_d(0), .reg_q(0)) hdmitranspose
- (
- .clk ( vid_clk ),
- .d ( { hdmi_tmds_data[2], hdmi_tmds_data[1], hdmi_tmds_data[0] } ),
- .q ( hdmi_to_tx )
- );
- wire vid_hdmiclk;
- hdmitx hdmitx (
- .pll_areset ( ~pll_locked[0] ),
- .tx_in ( hdmi_to_tx ),
- .tx_inclock ( vid_clk ),
- .tx_coreclock ( vid_hdmiclk ), // Pixel clock in HDMI domain
- .tx_locked ( pll_locked[1] ),
- .tx_out ( hdmi_d ),
- .tx_outclock ( hdmi_clk )
- );
- endmodule // video
|