From 4eb046760b4acf1e4ade6f42953dd0c11e9ea272 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 15 Aug 2019 21:57:59 -0600 Subject: [PATCH] still fixing the bug for local encoders, spot one in the special basis, ongoing bugfix --- .../fpga_x2p/base/fpga_x2p_bitstream_utils.c | 8 +- .../SRC/fpga_x2p/base/fpga_x2p_mux_utils.c | 23 ++-- .../vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c | 27 ++++- .../vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h | 2 + .../SRC/fpga_x2p/verilog/verilog_submodules.c | 112 +++++++++--------- 5 files changed, 100 insertions(+), 72 deletions(-) diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c index 127cc0adb..844eb16e3 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_bitstream_utils.c @@ -199,9 +199,9 @@ int count_num_sram_bits_one_mux_spice_model(t_spice_model* cur_spice_model, if ( (TRUE == cur_spice_model->design_tech_info.mux_info->local_encoder) && (2 < num_input_size) ) { if (SPICE_MODEL_STRUCTURE_ONELEVEL == cur_spice_model->design_tech_info.mux_info->structure) { - num_sram_bits = ceil(log(num_sram_bits + 1) / log(2)); + num_sram_bits = determine_mux_local_encoder_num_inputs(num_sram_bits); } else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.mux_info->structure) { - num_sram_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level * ceil(log(num_sram_bits / cur_spice_model->design_tech_info.mux_info->mux_num_level + 1) / log(2)); + num_sram_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level * determine_mux_local_encoder_num_inputs(num_sram_bits / cur_spice_model->design_tech_info.mux_info->mux_num_level); } } break; @@ -721,9 +721,9 @@ int count_num_conf_bits_one_mux_spice_model(t_spice_model* cur_spice_model, if ( (TRUE == cur_spice_model->design_tech_info.mux_info->local_encoder) && (2 < num_input_size) ) { if (SPICE_MODEL_STRUCTURE_ONELEVEL == cur_spice_model->design_tech_info.mux_info->structure) { - num_conf_bits = ceil(log(num_conf_bits + 1) / log(2)); + num_conf_bits = determine_mux_local_encoder_num_inputs(num_conf_bits); } else if (SPICE_MODEL_STRUCTURE_MULTILEVEL == cur_spice_model->design_tech_info.mux_info->structure) { - num_conf_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level * ceil(log(num_conf_bits / cur_spice_model->design_tech_info.mux_info->mux_num_level + 1) / log(2)); + num_conf_bits = cur_spice_model->design_tech_info.mux_info->mux_num_level * determine_mux_local_encoder_num_inputs(num_conf_bits / cur_spice_model->design_tech_info.mux_info->mux_num_level); } } break; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c index f47574b08..5e031e0c3 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_mux_utils.c @@ -204,7 +204,7 @@ int multilevel_mux_last_level_input_num(int num_level, int num_input_per_unit, * 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)); + return ceil(log(num_outputs) / log(2)); } /* Decoding a one-level MUX: @@ -233,8 +233,8 @@ int* decode_onelevel_mux_sram_bits(int fan_in, 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 + * For example: when path_id=3 (use the 4th input), using a 4-input encoder + * the sram_bits will be the 4-digit binary number of 3: 0100 */ ret = my_itobin_int(path_id, num_sram_bits); } else { @@ -325,20 +325,25 @@ int* decode_multilevel_mux_sram_bits(int fan_in, /* 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 end_idx = num_input_basis * (ilvl + 1); + int encoded_path_id = -1; int checker = 0; for (int idx = start_idx; idx < end_idx; ++idx) { - if ('1' == ret[idx]) { + if (1 == ret[idx]) { checker++; - encoded_path_id = idx; + encoded_path_id = idx - start_idx; } } /* There should be at most one '1' */ assert( (0 == checker) || (1 == checker)); + /* If all-zero bits are found, it means that the stage is not used, assign to the last input by default */ + if (0 == checker) { + encoded_path_id = num_input_basis - 1; + } + assert (-1 != encoded_path_id); /* 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 + * For example: when path_id=3 (use the 4th input), using a 4-input encoder + * the sram_bits will be the 4-digit binary number of 3: 0100 */ int* tmp_bits = my_itobin_int(encoded_path_id, num_bits_per_level); /* Copy tmp_bits to encoded bits */ diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c index c30ac6926..5166a27a7 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.c @@ -153,6 +153,7 @@ int create_dir_path(char* dir_path) { exit(1); return 0; } + return 0; } /* Cat string2 to the end of string1 */ @@ -576,6 +577,28 @@ t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib, return ret; } +/* Convert an integer to an one-hot encoding integer array */ +char* my_ito1hot(int in_int, int bin_len) { + char* ret = (char*) my_calloc (bin_len + 1, sizeof(char)); + + /* Make sure we do not have any overflow! */ + if (! ( (-1 < in_int) && (in_int <= bin_len) ) ) + assert ( (-1 < in_int) && (in_int <= bin_len) ); + + /* Initialize */ + for (int i = 0; i < bin_len - 1; i++) { + ret[i] = '0'; + } + sprintf(ret + bin_len - 1, "%s", "0"); + + if (bin_len == in_int) { + return ret; /* all zero case */ + } + ret[in_int] = '1'; /* Keep a good sequence of bits */ + + 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)); @@ -588,7 +611,7 @@ int* my_itobin_int(int in_int, int bin_len) { temp = in_int; for (i = 0; i < bin_len; i++) { if (1 == temp % 2) { - ret[i] = 1; + ret[i] = 1; /* Keep a good sequence of bits */ } temp = temp / 2; } @@ -596,7 +619,6 @@ int* my_itobin_int(int in_int, int bin_len) { return ret; } - /* Converter an integer to a binary string */ char* my_itobin(int in_int, int bin_len) { char* ret = (char*) my_calloc (bin_len + 1, sizeof(char)); @@ -622,6 +644,7 @@ char* my_itobin(int in_int, int bin_len) { return ret; } + /* Convert a integer to a string*/ char* my_itoa(int input) { char* ret = NULL; diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h index b488456e6..bf8d0beaa 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/base/fpga_x2p_utils.h @@ -58,6 +58,8 @@ t_spice_model_port** find_spice_model_config_done_ports(t_spice_model* spice_mod t_spice_transistor_type* find_mosfet_tech_lib(t_spice_tech_lib tech_lib, e_spice_trans_type trans_type); +char* my_ito1hot(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); diff --git a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c index a820a5102..9f0369d9a 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c @@ -1497,10 +1497,10 @@ void dump_verilog_cmos_mux_multilevel_structure(FILE* fp, if (TRUE == spice_model.design_tech_info.mux_info->local_encoder) { /* Print local wires for local encoders */ - fprintf(fp, "wire [%d:0] %s_data;\n", + fprintf(fp, "wire [0:%d] %s_data;\n", spice_mux_arch.num_level * spice_mux_arch.num_input_basis - 1, sram_port[0]->prefix); - fprintf(fp, "wire [%d:0] %s_data_inv;\n", + fprintf(fp, "wire [0:%d] %s_data_inv;\n", spice_mux_arch.num_level * spice_mux_arch.num_input_basis - 1, sram_port[0]->prefix); } @@ -1670,6 +1670,37 @@ void dump_verilog_cmos_mux_onelevel_structure(FILE* fp, fprintf(fp, "wire [0:%d] mux2_l%d_in; \n", spice_mux_arch.num_input - 1, 1); /* input0 */ fprintf(fp, "wire [0:%d] mux2_l%d_in; \n", 0, 0); /* output */ + /* Instanciate local encoder circuit here */ + if ( (TRUE == spice_model.design_tech_info.mux_info->local_encoder) + && ( 2 < spice_mux_arch.num_input) ) { + /* Get the number of inputs */ + int num_outputs = spice_mux_arch.num_input; + int num_inputs = determine_mux_local_encoder_num_inputs(num_outputs); + + /* Print local wires for local encoders */ + fprintf(fp, "wire [0:%d] %s_data;\n", + spice_mux_arch.num_input - 1, + sram_port[0]->prefix); + fprintf(fp, "wire [0:%d] %s_data_inv;\n", + spice_mux_arch.num_input - 1, + sram_port[0]->prefix); + /* Find the decoder name */ + fprintf(fp, "%s %s_0_ (", + generate_verilog_decoder_subckt_name(num_inputs, num_outputs), + generate_verilog_decoder_subckt_name(num_inputs, num_outputs)); + if (true == is_explicit_mapping) { + fprintf(fp, ".addr(%s), .data(%s_data), .data_inv(%s_data_inv) );\n", + sram_port[0]->prefix, + sram_port[0]->prefix, + sram_port[0]->prefix); + } else { + fprintf(fp, "%s, %s_data, %s_data_inv);\n", + sram_port[0]->prefix, + sram_port[0]->prefix, + sram_port[0]->prefix); + } + } + fprintf(fp, "%s mux_basis (\n", mux_basis_subckt_name); /* given_name */ /* Dump global ports */ if (0 < rec_dump_verilog_spice_model_global_ports(fp, &spice_model, FALSE, FALSE, @@ -1740,38 +1771,6 @@ void dump_verilog_cmos_mux_onelevel_structure(FILE* fp, } fprintf(fp, "\n"); fprintf(fp, ");\n"); - - if (2 < spice_mux_arch.num_input) { - /* Instanciate local encoder circuit here */ - if (TRUE == spice_model.design_tech_info.mux_info->local_encoder) { - /* Get the number of inputs */ - int num_outputs = spice_mux_arch.num_input - 1; - int num_inputs = determine_mux_local_encoder_num_inputs(num_outputs); - - /* Print local wires for local encoders */ - fprintf(fp, "wire [%d:0] %s_data;\n", - spice_mux_arch.num_input - 1, - sram_port[0]->prefix); - fprintf(fp, "wire [%d:0] %s_data_inv;\n", - spice_mux_arch.num_input - 1, - sram_port[0]->prefix); - /* Find the decoder name */ - fprintf(fp, "%s %s_0_ (", - generate_verilog_decoder_subckt_name(num_inputs, num_outputs), - generate_verilog_decoder_subckt_name(num_inputs, num_outputs)); - if (true == is_explicit_mapping) { - fprintf(fp, ".addr(%s), .data(%s_data), .data_inv(%s_data_inv) );\n", - sram_port[0]->prefix, - sram_port[0]->prefix, - sram_port[0]->prefix); - } else { - fprintf(fp, "%s, %s_data, %s_data_inv);\n", - sram_port[0]->prefix, - sram_port[0]->prefix, - sram_port[0]->prefix); - } - } - } return; } @@ -2870,9 +2869,8 @@ void dump_verilog_submodule_muxes(t_sram_orgz_info* cur_sram_orgz_info, * 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 + * Considering this fact, there are only num_of_outputs conditions to be encoded. + * Therefore, the number of inputs is ceil(log(num_of_outputs)/log(2)) ***************************************************************************************/ static void dump_verilog_mux_local_encoder_module(FILE* fp, int num_outputs) { @@ -2901,7 +2899,8 @@ void dump_verilog_mux_local_encoder_module(FILE* fp, int num_outputs) { 0, num_inputs - 1); fprintf(fp, ",\n"); /* Outputs */ - dump_verilog_generic_port(fp, VERILOG_PORT_OUTPUT, + fprintf(fp, "output "); + dump_verilog_generic_port(fp, VERILOG_PORT_REG, "data", 0, num_outputs - 1); fprintf(fp, ",\n"); @@ -2910,11 +2909,6 @@ void dump_verilog_mux_local_encoder_module(FILE* fp, int num_outputs) { 0, num_outputs - 1); fprintf(fp, "\n);\n"); - dump_verilog_generic_port(fp, VERILOG_PORT_REG, - "data_reg", - 0, num_outputs - 1); - fprintf(fp, ";\n"); - /* Print the truth table of this encoder */ /* Internal logics */ /* We use a magic number -1 as the addr=1 should be mapped to ...1 @@ -2925,23 +2919,27 @@ void dump_verilog_mux_local_encoder_module(FILE* fp, int num_outputs) { * will give a all-zero code * For example: * data is 5-bit while addr is 3-bit - * data=8'b0_0000 is reserved by addr=3'b000; - * data=8'b0_0001 will be encoded to addr=3'b001; - * data=8'b0_0010 will be encoded to addr=3'b010; - * data=8'b0_0100 will be encoded to addr=3'b011; - * data=8'b0_1000 will be encoded to addr=3'b100; - * data=8'b1_0000 will be encoded to addr=3'b101; + * data=8'b0_0000 will be encoded to addr=3'b001; + * data=8'b0_0001 will be encoded to addr=3'b010; + * data=8'b0_0010 will be encoded to addr=3'b011; + * data=8'b0_0100 will be encoded to addr=3'b100; + * data=8'b0_1000 will be encoded to addr=3'b101; + * data=8'b1_0000 will be encoded to addr=3'b110; * The rest of addr codes 3'b110, 3'b111 will be decoded to data=8'b0_0000; */ - fprintf(fp, "always@(addr, data)\n"); - fprintf(fp, "begin\n"); - fprintf(fp, "\tdata_reg = %d'b0;\n", num_outputs); - fprintf(fp, "\tif ((0 < addr) && (addr < %d) ) begin\n", num_outputs); - fprintf(fp, "\t\tdata_reg = 1'b1 << (addr - 1);\n"); - fprintf(fp, "\tend\n"); - fprintf(fp, "end\n"); - fprintf(fp, "assign data = data_reg;\n"); + fprintf(fp, "always@(addr)\n"); + fprintf(fp, "case (addr)\n"); + /* Create a string for addr and data */ + for (int i = 0; i < num_outputs; ++i) { + fprintf(fp, "\t%d'b%s : data = %d'b%s;\n", + num_inputs, my_itobin(i, num_inputs), + num_outputs, my_ito1hot(i, num_outputs)); + } + fprintf(fp, "\tdefault : data = %d'b%s;\n", + num_outputs, my_ito1hot(num_outputs, num_outputs)); + fprintf(fp, "endcase\n"); + fprintf(fp, "assign data_inv = ~data;\n");