updated bitstream generator for local encoders

This commit is contained in:
tangxifan 2019-08-02 22:55:21 -06:00
parent 557b1af633
commit 386bddacd1
5 changed files with 121 additions and 24 deletions

View File

@ -187,6 +187,26 @@ int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit,
return ret; return ret;
} }
/***************************************************************************************
* Find the number of inputs for a encoder with a given output size
* Inputs
* | | | | |
* +-----------+
* / \
* / Encoder \
* +-----------------+
* | | | | | | | |
* Outputs
*
* The outputs are assumes to be one-hot codes (at most only one '1' exist)
* Considering this fact, there are only num_of_outputs + 1 conditions to be encoded.
* Therefore, the number of inputs is ceil(log(num_of_outputs+1)/log(2))
* We plus 1, which is all-zero condition for outputs
***************************************************************************************/
int determine_mux_local_encoder_num_inputs(int num_outputs) {
return ceil(log(num_outputs + 1) / log(2));
}
/* Decoding a one-level MUX: /* Decoding a one-level MUX:
* SPICE/Verilog model declare the sram port sequence as follows: * SPICE/Verilog model declare the sram port sequence as follows:
* sel0, sel1, ... , selN, * sel0, sel1, ... , selN,
@ -198,24 +218,36 @@ int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit,
*/ */
int* decode_onelevel_mux_sram_bits(int fan_in, int* decode_onelevel_mux_sram_bits(int fan_in,
int mux_level, int mux_level,
int path_id) { int path_id,
int* ret = (int*)my_malloc(sizeof(int)*fan_in); boolean use_local_encoder) {
int i;
/* Check */ /* Check */
assert( (!(0 > path_id)) && (path_id < fan_in) ); assert( (!(0 > path_id)) && (path_id < fan_in) );
for (i = 0; i < fan_in; i++) { /* If we use local encoder, we have a different number of sram bits! */
ret[i] = 0; int num_sram_bits = fan_in;
if (TRUE == use_local_encoder) {
num_sram_bits = determine_mux_local_encoder_num_inputs(fan_in);
}
/* Allocate sram_bits array to return */
int* ret = (int*)my_calloc(num_sram_bits, sizeof(int));
if (TRUE == use_local_encoder) {
/* The encoder will convert the path_id to a binary number
* For example: when path_id=3, using a 4-input encoder
* the sram_bits will be the 4-digit binary number of 3: 0011
*/
ret = my_itobin_int(path_id, num_sram_bits);
} else {
ret[path_id] = 1;
} }
ret[path_id] = 1;
/* ret[fan_in - 1 - path_id] = 1; */ /* ret[fan_in - 1 - path_id] = 1; */
return ret; return ret;
} }
int* decode_multilevel_mux_sram_bits(int fan_in, int* decode_multilevel_mux_sram_bits(int fan_in,
int mux_level, int mux_level,
int path_id) { int path_id,
boolean use_local_encoder) {
int* ret = NULL; int* ret = NULL;
int i, j, path_differ, temp; int i, j, path_differ, temp;
int num_last_level_input, active_mux_level, active_path_id, num_input_basis; int num_last_level_input, active_mux_level, active_path_id, num_input_basis;
@ -228,7 +260,7 @@ int* decode_multilevel_mux_sram_bits(int fan_in,
switch (mux_level) { switch (mux_level) {
case 1: case 1:
/* Special: 1-level should be have special care !!! */ /* Special: 1-level should be have special care !!! */
return decode_onelevel_mux_sram_bits(fan_in, mux_level, path_id); return decode_onelevel_mux_sram_bits(fan_in, mux_level, path_id, use_local_encoder);
default: default:
assert(1 < mux_level); assert(1 < mux_level);
num_input_basis = determine_num_input_basis_multilevel_mux(fan_in, mux_level); num_input_basis = determine_num_input_basis_multilevel_mux(fan_in, mux_level);
@ -258,12 +290,7 @@ int* decode_multilevel_mux_sram_bits(int fan_in,
} else { } else {
assert(num_last_level_input == fan_in); assert(num_last_level_input == fan_in);
} }
/*
if ((41 == fan_in) && (40 == path_id)) {
printf("num_last_level_input=%d, active_mux_lvl=%d, active_path_id=%d\n",
num_last_level_input, active_mux_level, active_path_id);
}
*/
temp = active_path_id; temp = active_path_id;
for (i = mux_level - 1; i > (mux_level - active_mux_level - 1); i--) { for (i = mux_level - 1; i > (mux_level - active_mux_level - 1); i--) {
for (j = 0; j < num_input_basis; j++) { for (j = 0; j < num_input_basis; j++) {
@ -283,8 +310,49 @@ int* decode_multilevel_mux_sram_bits(int fan_in,
/* Check */ /* Check */
assert(0 == temp); assert(0 == temp);
return ret; /* If we do not use a local encoder, these are the sram bits we want */
if (FALSE == use_local_encoder) {
return ret;
}
/* If we use local encoder, we have a different number of sram bits! */
int num_bits_per_level = determine_mux_local_encoder_num_inputs(num_input_basis);
int num_sram_bits = mux_level * num_bits_per_level;
/* Allocate sram_bits array to return */
int* encoded_ret = (int*)my_calloc(num_sram_bits, sizeof(int));
/* Walk through each level and find the path_id and encode it */
for (int ilvl = 0; ilvl < mux_level; ++ilvl) {
int start_idx = num_input_basis * ilvl;
int end_idx = num_input_basis * (ilvl + 1) - 1;
int encoded_path_id = 0;
int checker = 0;
for (int idx = start_idx; idx < end_idx; ++idx) {
if ('1' == ret[idx]) {
checker++;
encoded_path_id = idx;
}
}
/* There should be at most one '1' */
assert( (0 == checker) || (1 == checker));
/* The encoder will convert the path_id to a binary number
* For example: when path_id=3, using a 4-input encoder
* the sram_bits will be the 4-digit binary number of 3: 0011
*/
int* tmp_bits = my_itobin_int(path_id, num_bits_per_level);
/* Copy tmp_bits to encoded bits */
for (int idx = 0; idx < num_bits_per_level; ++idx) {
encoded_ret[idx + ilvl* num_bits_per_level] = tmp_bits[idx];
}
/* Free */
my_free(tmp_bits);
}
/* Free ret */
my_free(ret);
return encoded_ret;
} }
/* Decode the configuration to sram_bits /* Decode the configuration to sram_bits
@ -428,12 +496,14 @@ void decode_cmos_mux_sram_bits(t_spice_model* mux_spice_model,
case SPICE_MODEL_STRUCTURE_ONELEVEL: case SPICE_MODEL_STRUCTURE_ONELEVEL:
(*mux_level) = 1; (*mux_level) = 1;
(*bit_len) = num_mux_input; (*bit_len) = num_mux_input;
(*conf_bits) = decode_onelevel_mux_sram_bits(num_mux_input, (*mux_level), datapath_id); (*conf_bits) = decode_onelevel_mux_sram_bits(num_mux_input, (*mux_level), datapath_id,
mux_spice_model->design_tech_info.mux_info->local_encoder);
break; break;
case SPICE_MODEL_STRUCTURE_MULTILEVEL: case SPICE_MODEL_STRUCTURE_MULTILEVEL:
(*mux_level) = mux_spice_model->design_tech_info.mux_info->mux_num_level; (*mux_level) = mux_spice_model->design_tech_info.mux_info->mux_num_level;
(*bit_len) = determine_num_input_basis_multilevel_mux(num_mux_input, (*mux_level)) * (*mux_level); (*bit_len) = determine_num_input_basis_multilevel_mux(num_mux_input, (*mux_level)) * (*mux_level);
(*conf_bits) = decode_multilevel_mux_sram_bits(num_mux_input, (*mux_level), datapath_id); (*conf_bits) = decode_multilevel_mux_sram_bits(num_mux_input, (*mux_level), datapath_id,
mux_spice_model->design_tech_info.mux_info->local_encoder);
break; break;
default: default:
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for mux_spice_model (%s)!\n", vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid structure for mux_spice_model (%s)!\n",

View File

@ -17,13 +17,17 @@ int tree_mux_last_level_input_num(int num_level,
int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit, int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit,
int mux_size); int mux_size);
int determine_mux_local_encoder_num_inputs(int num_outputs);
int* decode_onelevel_mux_sram_bits(int fan_in, int* decode_onelevel_mux_sram_bits(int fan_in,
int mux_level, int mux_level,
int path_id); int path_id,
boolean use_local_encoder);
int* decode_multilevel_mux_sram_bits(int fan_in, int* decode_multilevel_mux_sram_bits(int fan_in,
int mux_level, int mux_level,
int path_id); int path_id,
boolean use_local_encoder);
int* decode_tree_mux_sram_bits(int fan_in, int* decode_tree_mux_sram_bits(int fan_in,
int mux_level, int mux_level,

View File

@ -576,6 +576,26 @@ t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib,
return ret; return ret;
} }
/* Converter an integer to a binary string */
int* my_itobin_int(int in_int, int bin_len) {
int* ret = (int*) my_calloc (bin_len, sizeof(int));
int i, temp;
/* Make sure we do not have any overflow! */
assert ( (-1 < in_int) && (in_int < pow(2., bin_len)) );
temp = in_int;
for (i = 0; i < bin_len; i++) {
if (1 == temp % 2) {
ret[i] = 1;
}
temp = temp / 2;
}
return ret;
}
/* Converter an integer to a binary string */ /* Converter an integer to a binary string */
char* my_itobin(int in_int, int bin_len) { char* my_itobin(int in_int, int bin_len) {
char* ret = (char*) my_calloc (bin_len + 1, sizeof(char)); char* ret = (char*) my_calloc (bin_len + 1, sizeof(char));

View File

@ -60,6 +60,8 @@ t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib,
char* my_itobin(int in_int, int bin_len); char* my_itobin(int in_int, int bin_len);
int* my_itobin_int(int in_int, int bin_len);
char* my_itoa(int input); char* my_itoa(int input);
char* fpga_spice_create_one_subckt_filename(const char* file_name_prefix, char* fpga_spice_create_one_subckt_filename(const char* file_name_prefix,

View File

@ -1475,7 +1475,7 @@ void dump_verilog_cmos_mux_multilevel_structure(FILE* fp,
if (TRUE == spice_model.design_tech_info.mux_info->local_encoder) { if (TRUE == spice_model.design_tech_info.mux_info->local_encoder) {
/* Get the number of inputs */ /* Get the number of inputs */
int num_outputs = spice_mux_arch.num_input - 1; int num_outputs = spice_mux_arch.num_input - 1;
int num_inputs = ceil(log(num_outputs + 1) / log(2)); int num_inputs = determine_mux_local_encoder_num_inputs(num_outputs);
/* Find the decoder name */ /* Find the decoder name */
fprintf(fp, "%s %s_0_ (", fprintf(fp, "%s %s_0_ (",
generate_verilog_decoder_subckt_name(num_inputs, num_outputs), generate_verilog_decoder_subckt_name(num_inputs, num_outputs),
@ -1698,7 +1698,8 @@ void dump_verilog_cmos_mux_onelevel_structure(FILE* fp,
if (TRUE == spice_model.design_tech_info.mux_info->local_encoder) { if (TRUE == spice_model.design_tech_info.mux_info->local_encoder) {
/* Get the number of inputs */ /* Get the number of inputs */
int num_outputs = spice_mux_arch.num_input - 1; int num_outputs = spice_mux_arch.num_input - 1;
int num_inputs = ceil(log(num_outputs + 1) / log(2)); int num_inputs = determine_mux_local_encoder_num_inputs(num_outputs);
/* Print local wires for local encoders */ /* Print local wires for local encoders */
fprintf(fp, "wire [%d:0] %s_data;\n", fprintf(fp, "wire [%d:0] %s_data;\n",
spice_mux_arch.num_input - 1, spice_mux_arch.num_input - 1,
@ -2826,7 +2827,7 @@ void dump_verilog_mux_local_encoder_module(FILE* fp, int num_outputs) {
assert (2 <= num_outputs); assert (2 <= num_outputs);
/* Get the number of inputs */ /* Get the number of inputs */
int num_inputs = ceil(log(num_outputs + 1) / log(2)); int num_inputs = determine_mux_local_encoder_num_inputs(num_outputs);
/* Validate the FILE handler */ /* Validate the FILE handler */
if (NULL == fp) { if (NULL == fp) {