// // Encodes a word in TMDS 8/10 format // `undef USE_TMDSROM `ifdef USE_TMDSROM module tmdsenc ( input rst_n, input clk, input den, // It is a data word, not a control word input [7:0] d, // Data word input [1:0] c, // Control word output [9:0] q ); reg signed [3:0] disparity; // Running disparity/2 reg [9:0] qreg; assign q = qreg; wire [15:0] romq; tmdsrom tmdsrom ( .clk ( clk ), .d ( d ), .q ( romq ) ); // Delay two cycles to match tmdsrom reg [1:0] denreg; reg [1:0] creg[2]; wire invert = (disparity > 4'sd0 & romq[10]) | (disparity < 4'sd0 & romq[11]); wire cp = creg[1][0]; wire cn = ~creg[1][0]; wire cx = ~creg[1][0] ^ creg[1][1]; // XNOR of C1 and C0 always @(negedge rst_n or posedge clk) if (~rst_n) begin disparity <= 4'sd0; denreg <= 2'b00; creg[0] <= 2'b00; creg[1] <= 2'b00; end else begin denreg <= { denreg[0], den }; creg[0] <= c; creg[1] <= creg[0]; if (denreg[1]) begin qreg <= romq[9:0] ^ (invert ? 10'h2ff : 10'h000); disparity <= invert ? disparity - romq[15:12] : disparity + romq[15:12]; end else begin qreg <= { cx, {4{cn, cp}}, cp }; disparity <= 4'd0; end // else: !if(den) end // else: !if(~rst_n) endmodule // tmdsenc `else // not USE_TMDSROM module tmdsenc ( input rst_n, input clk, input den, // It is a data word, not a control word input [7:0] d, // Data word input [1:0] c, // Control word output [9:0] q ); reg signed [3:0] disparity; // Running disparity/2 reg [9:0] qreg = 10'b11010101000; // Symbol C0 assign q = qreg; reg [7:0] dreg; reg denreg; reg [1:0] creg; wire signed [2:0] delta = ((dreg[7] + dreg[6]) + (dreg[5] + dreg[4])) + ((dreg[3] + dreg[2]) + (dreg[1] + dreg[0])) - 3'sd4; reg [8:0] dx; // X(N)OR stage output always @(*) begin dx[8] = (delta > 3'sd0) | (~&delta & ~dreg[0]); dx[0] = dreg[0]; dx[1] = dx[0] ^ dreg[1] ^ ~dx[8]; dx[2] = dx[1] ^ dreg[2] ^ ~dx[8]; dx[3] = dx[2] ^ dreg[3] ^ ~dx[8]; dx[4] = dx[3] ^ dreg[4] ^ ~dx[8]; dx[5] = dx[4] ^ dreg[5] ^ ~dx[8]; dx[6] = dx[5] ^ dreg[6] ^ ~dx[8]; dx[7] = dx[6] ^ dreg[7] ^ ~dx[8]; end // always @ (*) wire cp = creg[0]; wire cn = ~creg[0]; wire cx = ~creg[0] ^ creg[1]; // XNOR of c[1] and c[0] always @(negedge rst_n or posedge clk) if (~rst_n) begin disparity <= 4'sd0; qreg <= 10'b11010101000; dreg <= 8'hxx; denreg <= 1'b0; creg <= 2'b00; end else begin denreg <= den; creg <= c; dreg <= d; if (denreg) begin if ( (disparity == 4'sd0) | (delta == 3'sd0) ) begin qreg <= { ~dx[8], dx[8], dx[7:0] ^ ~{8{dx[8]}} }; disparity <= dx[8] ? disparity + delta : disparity - delta; end else if ( disparity[3] ^ ~delta[2] ) begin qreg <= { 1'b1, dx[8], ~dx[7:0] }; disparity <= disparity - (delta - dx[8]); end else begin qreg <= { 1'b0, dx[8], dx[7:0] }; disparity <= disparity + (delta - ~dx[8]); end end // if (den) else begin qreg <= { cx, {4{cn, cp}}, cp }; disparity <= 4'sd0; end // else: !if(den) end // else: !if(~rst_n) endmodule // tmdsenc `endif