2
0

tmdsenc.sv 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //
  2. // Encodes a word in TMDS 8/10 format
  3. //
  4. `undef USE_TMDSROM
  5. `ifdef USE_TMDSROM
  6. module tmdsenc
  7. (
  8. input rst_n,
  9. input clk,
  10. input den, // It is a data word, not a control word
  11. input [7:0] d, // Data word
  12. input [1:0] c, // Control word
  13. output [9:0] q
  14. );
  15. reg signed [3:0] disparity; // Running disparity/2
  16. reg [9:0] qreg;
  17. assign q = qreg;
  18. wire [15:0] romq;
  19. tmdsrom tmdsrom (
  20. .clk ( clk ),
  21. .d ( d ),
  22. .q ( romq )
  23. );
  24. // Delay two cycles to match tmdsrom
  25. reg [1:0] denreg;
  26. reg [1:0] creg[2];
  27. wire invert =
  28. (disparity > 4'sd0 & romq[10]) |
  29. (disparity < 4'sd0 & romq[11]);
  30. wire cp = creg[1][0];
  31. wire cn = ~creg[1][0];
  32. wire cx = ~creg[1][0] ^ creg[1][1]; // XNOR of C1 and C0
  33. always @(negedge rst_n or posedge clk)
  34. if (~rst_n)
  35. begin
  36. disparity <= 4'sd0;
  37. denreg <= 2'b00;
  38. creg[0] <= 2'b00;
  39. creg[1] <= 2'b00;
  40. end
  41. else
  42. begin
  43. denreg <= { denreg[0], den };
  44. creg[0] <= c;
  45. creg[1] <= creg[0];
  46. if (denreg[1])
  47. begin
  48. qreg <= romq[9:0] ^ (invert ? 10'h2ff : 10'h000);
  49. disparity <= invert ?
  50. disparity - romq[15:12] :
  51. disparity + romq[15:12];
  52. end
  53. else
  54. begin
  55. qreg <= { cx, {4{cn, cp}}, cp };
  56. disparity <= 4'd0;
  57. end // else: !if(den)
  58. end // else: !if(~rst_n)
  59. endmodule // tmdsenc
  60. `else // not USE_TMDSROM
  61. module tmdsenc
  62. (
  63. input rst_n,
  64. input clk,
  65. input den, // It is a data word, not a control word
  66. input [7:0] d, // Data word
  67. input [1:0] c, // Control word
  68. output [9:0] q
  69. );
  70. reg signed [3:0] disparity; // Running disparity/2
  71. reg [9:0] qreg = 10'b11010101000; // Symbol C0
  72. assign q = qreg;
  73. reg [7:0] dreg;
  74. reg denreg;
  75. reg [1:0] creg;
  76. wire signed [2:0] delta =
  77. ((dreg[7] + dreg[6]) + (dreg[5] + dreg[4])) +
  78. ((dreg[3] + dreg[2]) + (dreg[1] + dreg[0])) - 3'sd4;
  79. reg [8:0] dx; // X(N)OR stage output
  80. always @(*)
  81. begin
  82. dx[8] = (delta > 3'sd0) | (~&delta & ~dreg[0]);
  83. dx[0] = dreg[0];
  84. dx[1] = dx[0] ^ dreg[1] ^ ~dx[8];
  85. dx[2] = dx[1] ^ dreg[2] ^ ~dx[8];
  86. dx[3] = dx[2] ^ dreg[3] ^ ~dx[8];
  87. dx[4] = dx[3] ^ dreg[4] ^ ~dx[8];
  88. dx[5] = dx[4] ^ dreg[5] ^ ~dx[8];
  89. dx[6] = dx[5] ^ dreg[6] ^ ~dx[8];
  90. dx[7] = dx[6] ^ dreg[7] ^ ~dx[8];
  91. end // always @ (*)
  92. wire cp = creg[0];
  93. wire cn = ~creg[0];
  94. wire cx = ~creg[0] ^ creg[1]; // XNOR of c[1] and c[0]
  95. always @(negedge rst_n or posedge clk)
  96. if (~rst_n)
  97. begin
  98. disparity <= 4'sd0;
  99. qreg <= 10'b11010101000;
  100. dreg <= 8'hxx;
  101. denreg <= 1'b0;
  102. creg <= 2'b00;
  103. end
  104. else
  105. begin
  106. denreg <= den;
  107. creg <= c;
  108. dreg <= d;
  109. if (denreg)
  110. begin
  111. if ( (disparity == 4'sd0) | (delta == 3'sd0) )
  112. begin
  113. qreg <= { ~dx[8], dx[8], dx[7:0] ^ ~{8{dx[8]}} };
  114. disparity <= dx[8] ?
  115. disparity + delta :
  116. disparity - delta;
  117. end
  118. else if ( disparity[3] ^ ~delta[2] )
  119. begin
  120. qreg <= { 1'b1, dx[8], ~dx[7:0] };
  121. disparity <= disparity - (delta - dx[8]);
  122. end
  123. else
  124. begin
  125. qreg <= { 1'b0, dx[8], dx[7:0] };
  126. disparity <= disparity + (delta - ~dx[8]);
  127. end
  128. end // if (den)
  129. else
  130. begin
  131. qreg <= { cx, {4{cn, cp}}, cp };
  132. disparity <= 4'sd0;
  133. end // else: !if(den)
  134. end // else: !if(~rst_n)
  135. endmodule // tmdsenc
  136. `endif