Last active
February 20, 2023 12:51
-
-
Save alsrgv/b08d35715854642691fed0084c6c1076 to your computer and use it in GitHub Desktop.
TMDS in C++ HLS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include "tmds.h" | |
#include "utils.h" | |
template<int X> | |
ap_uint<log2up(X)> count_ones(ap_uint<X> data) { | |
ap_uint<X> result = data[0]; | |
for (int i = 1; i < 8; i++) { | |
#pragma HLS UNROLL | |
result += data[i]; | |
} | |
return result; | |
} | |
template<int X> | |
ap_uint<X> rolling_xor(ap_uint<X> data) { | |
ap_uint<X> result = data[0]; | |
for (int i = 1; i < 8; i++) { | |
#pragma HLS UNROLL | |
result[i] = result[i - 1] ^ data[i]; | |
} | |
return result; | |
} | |
template<int X> | |
ap_uint<X> rolling_xnor(ap_uint<X> data) { | |
ap_uint<X> result = data[0]; | |
for (int i = 1; i < 8; i++) { | |
#pragma HLS UNROLL | |
result[i] = result[i - 1] ^~ data[i]; | |
} | |
return result; | |
} | |
void tmds_encode(bool disp_ena, ap_uint<2> control, | |
ap_uint<8> d_in, tmds_encoded_t& d_out) { | |
#pragma HLS INTERFACE ap_none port=disp_ena | |
#pragma HLS INTERFACE ap_none port=control | |
#pragma HLS INTERFACE ap_none port=d_in | |
#pragma HLS INTERFACE ap_none register port=d_out | |
#pragma HLS INTERFACE ap_ctrl_none port=return | |
#pragma HLS DATA_PACK variable=d_out | |
#pragma HLS LATENCY min=1 max=1 | |
#pragma HLS PIPELINE | |
#pragma HLS INLINE recursive | |
static ap_int<6> disparity; | |
#pragma HLS RESET variable=disparity | |
auto ones_d_in = count_ones(d_in); | |
auto use_xor = ones_d_in < 4 || (ones_d_in == 4 && (d_in & 1)); | |
auto q_m = use_xor ? rolling_xor(d_in) : rolling_xnor(d_in); | |
auto ones_q_m = count_ones(q_m); | |
auto diff_q_m = ones_q_m - (8 - ones_q_m); | |
bool inv_q_m; | |
if (disparity == 0 && ones_q_m == 4) { | |
// inv_q_m negates xor to preserve balance between ones and zeroes. | |
inv_q_m = !use_xor; | |
} else { | |
inv_q_m = (disparity > 0 && ones_q_m > 4) || (disparity < 0 && ones_q_m < 4); | |
} | |
if (disp_ena) { | |
// Output. | |
d_out.inv_q_m = inv_q_m; | |
d_out.use_xor = use_xor; | |
if (inv_q_m) { | |
d_out.q_m = ~q_m; | |
} else { | |
d_out.q_m = q_m; | |
} | |
// Adjust disparity. | |
if (inv_q_m) { | |
disparity -= diff_q_m - 1; | |
} else { | |
disparity += diff_q_m - 1; | |
} | |
} else { | |
// Output. | |
switch (control) { | |
case 0: | |
d_out = {true, true, 0x54}; | |
break; | |
case 1: | |
d_out = {false, false, 0xab}; | |
break; | |
case 2: | |
d_out = {false, true, 0x54}; | |
break; | |
case 3: | |
d_out = {true, false, 0xab}; | |
break; | |
} | |
// Adjust disparity. | |
disparity = 0; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "ap_int.h" | |
struct tmds_encoded_t { | |
bool inv_q_m; | |
bool use_xor; | |
ap_uint<8> q_m; | |
}; | |
void tmds_encode(bool disp_ena, ap_uint<2> control, | |
ap_uint<8> d_in, tmds_encoded_t& d_out); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "tmds.h" | |
int main() { | |
tmds_encoded_t result; | |
for (int i = 0; i < 10; i++) { | |
tmds_encode(true, 0, 123, result); | |
printf("result: %x\n", result.q_m.to_int()); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
constexpr int log2up(int n) { | |
return n < 2 ? 1 : 1 + log2up(n / 2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment