updated bitstream generator for local encoders
This commit is contained in:
parent
557b1af633
commit
386bddacd1
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue