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

@ -120,10 +120,16 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
* LVDD * LVDD
* | * |
* - * -
* ENb -o|| * ENb[0] -o||
* - * -
* | * |
* - * -
* ENb[1] -o||
* -
* |
* ...
* |
* -
* +-o|| * +-o||
* | - * | -
* | | * | |
@ -132,9 +138,14 @@ int print_spice_transistor_wrapper(NetlistManager& netlist_manager,
* | - * | -
* +--|| * +--||
* - * -
* ...
* | * |
* - * -
* EN -|| * EN[1] -||
* -
* |
* -
* EN[0] -||
* - * -
* | * |
* LGND * LGND
@ -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;
size_t last_enb_pin;
for (const auto& power_gate_pin : circuit_lib.pins(enb_port)) {
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 ";
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 << 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;
}
bool first_en_pin = true;
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(en_port) << " ";
fp << circuit_lib.port_prefix(output_ports[0]) << "_nmos_pg_" << power_gate_pin << " ";
fp << "LGND "; 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;
/* 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;
} }