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 27a84e6d1..cb8ca95ef 100644 --- a/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c +++ b/vpr7_x2p/vpr/SRC/fpga_x2p/verilog/verilog_submodules.c @@ -132,544 +132,6 @@ void dump_verilog_submodule_signal_init(FILE* fp, return; } - -/* Dump a module of inverter or buffer or tapered buffer */ -static -void dump_verilog_invbuf_module(FILE* fp, - t_spice_model* invbuf_spice_model) { - int ipin, iport, port_cnt; - int num_input_port = 0; - int num_output_port = 0; - int num_powergate_port = 0; - t_spice_model_port** input_port = NULL; - t_spice_model_port** output_port = NULL; - t_spice_model_port** powergate_port = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler.\n", - __FILE__, __LINE__); - exit(1); - } - - fprintf(fp, "//----- Verilog module for %s -----\n", - invbuf_spice_model->name); - - /* Find the input port, output port*/ - input_port = find_spice_model_ports(invbuf_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_port = find_spice_model_ports(invbuf_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - powergate_port = find_spice_model_config_done_ports(invbuf_spice_model, SPICE_MODEL_PORT_INPUT, &num_powergate_port, FALSE); - - /* Make sure: - * There is only 1 input port and 1 output port, - * each size of which is 1 - */ - assert(1 == num_input_port); - assert(1 == input_port[0]->size); - assert(1 == num_output_port); - assert(1 == output_port[0]->size); - - /* If power-gated, we need to find enable signals */ - if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { - if (0 == num_powergate_port) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Inverter, buffer SPICE model is power-gated, but cannot find any power-gate port!\n", - __FILE__, __LINE__); - exit(1); - } - assert ( 0 < num_powergate_port); - } - - /* dump module body */ - fprintf(fp, "module %s (\n", - invbuf_spice_model->name); - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_lib_global_ports(fp, invbuf_spice_model, TRUE, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - /* Dump ports */ - fprintf(fp, "input [0:0] %s,\n", input_port[0]->lib_name); - fprintf(fp, "output [0:0] %s\n", output_port[0]->lib_name); - fprintf(fp, ");\n"); - /* Finish dumping ports */ - - /* Assign logics : depending on topology */ - switch (invbuf_spice_model->design_tech_info.buffer_info->type) { - case SPICE_MODEL_BUF_INV: - if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { - /* Create a sensitive list */ - fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name); - fprintf(fp, "always @("); - /* Power-gate port first*/ - for (iport = 0; iport < num_powergate_port; iport++) { - fprintf(fp, "%s,", powergate_port[iport]->lib_name); - } - fprintf(fp, "%s) begin\n", - input_port[0]->lib_name); - /* Dump the case of power-gated */ - fprintf(fp, " if ("); - port_cnt = 0; /* Initialize the counter: decide if we need to put down '&&' */ - for (iport = 0; iport < num_powergate_port; iport++) { - if (0 == powergate_port[iport]->default_val) { - for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) { - if ( 0 < port_cnt ) { - fprintf(fp, "\n\t&&"); - } - /* Power-gated signal are disable during operating, enabled during configuration, - * Therefore, we need to reverse them here - */ - fprintf(fp, "(~%s[%d])", - powergate_port[iport]->lib_name, - ipin); - port_cnt++; /* Update port counter*/ - } - } else { - assert (1 == powergate_port[iport]->default_val); - for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) { - if ( 0 < port_cnt ) { - fprintf(fp, "\n\t&&"); - } - /* Power-gated signal are disable during operating, enabled during configuration, - * Therefore, we need to reverse them here - */ - fprintf(fp, "(%s[%d])", - powergate_port[iport]->lib_name, - ipin); - port_cnt++; /* Update port counter*/ - } - } - } - fprintf(fp, ") begin\n"); - fprintf(fp, "\t\tassign %s_reg = ~%s;\n", - output_port[0]->lib_name, - input_port[0]->lib_name); - fprintf(fp, "\tend else begin\n"); - fprintf(fp, "\t\tassign %s_reg = 1'bz;\n", - output_port[0]->lib_name); - fprintf(fp, "\tend\n"); - fprintf(fp, "end\n"); - fprintf(fp, "assign %s = %s_reg;\n", - output_port[0]->lib_name, - output_port[0]->lib_name); - } else { - fprintf(fp, "assign %s = (%s === 1'bz)? $random : ~%s;\n", - output_port[0]->lib_name, - input_port[0]->lib_name, - input_port[0]->lib_name); - } - break; - case SPICE_MODEL_BUF_BUF: - if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { - /* Create a sensitive list */ - fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name); - fprintf(fp, "always @("); - /* Power-gate port first*/ - for (iport = 0; iport < num_powergate_port; iport++) { - fprintf(fp, "%s,", powergate_port[iport]->lib_name); - } - fprintf(fp, "%s) begin\n", - input_port[0]->lib_name); - /* Dump the case of power-gated */ - fprintf(fp, " if ("); - port_cnt = 0; /* Initialize the counter: decide if we need to put down '&&' */ - for (iport = 0; iport < num_powergate_port; iport++) { - if (0 == powergate_port[iport]->default_val) { - for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) { - if ( 0 < port_cnt ) { - fprintf(fp, "\n\t&&"); - } - /* Power-gated signal are disable during operating, enabled during configuration, - * Therefore, we need to reverse them here - */ - fprintf(fp, "(~%s[%d])", - powergate_port[iport]->lib_name, - ipin); - port_cnt++; /* Update port counter*/ - } - } else { - assert (1 == powergate_port[iport]->default_val); - for (ipin = 0; ipin < powergate_port[iport]->size; ipin++) { - if ( 0 < port_cnt ) { - fprintf(fp, "\n\t&&"); - } - /* Power-gated signal are disable during operating, enabled during configuration, - * Therefore, we need to reverse them here - */ - fprintf(fp, "(%s[%d])", - powergate_port[iport]->lib_name, - ipin); - port_cnt++; /* Update port counter*/ - } - } - } - fprintf(fp, ") begin\n"); - fprintf(fp, "\t\tassign %s_reg = %s;\n", - output_port[0]->lib_name, - input_port[0]->lib_name); - fprintf(fp, "\tend else begin\n"); - fprintf(fp, "\t\tassign %s_reg = 1'bz;\n", - output_port[0]->lib_name); - fprintf(fp, "\tend\n"); - fprintf(fp, "end\n"); - fprintf(fp, "assign %s = %s_reg;\n", - output_port[0]->lib_name, - output_port[0]->lib_name); - - } else if (FALSE == invbuf_spice_model->design_tech_info.buffer_info->tapered_buf) { - fprintf(fp, "assign %s = (%s === 1'bz)? $random : %s;\n", - output_port[0]->lib_name, - input_port[0]->lib_name, - input_port[0]->lib_name); - } else { - assert (TRUE == invbuf_spice_model->design_tech_info.buffer_info->tapered_buf); - fprintf(fp, "assign %s = (%s === 1'bz)? $random : ", - output_port[0]->lib_name, - input_port[0]->lib_name); - /* depend on the stage, we may invert the output */ - if (1 == invbuf_spice_model->design_tech_info.buffer_info->tap_buf_level % 2) { - fprintf(fp, "~"); - } - fprintf(fp, "%s;\n", - input_port[0]->lib_name); - } - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid topology for spice model (%s)!\n", - __FILE__, __LINE__, invbuf_spice_model->name); - exit(1); - } - - /* Print timing info */ - dump_verilog_submodule_timing(fp, invbuf_spice_model); - - dump_verilog_submodule_signal_init(fp, invbuf_spice_model); - - fprintf(fp, "endmodule\n"); - - fprintf(fp, "\n"); - - /* Free */ - my_free(input_port); - my_free(output_port); - - return; -} - -/* Dump a module of pass-gate logic */ -static -void dump_verilog_passgate_module(FILE* fp, - t_spice_model* passgate_spice_model) { - int iport; - int num_input_port = 0; - int num_output_port = 0; - t_spice_model_port** input_port = NULL; - t_spice_model_port** output_port = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find the input port, output port*/ - input_port = find_spice_model_ports(passgate_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_port = find_spice_model_ports(passgate_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - - /* Make sure: - * There is only 1 output port, - * each size of which is 1 - */ - assert(1 == num_output_port); - assert(1 == output_port[0]->size); - - fprintf(fp, "//----- Verilog module for %s -----\n", - passgate_spice_model->name); - - /* dump module body */ - fprintf(fp, "module %s (\n", - passgate_spice_model->name); - - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_lib_global_ports(fp, passgate_spice_model, TRUE, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - - /* Assign ports : depending on topology */ - switch (passgate_spice_model->design_tech_info.pass_gate_info->type) { - case SPICE_MODEL_PASS_GATE_TRANSMISSION: - /* Make sure: - * There is only 3 input port (in, sel, selb), - * each size of which is 1 - */ - assert(3 == num_input_port); - for (iport = 0; iport < num_input_port; iport++) { - assert(1 == input_port[iport]->size); - } - /* Dump ports */ - fprintf(fp, "input [0:0] %s,\n", input_port[0]->lib_name); - fprintf(fp, "input [0:0] %s,\n", input_port[1]->lib_name); - fprintf(fp, "input [0:0] %s,\n", input_port[2]->lib_name); - fprintf(fp, "output [0:0] %s\n", output_port[0]->lib_name); - fprintf(fp, ");\n"); - /* Finish dumping ports */ - - break; - case SPICE_MODEL_PASS_GATE_TRANSISTOR: - /* Make sure: - * There is only 2 input port (in, sel), - * each size of which is 1 - */ - assert(2 == num_input_port); - for (iport = 0; iport < num_input_port; iport++) { - assert(1 == input_port[iport]->size); - } - /* Dump ports */ - fprintf(fp, "input [0:0] %s,\n", input_port[0]->lib_name); - fprintf(fp, "input [0:0] %s,\n", input_port[1]->lib_name); - fprintf(fp, "output [0:0] %s\n", output_port[0]->lib_name); - fprintf(fp, ");\n"); - /* Finish dumping ports */ - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid topology for spice model (%s)!\n", - __FILE__, __LINE__, passgate_spice_model->name); - exit(1); - } - - /* Dump logics */ - fprintf(fp, "assign %s = %s? %s : 1'bz;\n", - output_port[0]->lib_name, - input_port[1]->lib_name, - input_port[0]->lib_name); - - /* Print timing info */ - dump_verilog_submodule_timing(fp, passgate_spice_model); - - /* Print signal initialization */ - dump_verilog_submodule_signal_init(fp, passgate_spice_model); - - fprintf(fp, "endmodule\n"); - - fprintf(fp, "\n"); - - /* Free */ - my_free(input_port); - my_free(output_port); - - return; -} - -/* Dump a module of pass-gate logic */ -static -void dump_verilog_gate_module(FILE* fp, - t_spice_model* gate_spice_model) { - int iport, ipin, jport, jpin; - int num_input_port = 0; - int num_output_port = 0; - t_spice_model_port** input_port = NULL; - t_spice_model_port** output_port = NULL; - - /* Ensure a valid file handler*/ - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Invalid File handler.\n", - __FILE__, __LINE__); - exit(1); - } - - /* Find the input port, output port*/ - input_port = find_spice_model_ports(gate_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE); - output_port = find_spice_model_ports(gate_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE); - - /* Make sure: - * There is only 1 output port, - * each size of which is 1 - */ - assert(1 == num_output_port); - assert(1 == output_port[0]->size); - - assert(0 < num_input_port); - - fprintf(fp, "//----- Verilog module for %s -----\n", - gate_spice_model->name); - - /* dump module body */ - fprintf(fp, "module %s (\n", - gate_spice_model->name); - - /* Dump global ports */ - if (0 < rec_dump_verilog_spice_model_lib_global_ports(fp, gate_spice_model, TRUE, FALSE, FALSE)) { - fprintf(fp, ",\n"); - } - - /* Dump ports */ - for (iport = 0; iport < num_input_port; iport++) { - fprintf(fp, "input [0:%d] %s,\n", - input_port[iport]->size - 1, input_port[iport]->lib_name); - } - for (iport = 0; iport < num_output_port; iport++) { - fprintf(fp, "output [0:%d] %s\n", - output_port[iport]->size - 1, output_port[iport]->lib_name); - } - fprintf(fp, ");\n"); - - /* Dump logics */ - switch (gate_spice_model->design_tech_info.gate_info->type) { - case SPICE_MODEL_GATE_AND: - for (iport = 0; iport < num_output_port; iport++) { - for (ipin = 0; ipin < output_port[iport]->size; ipin++) { - fprintf(fp, "assign %s[%d] = ", - output_port[iport]->lib_name, ipin); - for (jport = 0; jport < num_input_port; jport++) { - for (jpin = 0; jpin < input_port[jport]->size; jpin++) { - fprintf(fp, "%s[%d]", - input_port[jport]->lib_name, jpin); - if ((jport == num_input_port - 1) && (jpin == input_port[jport]->size - 1)) { - continue; /* Stop output AND sign for the last element in the loop */ - } - fprintf(fp, " & "); - } - } - fprintf(fp, ";\n"); - } - } - break; - case SPICE_MODEL_GATE_OR: - for (iport = 0; iport < num_output_port; iport++) { - for (ipin = 0; ipin < output_port[iport]->size; ipin++) { - fprintf(fp, "assign %s[%d] = ", - output_port[iport]->lib_name, ipin); - for (jport = 0; jport < num_input_port; jport++) { - for (jpin = 0; jpin < input_port[jport]->size; jpin++) { - fprintf(fp, "%s[%d]", - input_port[jport]->lib_name, jpin); - if ((jport == num_input_port - 1) && (jpin == input_port[jport]->size - 1)) { - continue; /* Stop output AND sign for the last element in the loop */ - } - fprintf(fp, " | "); - } - } - fprintf(fp, ";\n"); - } - } - break; - case SPICE_MODEL_GATE_MUX2: - /* Check on the port sequence and map */ - /* MUX2 should only have 1 output port with size 1 */ - if (1 != num_output_port) { - vpr_printf(TIO_MESSAGE_ERROR, - "(File:%s, [LINE%d]) MUX2 circuit model must have only 1 output!\n", - __FILE__, __LINE__); - exit(1); - } else if (1 != output_port[0]->size) { - vpr_printf(TIO_MESSAGE_ERROR, - "(File:%s, [LINE%d]) Output size of a MUX2 circuit model must be 1!\n", - __FILE__, __LINE__); - exit(1); - } - /* MUX2 should only have 3 output port, each of which has a port size of 1 */ - if (3 != num_input_port) { - vpr_printf(TIO_MESSAGE_ERROR, - "(File:%s, [LINE%d]) MUX2 circuit model must have only 3 input!\n", - __FILE__, __LINE__); - exit(1); - } else { - for (iport = 0; iport < num_input_port; iport++) { - /* Bypass port size of 1 */ - if (1 == input_port[iport]->size) { - continue; - } - vpr_printf(TIO_MESSAGE_ERROR, - "(File:%s, [LINE%d]) Input size MUX2 circuit model must be 1!\n", - __FILE__, __LINE__); - exit(1); - } - } - /* Now, we output the logic of MUX2 - * IMPORTANT Restriction: - * We always assum the first two inputs are data inputs - * the third input is the select port - */ - fprintf(fp, "assign %s[%d] = %s[%d] ? %s[%d] : %s[%d];\n", - output_port[0]->lib_name, 0, - input_port[2]->lib_name, 0, - input_port[0]->lib_name, 0, - input_port[1]->lib_name, 0); - break; - default: - vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid topology for spice model (%s)!\n", - __FILE__, __LINE__, gate_spice_model->name); - exit(1); - } - - - /* Print timing info */ - dump_verilog_submodule_timing(fp, gate_spice_model); - - /* Print signal initialization */ - dump_verilog_submodule_signal_init(fp, gate_spice_model); - - fprintf(fp, "endmodule\n"); - - fprintf(fp, "\n"); - - /* Free */ - my_free(input_port); - my_free(output_port); - - return; -} - -/* Dump Essential modules: - * 1. inverters - * 2. buffers - * 3. pass-gate logics */ -static -void dump_verilog_submodule_essentials(char* verilog_dir, char* submodule_dir, - int num_spice_model, - t_spice_model* spice_models) { - int imodel; - char* verilog_name = my_strcat(submodule_dir, essentials_verilog_file_name); - FILE* fp = NULL; - - /* Create file */ - fp = fopen(verilog_name, "w"); - if (NULL == fp) { - vpr_printf(TIO_MESSAGE_ERROR,"(FILE:%s,LINE[%d])Failure in create Verilog netlist %s", - __FILE__, __LINE__, essentials_verilog_file_name); - exit(1); - } - dump_verilog_file_header(fp,"Essential gates"); - - verilog_include_defines_preproc_file(fp, verilog_dir); - - /* Output essential models*/ - for (imodel = 0; imodel < num_spice_model; imodel++) { - /* By pass user-defined modules */ - if (NULL != spice_models[imodel].verilog_netlist) { - continue; - } - if (SPICE_MODEL_INVBUF == spice_models[imodel].type) { - dump_verilog_invbuf_module(fp, &(spice_models[imodel])); - } - if (SPICE_MODEL_PASSGATE == spice_models[imodel].type) { - dump_verilog_passgate_module(fp, &(spice_models[imodel])); - } - if (SPICE_MODEL_GATE == spice_models[imodel].type) { - dump_verilog_gate_module(fp, &(spice_models[imodel])); - } - } - - /* Close file handler*/ - fclose(fp); - - /* Add fname to the linked list */ - submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_name); - - /* Free */ - - return; -} - /* Dump a CMOS MUX basis module */ static void dump_verilog_cmos_mux_one_basis_module(FILE* fp, @@ -4053,11 +3515,6 @@ void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info, /* 0. basic units: inverter, buffers and pass-gate logics, */ vpr_printf(TIO_MESSAGE_INFO, "Generating essential modules...\n"); - /* To be removed when testing passed - dump_verilog_submodule_essentials(verilog_dir, submodule_dir, - Arch.spice->num_spice_model, - Arch.spice->spice_models); - */ print_verilog_submodule_essentials(std::string(verilog_dir), std::string(submodule_dir), Arch.spice->circuit_lib);