/*************************************************************************************** * This file includes functions that are used to decode integer to binary vectors * or the reverse operation ***************************************************************************************/ #include /* Headers from vtrutil library */ #include "vtr_assert.h" #include "openfpga_decode.h" /* begin namespace openfpga */ namespace openfpga { /******************************************************************** * Convert an integer to an one-hot encoding integer array * For example: * Input integer: 3 * Binary length : 4 * Output: * index | 0 | 1 | 2 | 3 * ret | 0 | 0 | 0 | 1 * * If you need all zero code, set the input integer same as the binary length * For example: * Input integer: 4 * Binary length : 4 * Output: * index | 0 | 1 | 2 | 3 * ret | 0 | 0 | 0 | 0 * ********************************************************************/ std::vector ito1hot_vec(const size_t& in_int, const size_t& bin_len) { /* Make sure we do not have any overflow! */ VTR_ASSERT ( (in_int <= bin_len) ); /* Initialize */ std::vector ret(bin_len, 0); if (bin_len == in_int) { return ret; /* all zero case */ } ret[in_int] = 1; /* Keep a good sequence of bits */ return ret; } /******************************************************************** * Convert an integer to an one-hot encoding character array * For example: * Input integer: 3 * Binary length : 4 * Output: * index | 0 | 1 | 2 | 3 * ret | 0 | 0 | 0 | 1 * * If you need all zero code, set the input integer same as the binary length * For example: * Input integer: 4 * Binary length : 4 * Output: * index | 0 | 1 | 2 | 3 * ret | 0 | 0 | 0 | 0 * ********************************************************************/ std::vector ito1hot_charvec(const size_t& in_int, const size_t& bin_len, const char& default_bit) { /* Make sure we do not have any overflow! */ VTR_ASSERT ( (in_int <= bin_len) ); /* Initialize */ std::vector ret(bin_len, default_bit); if (bin_len == in_int) { return ret; /* all zero case */ } ret[in_int] = '1'; /* Keep a good sequence of bits */ return ret; } void replace_str_bits(std::string& str_to_convert, const char& bit_in_place, const char& bit_to_replace) { for (char& bit : str_to_convert) { if (bit_in_place == bit) { bit = bit_to_replace; } } } std::string combine_two_1hot_str(const std::string& code1, const std::string& code2) { VTR_ASSERT(code1.length() == code2.length()); std::string ret = code1; for (size_t ichar = 0; ichar < code2.length(); ichar++) { VTR_ASSERT('0' == code2[ichar] || '1' == code2[ichar] || 'x' == code2[ichar]); if ('1' == code2[ichar] || '0' == code2[ichar]) { ret[ichar] = code2[ichar]; } } return ret; } /******************************************************************** * Converter an integer to a binary vector * For example: * Input integer: 4 * Binary length : 3 * Output: * index | 0 | 1 | 2 * ret | 0 | 0 | 1 ********************************************************************/ std::vector itobin_vec(const size_t& in_int, const size_t& bin_len) { std::vector ret(bin_len, 0); /* Make sure we do not have any overflow! */ VTR_ASSERT ( (in_int < pow(2., bin_len)) ); size_t temp = in_int; for (size_t i = 0; i < bin_len; i++) { if (1 == temp % 2) { ret[i] = 1; /* Keep a good sequence of bits */ } temp = temp / 2; } return ret; } /******************************************************************** * Converter an integer to a binary vector * For example: * Input integer: 4 * Binary length : 3 * Output: * index | 0 | 1 | 2 * ret | 0 | 0 | 1 * * This function is optimized to return a vector of char * which has a smaller memory footprint than size_t ********************************************************************/ std::vector itobin_charvec(const size_t& in_int, const size_t& bin_len) { std::vector ret(bin_len, '0'); /* Make sure we do not have any overflow! */ VTR_ASSERT ( (in_int < pow(2., bin_len)) ); size_t temp = in_int; for (size_t i = 0; i < bin_len; i++) { if (1 == temp % 2) { ret[i] = '1'; /* Keep a good sequence of bits */ } temp = temp / 2; } return ret; } /******************************************************************** * Converter a binary vector to an integer * For example: * Binary length : 3 * Input: * index | 0 | 1 | 2 * ret | 0 | 0 | 1 * * Output integer: 4 * * This function is optimized to return a vector of char * which has a smaller memory footprint than size_t ********************************************************************/ size_t bintoi_charvec(const std::vector& bin) { size_t ret = 0; for (size_t i = 0; i < bin.size(); ++i) { if ('1' == bin[i]) { ret += pow(2., i); } } return ret; } /******************************************************************** * Expand all the don't care bits in a string * A don't care 'x' can be decoded to either '0' or '1' * For example: * input: 0x1x * output: 0010 * 0100 * 0101 * 0011 * * Return all the strings ********************************************************************/ std::vector expand_dont_care_bin_str(const std::string& input_str) { std::vector ret; /* If the input is don't care free, we can retrun */ bool has_dont_care = false; for (const char& bit : input_str) { if (DONT_CARE_CHAR == bit) { has_dont_care = true; break; } } if (false == has_dont_care) { ret.push_back(input_str); return ret; } /* Recusively expand all the don't bits */ for (size_t i = 0; i < input_str.length(); ++i) { if (DONT_CARE_CHAR == input_str[i]) { std::string temp_input_str = input_str; /* Flip to '0' and go recursively */ temp_input_str[i] = '0'; for (const std::string& expanded_str : expand_dont_care_bin_str(temp_input_str)) { ret.push_back(expanded_str); } /* Flip to '1' and go recursively */ temp_input_str[i] = '1'; for (const std::string& expanded_str : expand_dont_care_bin_str(temp_input_str)) { ret.push_back(expanded_str); } break; } } return ret; } } /* end namespace openfpga */