still fixing the bug for local encoders, spot one in the special basis, ongoing bugfix
This commit is contained in:
parent
35ad4a87e5
commit
4eb046760b
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
@ -1741,38 +1772,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");
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue