support multi-bit power gate ports in FPGA-SPICE

This commit is contained in:
tangxifan 2020-07-22 20:04:39 -06:00
parent f573fa3ee0
commit a4a38f8156
2 changed files with 87 additions and 38 deletions

View File

@ -117,27 +117,38 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
* Generate the SPICE subckt for a power gated inverter * Generate the SPICE subckt for a power gated inverter
* The Enable signal controlled the power gating * The Enable signal controlled the power gating
* Schematic * Schematic
* LVDD * LVDD
* | * |
* - * -
* ENb -o|| * ENb[0] -o||
* - * -
* | * |
* - * -
* +-o|| * ENb[1] -o||
* | - * -
* | | * |
* in-->+ +--> OUT * ...
* | | * |
* | - * -
* +--|| * +-o||
* - * | -
* | * | |
* - * in-->+ +--> OUT
* EN -|| * | |
* - * | -
* | * +--||
* LGND * -
* ...
* |
* -
* EN[1] -||
* -
* |
* -
* EN[0] -||
* -
* |
* LGND
* *
***********************************************/ ***********************************************/
static static
@ -178,33 +189,71 @@ int print_spice_powergated_inverter_subckt(std::fstream& fp,
/* TODO: may consider use size/bin to compact layout etc. */ /* TODO: may consider use size/bin to compact layout etc. */
for (size_t i = 0; i < circuit_lib.buffer_size(circuit_model); ++i) { for (size_t i = 0; i < circuit_lib.buffer_size(circuit_model); ++i) {
/* Write power-gateing transistor pairs using the technology model */ /* Write power-gating transistor pairs using the technology model
fp << "Xpmos_powergate_" << i << " "; * Note that for a mulit-bit power gating port, we should cascade the transistors
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg "; */
fp << circuit_lib.port_prefix(enb_port) << " "; bool first_enb_pin = true;
fp << "LVDD "; size_t last_enb_pin;
fp << "LVDD "; for (const auto& power_gate_pin : circuit_lib.pins(enb_port)) {
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX; BasicPort enb_pin(circuit_lib.port_prefix(enb_port), power_gate_pin, power_gate_pin);
fp << "Xpmos_powergate_" << i << "_pin_" << power_gate_pin << " ";
/* For the first pin, we should connect it to local VDD*/
if (true == first_enb_pin) {
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << power_gate_pin << " ";
fp << generate_spice_port(enb_pin) << " ";
fp << "LVDD ";
fp << "LVDD ";
first_enb_pin = false;
} else {
VTR_ASSERT_SAFE(false == first_enb_pin);
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << last_enb_pin << " ";
fp << generate_spice_port(enb_pin) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << power_gate_pin << " ";
fp << "LVDD ";
}
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << "Xnmos_powergate_" << i << " "; /* Cache the last pin*/
fp << circuit_lib.port_prefix(output_ports[0]) << " _nmos_pg "; last_enb_pin = power_gate_pin;
fp << circuit_lib.port_prefix(en_port) << " "; }
fp << "LGND ";
fp << "LGND "; bool first_en_pin = true;
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX; size_t last_en_pin;
for (const auto& power_gate_pin : circuit_lib.pins(en_port)) {
BasicPort en_pin(circuit_lib.port_prefix(en_port), power_gate_pin, power_gate_pin);
fp << "Xnmos_powergate_" << i << "_pin_" << power_gate_pin << " ";
/* For the first pin, we should connect it to local VDD*/
if (true == first_en_pin) {
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
fp << generate_spice_port(en_pin) << " ";
fp << "LGND ";
fp << "LGND ";
first_en_pin = false;
} else {
VTR_ASSERT_SAFE(false == first_enb_pin);
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << last_en_pin << " ";
fp << circuit_lib.port_prefix(en_port) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
fp << "LGND ";
}
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
/* Cache the last pin*/
last_enb_pin = power_gate_pin;
}
/* Write transistor pairs using the technology model */ /* Write transistor pairs using the technology model */
fp << "Xpmos_" << i << " "; fp << "Xpmos_" << i << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " "; fp << circuit_lib.port_prefix(output_ports[0]) << " ";
fp << circuit_lib.port_prefix(input_ports[0]) << " "; fp << circuit_lib.port_prefix(input_ports[0]) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg "; fp << circuit_lib.port_prefix(output_ports[0]) << "_pmos_pg_" << circuit_lib.pins(enb_port).back() << " ";
fp << "LVDD "; fp << "LVDD ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX; fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX;
fp << "Xnmos_" << i << " "; fp << "Xnmos_" << i << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " "; fp << circuit_lib.port_prefix(output_ports[0]) << " ";
fp << circuit_lib.port_prefix(input_ports[0]) << " "; fp << circuit_lib.port_prefix(input_ports[0]) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << " _nmos_pg "; fp << circuit_lib.port_prefix(output_ports[0]) << " _nmos_pg_" << circuit_lib.pins(en_port).back() << " ";
fp << "LGND "; fp << "LGND ";
fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX; fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_NMOS) << TRANSISTOR_WRAPPER_POSTFIX;
} }

View File

@ -307,7 +307,7 @@ CircuitPortId find_circuit_model_power_gate_en_port(const CircuitLibrary& circui
if (false == circuit_lib.port_is_config_enable(port)) { if (false == circuit_lib.port_is_config_enable(port)) {
continue; continue;
} }
if (0 == circuit_lib.port_default_value(port)) { if (1 == circuit_lib.port_default_value(port)) {
en_port = port; en_port = port;
break; break;
} }
@ -336,7 +336,7 @@ CircuitPortId find_circuit_model_power_gate_enb_port(const CircuitLibrary& circu
if (false == circuit_lib.port_is_config_enable(port)) { if (false == circuit_lib.port_is_config_enable(port)) {
continue; continue;
} }
if (1 == circuit_lib.port_default_value(port)) { if (0 == circuit_lib.port_default_value(port)) {
enb_port = port; enb_port = port;
break; break;
} }