|
@@ -2,100 +2,72 @@
|
|
|
// 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
|
|
|
+ input den, // It is a data word, not a control word
|
|
|
+ input [7:0] d, // Data word
|
|
|
+ input tercen, // Control data is TERC4 encoded
|
|
|
+ input [3:0] c, // Control or TERC4 word
|
|
|
output [9:0] q
|
|
|
);
|
|
|
|
|
|
- reg signed [3:0] disparity; // Running disparity/2
|
|
|
- reg [9:0] qreg = 10'b11010101000; // Symbol C0
|
|
|
+ // Bit 4 is TERC4 enable
|
|
|
+ function logic [9:0] csym(input tercen, input [4:0] sym);
|
|
|
+ casez ({tercen, sym})
|
|
|
+ // Plain TMDS control symbols
|
|
|
+ 5'b0_??00: csym = 10'b11010_10100;
|
|
|
+ 5'b0_??01: csym = 10'b00101_01011;
|
|
|
+ 5'b0_??10: csym = 10'b01010_10100;
|
|
|
+ 5'b0_??11: csym = 10'b10101_01011;
|
|
|
+
|
|
|
+ // TERC4 control symbols
|
|
|
+ 5'b1_0000: csym = 10'b10100_11100;
|
|
|
+ 5'b1_0001: csym = 10'b1001100011;
|
|
|
+ 5'b1_0010: csym = 10'b1011100100;
|
|
|
+ 5'b1_0011: csym = 10'b1011100010;
|
|
|
+ 5'b1_0100: csym = 10'b0101110001;
|
|
|
+ 5'b1_0101: csym = 10'b0100011110;
|
|
|
+ 5'b1_0110: csym = 10'b0110001110;
|
|
|
+ 5'b1_0111: csym = 10'b0100111100;
|
|
|
+ 5'b1_1000: csym = 10'b1011001100;
|
|
|
+ 5'b1_1001: csym = 10'b0100111001;
|
|
|
+ 5'b1_1010: csym = 10'b0110011100;
|
|
|
+ 5'b1_1011: csym = 10'b1011000110;
|
|
|
+ 5'b1_1100: csym = 10'b1010001110;
|
|
|
+ 5'b1_1101: csym = 10'b1001110001;
|
|
|
+ 5'b1_1110: csym = 10'b0101100011;
|
|
|
+ 5'b1_1111: csym = 10'b1011000011;
|
|
|
+ endcase // casez (sym)
|
|
|
+ endfunction // csym
|
|
|
+
|
|
|
+ function logic [9:0] bitrev10(input [9:0] in);
|
|
|
+ for (int i = 0; i < 10; i++)
|
|
|
+ bitrev10[i] = in[9-i];
|
|
|
+ endfunction // bitrev10
|
|
|
+
|
|
|
+ reg signed [4:0] disparity; // Running disparity/2
|
|
|
+ reg [9:0] qreg;
|
|
|
assign q = qreg;
|
|
|
|
|
|
reg [7:0] dreg;
|
|
|
reg denreg;
|
|
|
- reg [1:0] creg;
|
|
|
+ reg [3:0] creg;
|
|
|
+ reg tercenreg;
|
|
|
|
|
|
- wire signed [2:0] delta =
|
|
|
- ((dreg[7] + dreg[6]) + (dreg[5] + dreg[4])) +
|
|
|
- ((dreg[3] + dreg[2]) + (dreg[1] + dreg[0])) - 3'sd4;
|
|
|
+ wire signed [3:0] ddisp =
|
|
|
+ dreg[7] + dreg[6] + dreg[5] + dreg[4] +
|
|
|
+ dreg[3] + dreg[2] + dreg[1] + dreg[0] - 'sd4;
|
|
|
|
|
|
reg [8:0] dx; // X(N)OR stage output
|
|
|
- always @(*)
|
|
|
+ wire signed [3:0] xdisp = // Does not include dx[8]!
|
|
|
+ dx[7] + dx[6] + dx[5] + dx[4] +
|
|
|
+ dx[3] + dx[2] + dx[1] + dx[0] - 'sd4;
|
|
|
+
|
|
|
+ always_comb
|
|
|
begin
|
|
|
- dx[8] = (delta > 3'sd0) | (~&delta & ~dreg[0]);
|
|
|
+ dx[8] = $signed(ddisp | { 3'd0, ~dreg[0] }) <= 4'sd0;
|
|
|
dx[0] = dreg[0];
|
|
|
dx[1] = dx[0] ^ dreg[1] ^ ~dx[8];
|
|
|
dx[2] = dx[1] ^ dreg[2] ^ ~dx[8];
|
|
@@ -106,50 +78,47 @@ module tmdsenc
|
|
|
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]
|
|
|
+ reg [9:0] dq; // Disparity stage output
|
|
|
+ reg dispsign; // Disparity counter up or down
|
|
|
+
|
|
|
+ always_comb
|
|
|
+ begin
|
|
|
+ dq[9] = ((disparity == 5'sd0) | (xdisp == 4'sd0))
|
|
|
+ ? ~dx[8] : ( disparity[4] == xdisp[3] );
|
|
|
+ dq[8] = dx[8];
|
|
|
+ dq[7:0] = dx[7:0] ^ {{8{dq[9]}}};
|
|
|
+ end
|
|
|
+
|
|
|
+ wire signed [3:0] qdisp =
|
|
|
+ dq[9] + dq[8] + dq[7] + dq[6] + dq[5] +
|
|
|
+ dq[4] + dq[3] + dq[2] + dq[1] + dq[0] - 'sd5;
|
|
|
|
|
|
always @(negedge rst_n or posedge clk)
|
|
|
if (~rst_n)
|
|
|
begin
|
|
|
- disparity <= 4'sd0;
|
|
|
- qreg <= 10'b11010101000;
|
|
|
- dreg <= 8'hxx;
|
|
|
+ dreg <= 'b0;
|
|
|
+ disparity <= 'sd0;
|
|
|
+ qreg <= csym(1'b0, 4'b0000);
|
|
|
denreg <= 1'b0;
|
|
|
creg <= 2'b00;
|
|
|
+ tercenreg <= 1'b0;
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- denreg <= den;
|
|
|
- creg <= c;
|
|
|
- dreg <= d;
|
|
|
+ denreg <= den;
|
|
|
+ tercenreg <= tercen;
|
|
|
+ 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)
|
|
|
+ qreg <= dq;
|
|
|
+ disparity <= disparity + qdisp;
|
|
|
+ end
|
|
|
else
|
|
|
begin
|
|
|
- qreg <= { cx, {4{cn, cp}}, cp };
|
|
|
- disparity <= 4'sd0;
|
|
|
- end // else: !if(den)
|
|
|
+ qreg <= csym(tercenreg, creg);
|
|
|
+ disparity <= 'sd0;
|
|
|
+ end
|
|
|
end // else: !if(~rst_n)
|
|
|
endmodule // tmdsenc
|
|
|
-`endif
|