openfpga/src/fpga_spice/spice_subckt_writer.cpp
/********************************************************************
 * Write a SPICE instance to a file
 * This function will name the input and output connections to
 * the inputs/output or local wires available in the parent module
 *      
 *    Parent_module
 *    +-----------------------------+
 *    |                             |
 *    |       +--------------+      |
 *    |       |              |      |
 *    |       | child_module |      |
 *    |       |  [instance]  |      |
 *    |       +--------------+      |
 *    |                             |
 *    +-----------------------------+
 *
 *******************************************************************/
Write a SPICE instance to a file
This function will name the input and output connections to
the inputs/output or local wires available in the parent module


Write a SPICE instance to a file This function will name the input and output connections to the inputs / output or local wires available in the parent module
static 
void write_spice_instance_to_file(std::fstream& fp,
                                  const ModuleManager& module_manager,
                                  const ModuleId& parent_module,
                                  const ModuleId& child_module,
                                  const size_t& instance_id) {
  VTR_ASSERT(true == valid_file_stream(fp));
  std::string instance_head_line = "X ";
  if (true == module_manager.instance_name(parent_module, child_module, instance_id).empty()) {
    instance_head_line += generate_instance_name(module_manager.module_name(child_module), instance_id);
  } else {
    instance_head_line += module_manager.instance_name(parent_module, child_module, instance_id);
  }
  instance_head_line += " ";
  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& child_port_id : module_manager.module_port_ids_by_type(child_module, static_cast<ModuleManager::e_module_port_type>(port_type))) {
      BasicPort child_port = module_manager.module_port(child_module, child_port_id);
      std::vector<BasicPort> instance_ports; 
      for (size_t child_pin : child_port.pins()) {
        ModuleNetId net = module_manager.module_instance_port_net(parent_module, child_module, instance_id, 
                                                                  child_port_id, child_pin);
        BasicPort instance_port;
        if (ModuleNetId::INVALID() == net) {
          instance_port.set_name(generate_spice_undriven_local_wire_name(module_manager, parent_module, child_module, instance_id, child_port_id));
          instance_port.set_width(child_pin, child_pin); 
        } else {
          instance_port = generate_spice_port_for_module_net(module_manager, parent_module, net);
        }
        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);
        }
        VTR_ASSERT(1 == instance_port.get_width());
        bool omit_pin_zero = false;
        if ((1 == instance_port.pins().size())
           && (0 == instance_port.get_lsb())) {
          omit_pin_zero = true;
        }
        fp << generate_spice_port(instance_port, 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(child_module);
  fp << std::endl;
}
static void write_spice_instance_to_file ( std :: fstream & fp , const ModuleManager & module_manager , const ModuleId & parent_module , const ModuleId & child_module , const size_t & instance_id ) { VTR_ASSERT ( true == valid_file_stream ( fp ) ) ; std :: string instance_head_line = " " ; if ( true == module_manager . instance_name ( parent_module , child_module , instance_id ) . empty ( ) ) { instance_head_line += generate_instance_name ( module_manager . module_name ( child_module ) , instance_id ) ; } else { instance_head_line += module_manager . instance_name ( parent_module , child_module , instance_id ) ; } instance_head_line += " " ; 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 & child_port_id : module_manager . module_port_ids_by_type ( child_module , static_cast < ModuleManager :: e_module_port_type > ( port_type ) ) ) { BasicPort child_port = module_manager . module_port ( child_module , child_port_id ) ; std :: vector < BasicPort > instance_ports ; for ( size_t child_pin : child_port . pins ( ) ) { ModuleNetId net = module_manager . module_instance_port_net ( parent_module , child_module , instance_id , child_port_id , child_pin ) ; BasicPort instance_port ; if ( ModuleNetId :: INVALID ( ) == net ) { instance_port . set_name ( generate_spice_undriven_local_wire_name ( module_manager , parent_module , child_module , instance_id , child_port_id ) ) ; instance_port . set_width ( child_pin , child_pin ) ; } else { instance_port = generate_spice_port_for_module_net ( module_manager , parent_module , net ) ; } 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 ) ; } VTR_ASSERT ( 1 == instance_port . get_width ( ) ) ; bool omit_pin_zero = false ; if ( ( 1 == instance_port . pins ( ) . size ( ) ) && ( 0 == instance_port . get_lsb ( ) ) ) { omit_pin_zero = true ; } fp << generate_spice_port ( instance_port , 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 ( child_module ) ; fp << std :: endl ; }
Write a SPICE instance to a file
 This function will name the input and output connections to
 the inputs/output or local wires available in the parent module
Write a SPICE instance to a file This function will name the input and output connections to the inputs / output or local wires available in the parent module
/* Ensure a valid file stream */ /* Print instance name: 
   * if we have an instance name, use it;
   * if not, we use a default name <name>_<num_instance_in_parent_module> 
   */ /* Port sequence: global, inout, input, output and clock ports, */ /* Create the port name and width to be used by the instance */ /* Find the net linked to the pin */ /* We give the same port name as child module, this case happens to global ports */ /* Find the name for this child port */ /* 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 */