TMDSenc.v 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. module TMDSenc(
  2. input clk,
  3. input [7:0] data, // video data (red, green or blue)
  4. input blk, // blanking, selects between control code and data
  5. input [1:0] c, // control data
  6. output wire [9:0] q // output
  7. );
  8. wire [3:0] Nb1s = data[0] + data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
  9. wire XNOR = (Nb1s>4'd4) || (Nb1s==4'd4 && data[0]==1'b0);
  10. wire [8:0] q_m = {~XNOR, q_m[6:0] ^ data[7:1] ^ {7{XNOR}}, data[0]};
  11. reg [3:0] balance_acc = 0;
  12. 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;
  13. wire balance_sign_eq = (balance[3] == balance_acc[3]);
  14. wire invert_q_m = (balance==0 || balance_acc==0) ? ~q_m[8] : balance_sign_eq;
  15. wire [3:0] balance_acc_inc = balance - ({q_m[8] ^ ~balance_sign_eq} & ~(balance==0 || balance_acc==0));
  16. wire [3:0] balance_acc_new = invert_q_m ? balance_acc-balance_acc_inc : balance_acc+balance_acc_inc;
  17. wire [9:0] TMDS_data = {invert_q_m, q_m[8], q_m[7:0] ^ {8{invert_q_m}}};
  18. wire [9:0] TMDS_code = c[1] ? (c[0] ? 10'b1010101011 : 10'b0101010100) : (c[0] ? 10'b0010101011 : 10'b1101010100);
  19. assign q = blk ? TMDS_code : TMDS_data;
  20. always @(posedge clk)
  21. begin
  22. balance_acc <= blk ? 4'h0 : balance_acc_new;
  23. end
  24. endmodule