openfpga/src/fpga_spice/spice_writer_utils.cpp
/********************************************************************
 * Print an instance in SPICE format (a generic version)
 * This function will require user to provide an instance name
 *
 * This function will output the port map by referring to a port-to-port 
 * mapping:
 *   <module_port_name> -> <instance_port_name>
 * The key of the port-to-port mapping is the port name of the module: 
 * The value of the port-to-port mapping is the port information of the instance
 * With link between module and instance, the function can output a SPICE 
 * instance easily, by following the define port sequence of the module
 *
 * Note that, it is not necessary that the port-to-port mapping 
 * covers all the module ports.
 * Any instance/module port which are not specified in the port-to-port 
 * mapping will be output by the module port name.
 *******************************************************************/
Print an instance in SPICE format (a generic version)
This function will require user to provide an instance name



Note that, it is not necessary that the port-to-port mapping
covers all the module ports.
Any instance/module port which are not specified in the port-to-port
mapping will be output by the module port name.
Print an instance in SPICE format ( a generic version ) This function will require user to provide an instance name Note that it is not necessary that the port - to - port mapping covers all the module ports . Any instance / module port which are not specified in the port - to - port mapping will be output by the module port name .
void print_spice_subckt_instance(std::fstream& fp, 
                                 const ModuleManager& module_manager, 
                                 const ModuleId& module_id,
                                 const std::string& instance_name,
                                 const std::map<std::string, BasicPort>& port2port_name_map) {
  VTR_ASSERT(true == valid_file_stream(fp));
  for (const auto& kv : port2port_name_map) {
    ModulePortId module_port_id = module_manager.find_module_port(module_id, kv.first);
    VTR_ASSERT(ModulePortId::INVALID() != module_port_id);
  }
  std::string instance_head_line = "X " + instance_name + " ";
  fp << instance_head_line;
  bool fit_one_line = true;
  bool new_line = false;
  size_t pin_cnt = 0;
  for (int port_type = ModuleManager::MODULE_GLOBAL_PORT;
       port_type < ModuleManager::NUM_MODULE_PORT_TYPES;
       ++port_type) {
    for (const auto& port : module_manager.module_ports_by_type(module_id, static_cast<ModuleManager::e_module_port_type>(port_type))) {
      BasicPort port_to_print = port;
      auto port_search_result = port2port_name_map.find(port.get_name());
      if (port_search_result != port2port_name_map.end()) {
        ModulePortId module_port_id = module_manager.find_module_port(module_id, port.get_name());
        BasicPort module_port = module_manager.module_port(module_id, module_port_id);
        VTR_ASSERT(module_port.get_width() == port_search_result->second.get_width());
        port_to_print = port_search_result->second;
      }
      for (const auto& pin : port_to_print.pins()) {
        if (true == new_line) {
          std::string port_whitespace(instance_head_line.length() - 2, ' ');
          fp << "+ " << port_whitespace;
        }
        if (0 != pin_cnt) {
          write_space_to_file(fp, 1);
        }
        BasicPort port_pin(port.get_name(), pin, pin);
        bool omit_pin_zero = false;
        if ((1 == port.pins().size())
           && (0 == pin)) {
          omit_pin_zero = true;
        }
        fp << generate_spice_port(port_pin, omit_pin_zero);
        pin_cnt++;
        new_line = false;
        if (SPICE_NETLIST_MAX_NUM_PORTS_PER_LINE == pin_cnt) {
          pin_cnt = 0;
          fp << std::endl;
          new_line = true;
          fit_one_line = false;
        }
      }
    }
  }
  if (true == new_line) {
    std::string port_whitespace(instance_head_line.length() - 2, ' ');
    fp << "+ " << port_whitespace;
  }
  write_space_to_file(fp, 1);
  fp << SPICE_SUBCKT_VDD_PORT_NAME;
  write_space_to_file(fp, 1);
  fp << SPICE_SUBCKT_GND_PORT_NAME;
  pin_cnt += 2;
  new_line = false;
  if (SPICE_NETLIST_MAX_NUM_PORTS_PER_LINE == pin_cnt) {
    pin_cnt = 0;
    fp << std::endl;
    new_line = true;
    fit_one_line = false;
  }
  if (false == fit_one_line) {
    fp << std::endl;
    fp << "+";
  }
  write_space_to_file(fp, 1);
  fp << module_manager.module_name(module_id);
  fp << std::endl;
}
void print_spice_subckt_instance ( std :: fstream & fp , const ModuleManager & module_manager , const ModuleId & module_id , const std :: string & instance_name , const std :: map < std :: string , BasicPort > & port2port_name_map ) { VTR_ASSERT ( true == valid_file_stream ( fp ) ) ; for ( const auto & kv : port2port_name_map ) { ModulePortId module_port_id = module_manager . find_module_port ( module_id , kv . first ) ; VTR_ASSERT ( ModulePortId :: INVALID ( ) != module_port_id ) ; } std :: string instance_head_line = " " + instance_name + " " ; fp << instance_head_line ; bool fit_one_line = true ; bool new_line = false ; size_t pin_cnt = 0 ; for ( int port_type = ModuleManager :: MODULE_GLOBAL_PORT ; port_type < ModuleManager :: NUM_MODULE_PORT_TYPES ; ++ port_type ) { for ( const auto & port : module_manager . module_ports_by_type ( module_id , static_cast < ModuleManager :: e_module_port_type > ( port_type ) ) ) { BasicPort port_to_print = port ; auto port_search_result = port2port_name_map . find ( port . get_name ( ) ) ; if ( port_search_result != port2port_name_map . end ( ) ) { ModulePortId module_port_id = module_manager . find_module_port ( module_id , port . get_name ( ) ) ; BasicPort module_port = module_manager . module_port ( module_id , module_port_id ) ; VTR_ASSERT ( module_port . get_width ( ) == port_search_result -> second . get_width ( ) ) ; port_to_print = port_search_result -> second ; } for ( const auto & pin : port_to_print . pins ( ) ) { if ( true == new_line ) { std :: string port_whitespace ( instance_head_line . length ( ) - 2 , ' ' ) ; fp << " " << port_whitespace ; } if ( 0 != pin_cnt ) { write_space_to_file ( fp , 1 ) ; } BasicPort port_pin ( port . get_name ( ) , pin , pin ) ; bool omit_pin_zero = false ; if ( ( 1 == port . pins ( ) . size ( ) ) && ( 0 == pin ) ) { omit_pin_zero = true ; } fp << generate_spice_port ( port_pin , omit_pin_zero ) ; pin_cnt ++ ; new_line = false ; if ( SPICE_NETLIST_MAX_NUM_PORTS_PER_LINE == pin_cnt ) { pin_cnt = 0 ; fp << std :: endl ; new_line = true ; fit_one_line = false ; } } } } if ( true == new_line ) { std :: string port_whitespace ( instance_head_line . length ( ) - 2 , ' ' ) ; fp << " " << port_whitespace ; } write_space_to_file ( fp , 1 ) ; fp << SPICE_SUBCKT_VDD_PORT_NAME ; write_space_to_file ( fp , 1 ) ; fp << SPICE_SUBCKT_GND_PORT_NAME ; pin_cnt += 2 ; new_line = false ; if ( SPICE_NETLIST_MAX_NUM_PORTS_PER_LINE == pin_cnt ) { pin_cnt = 0 ; fp << std :: endl ; new_line = true ; fit_one_line = false ; } if ( false == fit_one_line ) { fp << std :: endl ; fp << " " ; } write_space_to_file ( fp , 1 ) ; fp << module_manager . module_name ( module_id ) ; fp << std :: endl ; }
Print an instance in SPICE format (a generic version)
 This function will require user to provide an instance name
Print an instance in SPICE format ( a generic version ) This function will require user to provide an instance name
/* Check: all the key ports in the port2port_name_map does exist in the child module */ /* Print instance name */ /* Port sequence: global, inout, input, output and clock ports, */ /* Deposit a default port name */ /* Try to find the instanced port name in the name map */ /* Found it, we assign the port name */ /* TODO: make sure the port width matches! */ /* Get the port from module */ /* Print port: only the port name is enough */ /* For single-bit port,
         * we can print the port name directly
         */ /* Increase the counter */ /* Currently we limit 10 ports per line to keep a clean netlist */ /* Print VDD and VSS ports
   * TODO: the supply ports should be derived from module manager
   */ /* Check if we need a new line */ /* Print module name: 
   * if port print cannot fit one line, we create a new line for the module for a clean format
   */ /* Print an end to the instance */