refactored power-gate inverter

This commit is contained in:
tangxifan 2019-08-20 21:56:55 -06:00
parent 19472ace4e
commit a40e5c91ca
6 changed files with 95 additions and 67 deletions

View File

@ -258,6 +258,17 @@ enum e_spice_model_gate_type CircuitLibrary::gate_type(const CircuitModelId& mod
return gate_types_[model_id]; return gate_types_[model_id];
} }
/* Return the type of buffer for a circuit model
* Only applicable for BUF/INV circuit model
*/
enum e_spice_model_buffer_type CircuitLibrary::buffer_type(const CircuitModelId& model_id) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* validate the circuit model type is MUX */
VTR_ASSERT(SPICE_MODEL_INVBUF == model_type(model_id));
return buffer_types_[model_id];
}
/************************************************************************ /************************************************************************
* Public Accessors : Basic data query on Circuit models' Circuit Port * Public Accessors : Basic data query on Circuit models' Circuit Port
***********************************************************************/ ***********************************************************************/

View File

@ -227,6 +227,7 @@ class CircuitLibrary {
bool mux_add_const_input(const CircuitModelId& model_id) const; bool mux_add_const_input(const CircuitModelId& model_id) const;
size_t mux_const_input_value(const CircuitModelId& model_id) const; size_t mux_const_input_value(const CircuitModelId& model_id) const;
enum e_spice_model_gate_type gate_type(const CircuitModelId& model_id) const; enum e_spice_model_gate_type gate_type(const CircuitModelId& model_id) const;
enum e_spice_model_buffer_type buffer_type(const CircuitModelId& model_id) const;
public: /* Public Accessors: Basic data query on cirucit models' Circuit Ports*/ public: /* Public Accessors: Basic data query on cirucit models' Circuit Ports*/
CircuitPortId model_port(const CircuitModelId& model_id, const std::string& name) const; CircuitPortId model_port(const CircuitModelId& model_id, const std::string& name) const;
size_t num_model_ports(const CircuitModelId& model_id) const; size_t num_model_ports(const CircuitModelId& model_id) const;

View File

@ -19,6 +19,66 @@
#include "verilog_writer_utils.h" #include "verilog_writer_utils.h"
#include "verilog_essential_gates.h" #include "verilog_essential_gates.h"
/************************************************
* Print Verilog codes of a power-gated inverter
***********************************************/
static
void print_verilog_power_gated_inv_module(std::fstream& fp,
const CircuitLibrary& circuit_lib,
const CircuitPortId& input_port,
const CircuitPortId& output_port,
const std::vector<CircuitPortId>& power_gate_ports) {
/* Ensure a valid file handler*/
check_file_handler(fp);
fp << "//----- Verilog codes of a power-gated inverter -----" << std::endl;
/* Create a sensitive list */
fp << "\treg " << circuit_lib.port_lib_name(output_port) << "_reg;" << std::endl;
fp << "\talways @(" << std::endl;
/* Power-gate port first*/
for (const auto& power_gate_port : power_gate_ports) {
/* Skip first comma to dump*/
if (0 < &power_gate_port - &power_gate_ports[0]) {
fp << ",";
}
fp << circuit_lib.port_lib_name(power_gate_port);
}
fp << circuit_lib.port_lib_name(input_port) << ") begin" << std::endl;
/* Dump the case of power-gated */
fp << "\t\tif (";
/* For the first pin, we skip output comma */
size_t port_cnt = 0;
for (const auto& power_gate_port : power_gate_ports) {
for (const auto& power_gate_pin : circuit_lib.pins(power_gate_port)) {
if (0 < port_cnt) {
fp << std::endl << "\t\t&&";
}
fp << "(";
/* Power-gated signal are disable during operating, enabled during configuration,
* Therefore, we need to reverse them here
*/
if (0 == circuit_lib.port_default_value(power_gate_port)) {
fp << "~";
}
fp << circuit_lib.port_lib_name(power_gate_port) << "[" << power_gate_pin << "])";
port_cnt++; /* Update port counter*/
}
}
fp << ") begin" << std::endl;
fp << "\t\t\tassign " << circuit_lib.port_lib_name(output_port) << "_reg = ~" << circuit_lib.port_lib_name(input_port) << ";" << std::endl;
fp << "\t\tend else begin" << std::endl;
fp << "\t\t\tassign " << circuit_lib.port_lib_name(output_port) << "_reg = 1'bz;" << std::endl;
fp << "\t\tend" << std::endl;
fp << "\tend" << std::endl;
fp << "\tassign " << circuit_lib.port_lib_name(output_port) << " = " << circuit_lib.port_lib_name(output_port) << "_reg;" << std::endl;
}
/************************************************ /************************************************
* Print a Verilog module of inverter or buffer * Print a Verilog module of inverter or buffer
@ -97,72 +157,20 @@ void print_verilog_invbuf_module(std::fstream& fp,
fp << ");" << std::endl; fp << ");" << std::endl;
/* Finish dumping ports */ /* Finish dumping ports */
// /* Assign logics : depending on topology */ /* Assign logics : depending on topology */
// switch (invbuf_spice_model->design_tech_info.buffer_info->type) { switch (circuit_lib.buffer_type(circuit_model)) {
// case SPICE_MODEL_BUF_INV: case SPICE_MODEL_BUF_INV:
// if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { if (TRUE == circuit_lib.is_power_gated(circuit_model)) {
// /* Create a sensitive list */ print_verilog_power_gated_inv_module(fp, circuit_lib, input_ports[0], output_ports[0], global_ports);
// 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 { // } else {
// fprintf(fp, "assign %s = (%s === 1'bz)? $random : ~%s;\n", // fprintf(fp, "assign %s = (%s === 1'bz)? $random : ~%s;\n",
// output_port[0]->lib_name, // output_port[0]->lib_name,
// input_port[0]->lib_name, // input_port[0]->lib_name,
// input_port[0]->lib_name); // input_port[0]->lib_name);
// } // }
// break; break;
// case SPICE_MODEL_BUF_BUF: case SPICE_MODEL_BUF_BUF:
// if (TRUE == invbuf_spice_model->design_tech_info.power_gated) { // if (TRUE == invbuf_spice_model->design_tech_info.power_gated) {
// /* Create a sensitive list */ // /* Create a sensitive list */
// fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name); // fprintf(fp, "reg %s_reg;\n", output_port[0]->lib_name);
@ -236,12 +244,13 @@ void print_verilog_invbuf_module(std::fstream& fp,
// fprintf(fp, "%s;\n", // fprintf(fp, "%s;\n",
// input_port[0]->lib_name); // input_port[0]->lib_name);
// } // }
// break; break;
// default: default:
// vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid topology for spice model (%s)!\n", vpr_printf(TIO_MESSAGE_ERROR,
// __FILE__, __LINE__, invbuf_spice_model->name); "(File:%s,[LINE%d])Invalid topology for circuit model (name=%s)!\n",
// exit(1); __FILE__, __LINE__, circuit_lib.model_name(circuit_model));
// } exit(1);
}
// //
// /* Print timing info */ // /* Print timing info */
// dump_verilog_submodule_timing(fp, invbuf_spice_model); // dump_verilog_submodule_timing(fp, invbuf_spice_model);
@ -302,7 +311,9 @@ void print_verilog_submodule_essentials(const std::string& verilog_dir,
fp.close(); fp.close();
/* Add fname to the linked list */ /* Add fname to the linked list */
/* TODO: enable this when this function is completed
submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_fname.c_str()); submodule_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(submodule_verilog_subckt_file_path_head, verilog_fname.c_str());
*/
return; return;
} }

