video.sv 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. module video (
  2. input rst_n,
  3. input vid_clk,
  4. input [1:0] pll_locked,
  5. output [2:0] hdmi_d,
  6. output hdmi_clk,
  7. inout hdmi_scl,
  8. inout hdmi_sda,
  9. inout hdmi_hpd
  10. );
  11. assign hdmi_scl = 1'bz;
  12. assign hdmi_sda = 1'bz;
  13. assign hdmi_hpd = 1'bz;
  14. //
  15. // 1024x768x60 with a 56 MHz pixel clock
  16. //
  17. // Htiming: 1024 48 32 80 = 1184 = 47.297 kHz
  18. // Vtiming: 768 4 4 12 = 788 = 60.022 Hz
  19. //
  20. localparam [10:0] xact = 11'd1024;
  21. localparam [10:0] xback = 11'd48;
  22. localparam [10:0] xsync = 11'd32;
  23. localparam [10:0] xfront = 11'd80;
  24. localparam [ 9:0] yact = 10'd768;
  25. localparam [ 9:0] yback = 10'd4;
  26. localparam [ 9:0] ysync = 10'd4;
  27. localparam [ 9:0] yfront = 10'd12;
  28. reg [10:0] x;
  29. reg [ 9:0] y;
  30. reg [7:0] r;
  31. reg [7:0] g;
  32. reg [7:0] b;
  33. reg hblank;
  34. reg hsync;
  35. reg vblank;
  36. reg vsync;
  37. wire [7:0] pixbar = { x[6:0], 1'b0 } ^ {8{y[9]}};
  38. always @(posedge vid_clk or negedge rst_n)
  39. if (~rst_n)
  40. begin
  41. x <= 11'b0;
  42. y <= 10'b0;
  43. r <= 8'b0;
  44. g <= 8'b0;
  45. b <= 8'b0;
  46. hblank <= 1'b0;
  47. hsync <= 1'b0;
  48. vblank <= 1'b0;
  49. vsync <= 1'b0;
  50. end
  51. else
  52. begin
  53. r <= pixbar & {8{x[9]}};
  54. g <= pixbar & {8{x[8]}};
  55. b <= pixbar & {8{x[7]}};
  56. x <= x + 1'b1;
  57. if (x >= (xact+xback+xsync+xfront-1'b1))
  58. begin
  59. x <= 11'd0;
  60. y <= y + 1'b1;
  61. if (y >= (yact+yback+ysync+yfront-1'b1))
  62. y <= 10'd0;
  63. end
  64. hblank <= x >= xact;
  65. vblank <= y >= yact;
  66. hsync <= (x >= (xact+xback) && x < (xact+xback+xsync));
  67. vsync <= (y >= (yact+yback) && y < (yact+yback+ysync));
  68. end // else: !if(~rst_n)
  69. wire [7:0] hdmi_data[0:2];
  70. //assign hdmi_data[2] = r;
  71. //assign hdmi_data[1] = g;
  72. //assign hdmi_data[0] = b;
  73. //assign hdmi_data[2] = 8'b11110000;
  74. //assign hdmi_data[1] = 8'b11001100;
  75. assign hdmi_data[2] = 8'b10101010;
  76. assign hdmi_data[1] = 8'b10101010;
  77. assign hdmi_data[0] = 8'b10101010;
  78. wire [1:0] hdmi_ctl[0:2];
  79. assign hdmi_ctl[0] = { vsync, hsync };
  80. assign hdmi_ctl[1] = 2'b00;
  81. assign hdmi_ctl[2] = 2'b00;
  82. wire [9:0] hdmi_tmds_data[0:2]; // TMDS encoded data per channel
  83. generate
  84. genvar i;
  85. for (i = 0; i < 3; i = i + 1)
  86. begin : hdmitmds
  87. tmdsenc enc (
  88. .rst_n ( rst_n ),
  89. .clk ( vid_clk ),
  90. .den ( ~hblank & ~vblank ),
  91. .d ( hdmi_data[i] ),
  92. .ten ( 1'b0 ), // TERC data not supported yet
  93. .t ( 4'bx ),
  94. .c ( hdmi_ctl[i] ),
  95. .q ( hdmi_tmds_data[i] )
  96. );
  97. end
  98. endgenerate
  99. assign hdmi_scl = 1'bz;
  100. assign hdmi_sda = 1'bz;
  101. assign hdmi_hpd = 1'bz;
  102. //
  103. // The ALTLVDS_TX megafunctions is MSB-first in channel-major
  104. // order, but TMDS is LSB first. Thus, bit-reverse the data within
  105. // each channel.
  106. //
  107. wire [29:0] hdmi_to_tx; // TMDS data in the order hdmitx expects
  108. transpose #(.words( 3 ),
  109. .bits( 10 ),
  110. .reverse_b ( 1'b1 ),
  111. .reverse_w ( 1'b0 ),
  112. .transpose ( 1'b0 ),
  113. .reg_d ( 1'b0 ),
  114. .reg_q ( 1'b0 )
  115. ) hdmitranspose
  116. (
  117. .clk ( vid_clk ),
  118. .d ( { hdmi_tmds_data[2], hdmi_tmds_data[1], hdmi_tmds_data[0] } ),
  119. .q ( hdmi_to_tx )
  120. );
  121. wire vid_hdmiclk;
  122. hdmitx hdmitx (
  123. .pll_areset ( ~pll_locked[0] ),
  124. .tx_in ( hdmi_to_tx ),
  125. .tx_inclock ( vid_clk ),
  126. .tx_coreclock ( vid_hdmiclk ), // Pixel clock in HDMI domain
  127. .tx_locked ( pll_locked[1] ),
  128. .tx_out ( hdmi_d ),
  129. .tx_outclock ( hdmi_clk )
  130. );
  131. endmodule // video