tmdsenc.sv 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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, // It is a data word, not a control word
  9. input [7:0] d, // Data word
  10. input tercen, // Control data is TERC4 encoded
  11. input [3:0] c, // Control or TERC4 word
  12. output [9:0] q
  13. );
  14. // Bit 4 is TERC4 enable
  15. function logic [9:0] csym(input tercen, input [4:0] sym);
  16. casez ({tercen, sym})
  17. // Plain TMDS control symbols
  18. 5'b0_??00: csym = 10'b11010_10100;
  19. 5'b0_??01: csym = 10'b00101_01011;
  20. 5'b0_??10: csym = 10'b01010_10100;
  21. 5'b0_??11: csym = 10'b10101_01011;
  22. // TERC4 control symbols
  23. 5'b1_0000: csym = 10'b10100_11100;
  24. 5'b1_0001: csym = 10'b1001100011;
  25. 5'b1_0010: csym = 10'b1011100100;
  26. 5'b1_0011: csym = 10'b1011100010;
  27. 5'b1_0100: csym = 10'b0101110001;
  28. 5'b1_0101: csym = 10'b0100011110;
  29. 5'b1_0110: csym = 10'b0110001110;
  30. 5'b1_0111: csym = 10'b0100111100;
  31. 5'b1_1000: csym = 10'b1011001100;
  32. 5'b1_1001: csym = 10'b0100111001;
  33. 5'b1_1010: csym = 10'b0110011100;
  34. 5'b1_1011: csym = 10'b1011000110;
  35. 5'b1_1100: csym = 10'b1010001110;
  36. 5'b1_1101: csym = 10'b1001110001;
  37. 5'b1_1110: csym = 10'b0101100011;
  38. 5'b1_1111: csym = 10'b1011000011;
  39. endcase // casez (sym)
  40. endfunction // csym
  41. function logic [9:0] bitrev10(input [9:0] in);
  42. for (int i = 0; i < 10; i++)
  43. bitrev10[i] = in[9-i];
  44. endfunction // bitrev10
  45. reg signed [4:0] disparity; // Running disparity/2
  46. reg [9:0] qreg;
  47. assign q = qreg;
  48. reg [7:0] dreg;
  49. reg denreg;
  50. reg [3:0] creg;
  51. reg tercenreg;
  52. wire signed [3:0] ddisp =
  53. dreg[7] + dreg[6] + dreg[5] + dreg[4] +
  54. dreg[3] + dreg[2] + dreg[1] + dreg[0] - 'sd4;
  55. reg [8:0] dx; // X(N)OR stage output
  56. wire signed [3:0] xdisp = // Does not include dx[8]!
  57. dx[7] + dx[6] + dx[5] + dx[4] +
  58. dx[3] + dx[2] + dx[1] + dx[0] - 'sd4;
  59. always_comb
  60. begin
  61. dx[8] = $signed(ddisp | { 3'd0, ~dreg[0] }) <= 4'sd0;
  62. dx[0] = dreg[0];
  63. dx[1] = dx[0] ^ dreg[1] ^ ~dx[8];
  64. dx[2] = dx[1] ^ dreg[2] ^ ~dx[8];
  65. dx[3] = dx[2] ^ dreg[3] ^ ~dx[8];
  66. dx[4] = dx[3] ^ dreg[4] ^ ~dx[8];
  67. dx[5] = dx[4] ^ dreg[5] ^ ~dx[8];
  68. dx[6] = dx[5] ^ dreg[6] ^ ~dx[8];
  69. dx[7] = dx[6] ^ dreg[7] ^ ~dx[8];
  70. end // always @ (*)
  71. reg [9:0] dq; // Disparity stage output
  72. reg dispsign; // Disparity counter up or down
  73. always_comb
  74. begin
  75. dq[9] = ((disparity == 5'sd0) | (xdisp == 4'sd0))
  76. ? ~dx[8] : ( disparity[4] == xdisp[3] );
  77. dq[8] = dx[8];
  78. dq[7:0] = dx[7:0] ^ {{8{dq[9]}}};
  79. end
  80. wire signed [3:0] qdisp =
  81. dq[9] + dq[8] + dq[7] + dq[6] + dq[5] +
  82. dq[4] + dq[3] + dq[2] + dq[1] + dq[0] - 'sd5;
  83. always @(negedge rst_n or posedge clk)
  84. if (~rst_n)
  85. begin
  86. dreg <= 'b0;
  87. disparity <= 'sd0;
  88. qreg <= csym(1'b0, 4'b0000);
  89. denreg <= 1'b0;
  90. creg <= 2'b00;
  91. tercenreg <= 1'b0;
  92. end
  93. else
  94. begin
  95. denreg <= den;
  96. tercenreg <= tercen;
  97. creg <= c;
  98. dreg <= d;
  99. if (denreg)
  100. begin
  101. qreg <= dq;
  102. disparity <= disparity + qdisp;
  103. end
  104. else
  105. begin
  106. qreg <= csym(tercenreg, creg);
  107. disparity <= 'sd0;
  108. end
  109. end // else: !if(~rst_n)
  110. endmodule // tmdsenc