zynq-sandbox

old FPGA projects for ZYNQ
git clone http://frotz.net/git/zynq-sandbox.git
Log | Files | Refs | README

hdmi_core.sv (2689B)


      1 // Copyright 2014 Brian Swetland <swetland@frotz.net>
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 `timescale 1ns/1ps
     16 
     17 module hdmi_core (
     18 	input pixclk,
     19 	input pixclkx5,
     20 	// TMDS33 outputs
     21 	output [2:0]hdmi_d_p,
     22 	output [2:0]hdmi_d_n,
     23 	output hdmi_clk_p,
     24 	output hdmi_clk_n,
     25 	// RGB data input
     26 	output rgb_ready,
     27 	input [7:0]red,
     28 	input [7:0]grn,
     29 	input [7:0]blu,
     30 	// core status
     31 	output [10:0]xpixel,
     32 	output [10:0]ypixel,
     33 	output vblank
     34 	);
     35 
     36 parameter HWIDTH = 960;
     37 parameter HSYNC0 = 1000;
     38 parameter HSYNC1 = 1100;
     39 parameter HMAX = 1199;
     40 parameter VHEIGHT = 600;
     41 parameter VSYNC0 = 613;
     42 parameter VSYNC1 = 620;
     43 parameter VMAX = 624;
     44 
     45 reg [10:0] hcount, vcount;
     46 reg hsync, vsync, active;
     47 
     48 assign vblank = vsync;
     49 
     50 always @(posedge pixclk) begin
     51 	if (hcount == HMAX) begin
     52 		hcount <= 0;
     53 		if (vcount == VMAX) begin
     54 			vcount <= 0;
     55 		end else begin
     56 			vcount <= vcount + 1;
     57 		end
     58 	end else begin
     59 		hcount <= hcount + 1;
     60 	end
     61 	active <= (hcount < HWIDTH) && (vcount < VHEIGHT);
     62 	hsync <= (hcount >= HSYNC0) && (hcount < HSYNC1);
     63 	vsync <= (vcount >= VSYNC0) && (vcount < VSYNC1);
     64 end
     65 
     66 assign xpixel = hcount;
     67 assign ypixel = vcount;
     68 assign rgb_ready = active;
     69 
     70 wire [9:0] ch0, ch1, ch2;
     71 
     72 tmds_encoder enc2(
     73 	.clk(pixclk),
     74 	.data(red),
     75 	.ctrl(0),
     76 	.active(active),
     77 	.out(ch2)
     78 	);
     79 tmds_encoder enc1(
     80 	.clk(pixclk),
     81 	.active(active),
     82 	.data(grn),
     83 	.ctrl(0),
     84 	.out(ch1)
     85 	);
     86 tmds_encoder enc0(
     87 	.clk(pixclk),
     88 	.active(active),
     89 	.data(blu),
     90 	.ctrl({vsync,hsync}),
     91 	.out(ch0)
     92 	);
     93 
     94 // does not reliably work on cold boot without reset/sync
     95 reg [9:0]txrescnt = 0;
     96 wire txres = (txrescnt[9:1] == 9'b100000000);
     97 always @(posedge pixclk) begin
     98 	if (txrescnt != 10'b1111111111) begin
     99 		txrescnt <= txrescnt + 1;
    100 	end
    101 end
    102 
    103 serdes_10to1_tx tx2(
    104 	.clk(pixclk),
    105 	.clkx5(pixclkx5),
    106 	.reset(txres),
    107 	.o_p(hdmi_d_p[2]),
    108 	.o_n(hdmi_d_n[2]),
    109 	.i_data(ch2)
    110 	);
    111 
    112 serdes_10to1_tx tx1(
    113 	.clk(pixclk),
    114 	.clkx5(pixclkx5),
    115 	.reset(txres),
    116 	.o_p(hdmi_d_p[1]),
    117 	.o_n(hdmi_d_n[1]),
    118 	.i_data(ch1)
    119 	);
    120 
    121 serdes_10to1_tx tx0(
    122 	.clk(pixclk),
    123 	.clkx5(pixclkx5),
    124 	.reset(txres),
    125 	.o_p(hdmi_d_p[0]),
    126 	.o_n(hdmi_d_n[0]),
    127 	.i_data(ch0)
    128 	);
    129 
    130 OBUFDS OBUFDS_clock(.I(pixclk), .O(hdmi_clk_p), .OB(hdmi_clk_n));
    131 
    132 endmodule