OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [Verilog/] [rgb2hdmi_encode.v] - Blame information for rev 216

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 210 davidgb
// RGB2HDMI_encoder
2
// Derived from HDMI_test.v https://www.fpga4fun.com/HDMI.html
3
//          (c) fpga4fun.com & KNJN LLC 2013
4
 
5
////////////////////////////////////////////////////////////////////////
6
module RGB2HDMI_encoder(
7
  input pixclk,  // 25MHz
8
  input vSync,
9
  input hSync,
10
  input DrawArea,
11
  input [7:0] red,
12
  input [7:0] green,
13
  input [7:0] blue,
14
  output [2:0] TMDSp, TMDSn,
15
  output TMDSp_clock, TMDSn_clock
16
);
17
  ////////////////////////////////////////////////////////////////////////
18
  wire [9:0] TMDS_red, TMDS_green, TMDS_blue;
19
  TMDS_encoder encode_R(.clk(pixclk), .VD(red  ), .CD(2'b00)        , .VDE(DrawArea), .TMDS(TMDS_red));
20
  TMDS_encoder encode_G(.clk(pixclk), .VD(green), .CD(2'b00)        , .VDE(DrawArea), .TMDS(TMDS_green));
21
  TMDS_encoder encode_B(.clk(pixclk), .VD(blue ), .CD({vSync,hSync}), .VDE(DrawArea), .TMDS(TMDS_blue));
22
 
23
  ////////////////////////////////////////////////////////////////////////
24
  wire clk_TMDS, DCM_TMDS_CLKFX;  // 25MHz x 10 = 250MHz
25 216 davidgb
  wire clk_CLK0;
26
  DCM_SP #(.CLKFX_MULTIPLY(10)) DCM_TMDS_inst(.CLKIN(pixclk), .CLKFX(DCM_TMDS_CLKFX), .CLK0(clk_CLK0), .RST(1'b0));
27 210 davidgb
  BUFG BUFG_TMDSp(.I(DCM_TMDS_CLKFX), .O(clk_TMDS));
28
 
29
  ////////////////////////////////////////////////////////////////////////
30
  reg [3:0] TMDS_mod10=0;  // modulus 10 counter
31
  reg [9:0] TMDS_shift_red=0, TMDS_shift_green=0, TMDS_shift_blue=0;
32
  reg TMDS_shift_load=0;
33
  always @(posedge clk_TMDS) TMDS_shift_load <= (TMDS_mod10==4'd9);
34
 
35
  always @(posedge clk_TMDS)
36
  begin
37
    TMDS_shift_red   <= TMDS_shift_load ? TMDS_red   : TMDS_shift_red  [9:1];
38
    TMDS_shift_green <= TMDS_shift_load ? TMDS_green : TMDS_shift_green[9:1];
39
    TMDS_shift_blue  <= TMDS_shift_load ? TMDS_blue  : TMDS_shift_blue [9:1];
40
    TMDS_mod10 <= (TMDS_mod10==4'd9) ? 4'd0 : TMDS_mod10+4'd1;
41
  end
42
 
43
  OBUFDS OBUFDS_red  (.I(TMDS_shift_red  [0]), .O(TMDSp[2]), .OB(TMDSn[2]));
44
  OBUFDS OBUFDS_green(.I(TMDS_shift_green[0]), .O(TMDSp[1]), .OB(TMDSn[1]));
45
  OBUFDS OBUFDS_blue (.I(TMDS_shift_blue [0]), .O(TMDSp[0]), .OB(TMDSn[0]));
46
  OBUFDS OBUFDS_clock(.I(pixclk), .O(TMDSp_clock), .OB(TMDSn_clock));
47
endmodule
48
 
49
////////////////////////////////////////////////////////////////////////
50
module TMDS_encoder(
51
  input clk,
52
  input [7:0] VD,  // video data (red, green or blue)
53
  input [1:0] CD,  // control data
54
  input VDE,  // video data enable, to choose between CD (when VDE=0) and VD (when VDE=1)
55
  output reg [9:0] TMDS = 0
56
);
57
 
58
  wire [3:0] Nb1s = VD[0] + VD[1] + VD[2] + VD[3] + VD[4] + VD[5] + VD[6] + VD[7];
59
  wire XNOR = (Nb1s>4'd4) || (Nb1s==4'd4 && VD[0]==1'b0);
60
  wire [8:0] q_m = {~XNOR, q_m[6:0] ^ VD[7:1] ^ {7{XNOR}}, VD[0]};
61
 
62
  reg [3:0] balance_acc = 0;
63
  wire [3:0] balance = q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7] - 4'd4;
64
  wire balance_sign_eq = (balance[3] == balance_acc[3]);
65
  wire invert_q_m = (balance==0 || balance_acc==0) ? ~q_m[8] : balance_sign_eq;
66
  wire [3:0] balance_acc_inc = balance - ({q_m[8] ^ ~balance_sign_eq} & ~(balance==0 || balance_acc==0));
67
  wire [3:0] balance_acc_new = invert_q_m ? balance_acc-balance_acc_inc : balance_acc+balance_acc_inc;
68
  wire [9:0] TMDS_data = {invert_q_m, q_m[8], q_m[7:0] ^ {8{invert_q_m}}};
69
  wire [9:0] TMDS_code = CD[1] ? (CD[0] ? 10'b1010101011 : 10'b0101010100) : (CD[0] ? 10'b0010101011 : 10'b1101010100);
70
 
71
  always @(posedge clk) TMDS <= VDE ? TMDS_data : TMDS_code;
72
  always @(posedge clk) balance_acc <= VDE ? balance_acc_new : 4'h0;
73
endmodule
74
 
75
////////////////////////////////////////////////////////////////////////

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.