2
0

tmdsenc.sv 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //
  2. // Encodes a word in TMDS 8/10 format
  3. //
  4. module tmdsenc
  5. (
  6. input rst_n,
  7. input clk,
  8. input den, // Video data enable
  9. input [7:0] d, // Video data word
  10. input ten, // TERC data enable
  11. input [3:0] t, // TERC data
  12. input [1:0] c, // Control symbol
  13. output [9:0] q
  14. );
  15. // Control symbols
  16. wire [9:0] csym[0:3];
  17. assign csym[ 0] = 10'b11010_10100;
  18. assign csym[ 1] = 10'b00101_01011;
  19. assign csym[ 2] = 10'b01010_10100;
  20. assign csym[ 3] = 10'b10101_01011;
  21. // TERC4 symbols
  22. wire [9:0] tsym[0:15];
  23. assign tsym[ 0] = 10'b10100_11100;
  24. assign tsym[ 1] = 10'b10011_00011;
  25. assign tsym[ 2] = 10'b10111_00100;
  26. assign tsym[ 3] = 10'b10111_00010;
  27. assign tsym[ 4] = 10'b01011_10001;
  28. assign tsym[ 5] = 10'b01000_11110;
  29. assign tsym[ 6] = 10'b01100_01110;
  30. assign tsym[ 7] = 10'b01001_11100;
  31. assign tsym[ 8] = 10'b10110_01100;
  32. assign tsym[ 9] = 10'b01001_11001;
  33. assign tsym[10] = 10'b01100_11100;
  34. assign tsym[11] = 10'b10110_00110;
  35. assign tsym[12] = 10'b10100_01110;
  36. assign tsym[13] = 10'b10011_10001;
  37. assign tsym[14] = 10'b01011_00011;
  38. assign tsym[15] = 10'b10110_00011;
  39. reg signed [4:0] disparity; // Running disparity/2
  40. reg [9:0] qreg;
  41. assign q = qreg;
  42. reg [7:0] dreg;
  43. reg denreg;
  44. reg [3:0] treg;
  45. reg tenreg;
  46. reg [1:0] creg;
  47. wire signed [3:0] ddisp =
  48. dreg[7] + dreg[6] + dreg[5] + dreg[4] +
  49. dreg[3] + dreg[2] + dreg[1] + dreg[0] - 'sd4;
  50. reg [8:0] dx; // X(N)OR stage output
  51. wire signed [3:0] xdisp = // Does not include dx[8]!
  52. dx[7] + dx[6] + dx[5] + dx[4] +
  53. dx[3] + dx[2] + dx[1] + dx[0] - 'sd4;
  54. always_comb
  55. begin
  56. dx[8] = $signed(ddisp | { 3'd0, ~dreg[0] }) <= 4'sd0;
  57. dx[0] = dreg[0];
  58. dx[1] = dx[0] ^ dreg[1] ^ ~dx[8];
  59. dx[2] = dx[1] ^ dreg[2] ^ ~dx[8];
  60. dx[3] = dx[2] ^ dreg[3] ^ ~dx[8];
  61. dx[4] = dx[3] ^ dreg[4] ^ ~dx[8];
  62. dx[5] = dx[4] ^ dreg[5] ^ ~dx[8];
  63. dx[6] = dx[5] ^ dreg[6] ^ ~dx[8];
  64. dx[7] = dx[6] ^ dreg[7] ^ ~dx[8];
  65. end // always @ (*)
  66. reg [9:0] dq; // Disparity stage output
  67. always_comb
  68. begin
  69. dq[9] = ((disparity == 5'sd0) | (xdisp == 4'sd0))
  70. ? ~dx[8] : ( disparity[4] == xdisp[3] );
  71. dq[8] = dx[8];
  72. dq[7:0] = dx[7:0] ^ {{8{dq[9]}}};
  73. end
  74. wire signed [3:0] qdisp =
  75. dq[9] + dq[8] + dq[7] + dq[6] + dq[5] +
  76. dq[4] + dq[3] + dq[2] + dq[1] + dq[0] - 'sd5;
  77. always @(negedge rst_n or posedge clk)
  78. if (~rst_n)
  79. begin
  80. disparity <= 'sd0;
  81. qreg <= csym[0];
  82. dreg <= 8'bx;
  83. denreg <= 1'b0;
  84. tenreg <= 1'b0;
  85. treg <= 4'bx;
  86. creg <= 2'b00;
  87. end
  88. else
  89. begin
  90. denreg <= den;
  91. tenreg <= ten;
  92. creg <= c;
  93. treg <= t;
  94. dreg <= d;
  95. if (denreg)
  96. begin
  97. qreg <= dq;
  98. disparity <= disparity + qdisp;
  99. end
  100. else
  101. begin
  102. qreg <= tenreg ? tsym[treg] : csym[creg];
  103. disparity <= 'sd0;
  104. end
  105. end // else: !if(~rst_n)
  106. endmodule // tmdsenc