View File

@ -120,6 +120,7 @@ void generate_verilog_cmos_mux_branch_module_structural(std::fstream& fp,
* When mem = 1, propagate input 0; * When mem = 1, propagate input 0;
* when mem = 0, propagate input 1; * when mem = 0, propagate input 1;
*/ */
/* TODO: we should output the netlist following the connections in mux_graph */
if (1 == num_mems) { if (1 == num_mems) {
/* Transmission gates are connected to each input and also the output*/ /* Transmission gates are connected to each input and also the output*/
fp << "\t" << circuit_lib.model_name(tgate_model) << " " << circuit_lib.model_prefix(tgate_model) << "_0 "; fp << "\t" << circuit_lib.model_name(tgate_model) << " " << circuit_lib.model_prefix(tgate_model) << "_0 ";

View File

@ -40,6 +40,7 @@
#include "mux_utils.h" #include "mux_utils.h"
#include "verilog_mux.h" #include "verilog_mux.h"
#include "verilog_essential_gates.h"
/***** Subroutines *****/ /***** Subroutines *****/
@ -4055,6 +4056,9 @@ void dump_verilog_submodules(t_sram_orgz_info* cur_sram_orgz_info,
dump_verilog_submodule_essentials(verilog_dir, submodule_dir, dump_verilog_submodule_essentials(verilog_dir, submodule_dir,
Arch.spice->num_spice_model, Arch.spice->num_spice_model,
Arch.spice->spice_models); Arch.spice->spice_models);
print_verilog_submodule_essentials(std::string(verilog_dir),
std::string(submodule_dir),
Arch.spice->circuit_lib);
/* 1. MUXes */ /* 1. MUXes */
vpr_printf(TIO_MESSAGE_INFO, "Generating modules of multiplexers...\n"); vpr_printf(TIO_MESSAGE_INFO, "Generating modules of multiplexers...\n");

View File

@ -34,7 +34,7 @@ void print_verilog_file_header(std::fstream& fp,
fp << "//\tDescription: " << usage << std::endl; fp << "//\tDescription: " << usage << std::endl;
fp << "//\tAuthor: Xifan TANG" << std::endl; fp << "//\tAuthor: Xifan TANG" << std::endl;
fp << "//\t Organization: University of Utah" << std::endl; fp << "//\t Organization: University of Utah" << std::endl;
fp << "//\tDate: " << std::ctime(&end_time) << std::endl; fp << "//\tDate: " << std::ctime(&end_time) ;
fp << "//-------------------------------------------" << std::endl; fp << "//-------------------------------------------" << std::endl;
fp << "//----- Time scale -----" << std::endl; fp << "//----- Time scale -----" << std::endl;
fp << "`timescale 1ns / 1ps" << std::endl; fp << "`timescale 1ns / 1ps" << std::endl;