123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- //
- // 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
|