openfpga/src/fpga_spice/spice_buffer.cpp
/********************************************************************
 * Generate the SPICE modeling for a power-gated inverter
 *
 * This function is created to be shared by inverter and buffer SPICE netlist writer
 *
 * Note: 
 * - This function does NOT create a file
 *   but requires a file stream created
 * - This function only output SPICE modeling for 
 *   an inverter. Any preprocessing or subckt definition should not be included!
 *******************************************************************/
Generate the SPICE modeling for a power-gated inverter
This function is created to be shared by inverter and buffer SPICE netlist writer

- This function does NOT create a file
but requires a file stream created
- This function only output SPICE modeling for
an inverter. Any preprocessing or subckt definition should not be included!
Generate the SPICE modeling for a power - gated inverter This function is created to be shared by inverter and buffer SPICE netlist writer - This function does NOT create a file but requires a file stream created - This function only output SPICE modeling for an inverter . Any preprocessing or subckt definition should not be included!
static 
int print_spice_powergated_inverter_pmos_modeling(std::fstream& fp,
                                                  const std::string& trans_name_postfix,
                                                  const std::string& input_port_name,
                                                  const std::string& output_port_name,
                                                  const CircuitLibrary& circuit_lib,
                                                  const CircuitPortId& enb_port,
                                                  const TechnologyLibrary& tech_lib,
                                                  const TechnologyModelId& tech_model,
                                                  const float& trans_width) {
  if (false == valid_file_stream(fp)) {
    return CMD_EXEC_FATAL_ERROR;
  }
  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_" << trans_name_postfix << "_pin_" << power_gate_pin << " ";
    if (true == first_enb_pin) {
      fp << output_port_name << "_pmos_pg_" << power_gate_pin << " "; 
      fp << generate_spice_port(enb_pin) << " "; 
      fp << SPICE_SUBCKT_VDD_PORT_NAME << " "; 
      fp << SPICE_SUBCKT_VDD_PORT_NAME << " "; 
      first_enb_pin = false;
    } else {
      VTR_ASSERT_SAFE(false == first_enb_pin);
      fp << output_port_name << "_pmos_pg_" << last_enb_pin << " "; 
      fp << generate_spice_port(enb_pin) << " "; 
      fp << output_port_name << "_pmos_pg_" << power_gate_pin << " "; 
      fp << SPICE_SUBCKT_VDD_PORT_NAME << " "; 
    }
    fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX; 
    fp << " W=" << std::setprecision(10) << trans_width;
    fp << "\n";
    last_enb_pin = power_gate_pin;
  }
  fp << "Xpmos_" << trans_name_postfix << " ";
  fp << output_port_name << " "; 
  fp << input_port_name << " "; 
  fp << output_port_name << "_pmos_pg_" << circuit_lib.pins(enb_port).back() << " "; 
  fp << SPICE_SUBCKT_VDD_PORT_NAME << " "; 
  fp << tech_lib.transistor_model_name(tech_model, TECH_LIB_TRANSISTOR_PMOS) << TRANSISTOR_WRAPPER_POSTFIX; 
  fp << " W=" << std::setprecision(10) << trans_width;
  fp << "\n";
  return CMD_EXEC_SUCCESS;
}
static int print_spice_powergated_inverter_pmos_modeling ( std :: fstream & fp , const std :: string & trans_name_postfix , const std :: string & input_port_name , const std :: string & output_port_name , const CircuitLibrary & circuit_lib , const CircuitPortId & enb_port , const TechnologyLibrary & tech_lib , const TechnologyModelId & tech_model , const float & trans_width ) { if ( false == valid_file_stream ( fp ) ) { return CMD_EXEC_FATAL_ERROR ; } 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 << " " << trans_name_postfix << " " << power_gate_pin << " " ; if ( true == first_enb_pin ) { fp << output_port_name << " " << power_gate_pin << " " ; fp << generate_spice_port ( enb_pin ) << " " ; fp << SPICE_SUBCKT_VDD_PORT_NAME << " " ; fp << SPICE_SUBCKT_VDD_PORT_NAME << " " ; first_enb_pin = false ; } else { VTR_ASSERT_SAFE ( false == first_enb_pin ) ; fp << output_port_name << " " << last_enb_pin << " " ; fp << generate_spice_port ( enb_pin ) << " " ; fp << output_port_name << " " << power_gate_pin << " " ; fp << SPICE_SUBCKT_VDD_PORT_NAME << " " ; } fp << tech_lib . transistor_model_name ( tech_model , TECH_LIB_TRANSISTOR_PMOS ) << TRANSISTOR_WRAPPER_POSTFIX ; fp << " " << std :: setprecision ( 10 ) << trans_width ; fp << " \n " ; last_enb_pin = power_gate_pin ; } fp << " " << trans_name_postfix << " " ; fp << output_port_name << " " ; fp << input_port_name << " " ; fp << output_port_name << " " << circuit_lib . pins ( enb_port ) . back ( ) << " " ; fp << SPICE_SUBCKT_VDD_PORT_NAME << " " ; fp << tech_lib . transistor_model_name ( tech_model , TECH_LIB_TRANSISTOR_PMOS ) << TRANSISTOR_WRAPPER_POSTFIX ; fp << " " << std :: setprecision ( 10 ) << trans_width ; fp << " \n " ; return CMD_EXEC_SUCCESS ; }
Generate the SPICE modeling for a power-gated inverter
 This function is created to be shared by inverter and buffer SPICE netlist writer
Generate the SPICE modeling for a power - gated inverter This function is created to be shared by inverter and buffer SPICE netlist writer
/* Write power-gating transistor pairs using the technology model
   * Note that for a mulit-bit power gating port, we should cascade the transistors
   */ /* For the first pin, we should connect it to local VDD*/ /* Cache the last pin*/ /* Write transistor pairs using the technology model */