// // Encodes a word in TMDS 8/10 format // 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 tercen, // Control data is TERC4 encoded input [3:0] c, // Control or TERC4 word output [9:0] q ); // 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 [3:0] creg; reg tercenreg; 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 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] = $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]; 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 @ (*) 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 dreg <= 'b0; disparity <= 'sd0; qreg <= csym(1'b0, 4'b0000); denreg <= 1'b0; creg <= 2'b00; tercenreg <= 1'b0; end else begin denreg <= den; tercenreg <= tercen; creg <= c; dreg <= d; if (denreg) begin qreg <= dq; disparity <= disparity + qdisp; end else begin qreg <= csym(tercenreg, creg); disparity <= 'sd0; end end // else: !if(~rst_n) endmodule // tmdsenc