openfpga/src/fabric/build_top_module_memory.cpp
/********************************************************************
 * This function will 
 * - Add a frame decoder to the parent module 
 *   - If the decoder exists in the library, we use the module
 *   - If the decoder does not exist, we create a new module and use it
 * - Create nets for the following types of connections:
 *   - Connect the EN signal, first few bits of address of parent module 
 *     to the frame decoder inputs
 *     Note that the top-level module may have more address bits than
 *     what is required for this configuration region.
 *     A decoder will be created anyway to avoid address collision 
 *     to other configuration regions
 *     The address lines will be aligned from the MSB of top-level address lines!!!
 *   - Connect the enable (EN) port of memory modules under the parent module
 *     to the frame decoder outputs
 *   - Connect the data_in (Din) of parent module to the data_in of the all
 *     the memory modules
 *     Note that the top-level module may have multiple regions and 
 *     therefore the Din port have multiple pins. The Din of local decoder
 *     should be connected the Din pin indexed by current configuration region
 *
 *           EN  ADDR[X-1:0] DATA_IN[Y-1:0]
 *            |       |            |
 *            |       |            |     Top module
 *   +--------+-------+------------+------------------
 *   |        |       |             
 *   |        v       v                                           
 *   |       EN      ADDR[X - 1: X - log(N)/log2]
 *   |        |        |
 *   |        v        v                                        
 *   |  +--------------------------------------------+
 *   |  |             Frame-based decoder            |
 *   |  |                                            |
 *   |  |                Data out                    |
 *   |  +--------------------------------------------+
 *   |                     |
 *   |       +-------------+--------------------+
 *   |       |             |                    |  
 *   |   Din |         Din |                Din |  
 *   |   [Y] |         [Y] |                [Y] |
 *   |    |  |          |  |                 |  |
 *   |    v  v          v  v                 v  v
 *   |  +--------+    +--------+            +--------+
 *   |  | Memory |    | Memory |    ...     | Memory |
 *   |  | Module |    | Module |            | Module |
 *   |  |   [0]  |    |   [1]  |            |  [N-1] |             
 *   |  +--------+    +--------+            +--------+
 *   |       ^             ^                    ^
 *   |       |             |                    |
 *   |       +-------------+--------------------+
 *   |                     |
 *   |                  ADDR[log(N)/log2 - 1: 0]
 *
 * Note:
 *  - X is the port size of address port of the parent module
 *  - the address port of child memory modules may be smaller than 
 *    X - log(N)/log2. In such case, we will drop the MSBs until it fit
 *********************************************************************/




- X is the port size of address port of the parent module
- the address port of child memory modules may be smaller than
X - log(N)/log2. In such case, we will drop the MSBs until it fit
- X is the port size of address port of the parent module - the address port of child memory modules may be smaller than X - log ( N ) / log2 . In such case we will drop the MSBs until it fit
static 
void add_top_module_nets_cmos_memory_frame_decoder_config_bus(ModuleManager& module_manager,
                                                              DecoderLibrary& decoder_lib,
                                                              const ModuleId& parent_module,
                                                              const ConfigRegionId& config_region) {
  std::vector<ModuleId> configurable_children = module_manager.region_configurable_children(parent_module, config_region);
  std::vector<size_t> configurable_child_instances = module_manager.region_configurable_child_instances(parent_module, config_region);
  ModulePortId parent_addr_port = module_manager.find_module_port(parent_module, std::string(DECODER_ADDRESS_PORT_NAME));
  BasicPort parent_addr_port_info = module_manager.module_port(parent_module, parent_addr_port);
  size_t addr_size = find_mux_local_decoder_addr_size(configurable_children.size());
  size_t data_size = configurable_children.size(); 
  DecoderId decoder_id = decoder_lib.find_decoder(addr_size, data_size, true, false, false);
  if (DecoderId::INVALID() == decoder_id) {
    decoder_id = decoder_lib.add_decoder(addr_size, data_size, true, false, false);
  }
  VTR_ASSERT(DecoderId::INVALID() != decoder_id);
  std::string decoder_module_name = generate_memory_decoder_subckt_name(addr_size, data_size);
  ModuleId decoder_module = module_manager.find_module(decoder_module_name);
  if (ModuleId::INVALID() == decoder_module) {
    decoder_module = build_frame_memory_decoder_module(module_manager,
                                                       decoder_lib,
                                                       decoder_id);
  }
  VTR_ASSERT(ModuleId::INVALID() != decoder_module);
  size_t decoder_instance = module_manager.num_instance(parent_module, decoder_module);
  module_manager.add_child_module(parent_module, decoder_module);
  ModulePortId parent_en_port = module_manager.find_module_port(parent_module, std::string(DECODER_ENABLE_PORT_NAME));
  ModulePortId decoder_en_port = module_manager.find_module_port(decoder_module, std::string(DECODER_ENABLE_PORT_NAME));
  add_module_bus_nets(module_manager, parent_module,
                      parent_module, 0, parent_en_port,
                      decoder_module, decoder_instance, decoder_en_port);
  ModulePortId decoder_addr_port = module_manager.find_module_port(decoder_module, std::string(DECODER_ADDRESS_PORT_NAME));
  BasicPort decoder_addr_port_info = module_manager.module_port(decoder_module, decoder_addr_port);
  for (size_t ipin = 0; ipin < decoder_addr_port_info.get_width(); ++ipin) {
    ModuleNetId addr_net = create_module_source_pin_net(module_manager, parent_module, 
                                                        parent_module, 0, 
                                                        parent_addr_port,
                                                        parent_addr_port_info.pins()[parent_addr_port_info.get_width() - 1 - ipin]);
    VTR_ASSERT(ModuleNetId::INVALID() != addr_net);
    module_manager.add_module_net_sink(parent_module, addr_net,
                                       decoder_module, decoder_instance,
                                       decoder_addr_port,
                                       decoder_addr_port_info.pins()[decoder_addr_port_info.get_width() - 1 - ipin]);
  } 
  for (size_t mem_index = 0; mem_index < configurable_children.size(); ++mem_index) {
    ModuleId child_module = configurable_children[mem_index]; 
    size_t child_instance = configurable_child_instances[mem_index];
    ModulePortId child_addr_port = module_manager.find_module_port(child_module, std::string(DECODER_ADDRESS_PORT_NAME));
    BasicPort child_addr_port_info = module_manager.module_port(child_module, child_addr_port);
    for (size_t ipin = 0; ipin < child_addr_port_info.get_width(); ++ipin) {
      ModuleNetId addr_net = create_module_source_pin_net(module_manager, parent_module, 
                                                          parent_module, 0, 
                                                          parent_addr_port,
                                                          parent_addr_port_info.pins()[ipin]);
      VTR_ASSERT(ModuleNetId::INVALID() != addr_net);
      module_manager.add_module_net_sink(parent_module, addr_net,
                                         child_module, child_instance,
                                         child_addr_port,
                                         child_addr_port_info.pins()[ipin]);
    }
  }
  ModulePortId parent_din_port = module_manager.find_module_port(parent_module, std::string(DECODER_DATA_IN_PORT_NAME));
  BasicPort parent_din_port_info = module_manager.module_port(parent_module, parent_din_port);
  for (size_t mem_index = 0; mem_index < configurable_children.size(); ++mem_index) {
    ModuleId child_module = configurable_children[mem_index]; 
    size_t child_instance = module_manager.configurable_child_instances(parent_module)[mem_index];
    ModulePortId child_din_port = module_manager.find_module_port(child_module, std::string(DECODER_DATA_IN_PORT_NAME));
    BasicPort child_din_port_info = module_manager.module_port(child_module, child_din_port);
    VTR_ASSERT(size_t(config_region) < parent_din_port_info.get_width());
    VTR_ASSERT(1 == child_din_port_info.get_width());
    ModuleNetId din_net = create_module_source_pin_net(module_manager, parent_module, 
                                                       parent_module, 0, 
                                                       parent_din_port,
                                                       parent_din_port_info.pins()[size_t(config_region)]);
    VTR_ASSERT(ModuleNetId::INVALID() != din_net);
    module_manager.add_module_net_sink(parent_module, din_net, child_module, child_instance, child_din_port, child_din_port_info.pins()[0]);
  }
  ModulePortId decoder_dout_port = module_manager.find_module_port(decoder_module, std::string(DECODER_DATA_OUT_PORT_NAME));
  BasicPort decoder_dout_port_info = module_manager.module_port(decoder_module, decoder_dout_port);
  VTR_ASSERT(decoder_dout_port_info.get_width() == configurable_children.size());
  for (size_t mem_index = 0; mem_index < configurable_children.size(); ++mem_index) {
    ModuleId child_module = configurable_children[mem_index]; 
    size_t child_instance = module_manager.configurable_child_instances(parent_module)[mem_index];
    ModulePortId child_en_port = module_manager.find_module_port(child_module, std::string(DECODER_ENABLE_PORT_NAME));
    BasicPort child_en_port_info = module_manager.module_port(child_module, child_en_port);
    for (size_t ipin = 0; ipin < child_en_port_info.get_width(); ++ipin) {
      ModuleNetId en_net = create_module_source_pin_net(module_manager, parent_module, 
                                                        decoder_module, decoder_instance, 
                                                        decoder_dout_port,
                                                        decoder_dout_port_info.pins()[mem_index]);
      VTR_ASSERT(ModuleNetId::INVALID() != en_net);
      module_manager.add_module_net_sink(parent_module, en_net,
                                         child_module, child_instance,
                                         child_en_port,
                                         child_en_port_info.pins()[ipin]);
    }
  }
  module_manager.add_configurable_child(parent_module, decoder_module, decoder_instance);
  module_manager.add_configurable_child_to_region(parent_module,
                                                  config_region,
                                                  decoder_module, 
                                                  decoder_instance,
                                                  module_manager.configurable_children(parent_module).size() - 1);
}
static void add_top_module_nets_cmos_memory_frame_decoder_config_bus ( ModuleManager & module_manager , DecoderLibrary & decoder_lib , const ModuleId & parent_module , const ConfigRegionId & config_region ) { std :: vector < ModuleId > configurable_children = module_manager . region_configurable_children ( parent_module , config_region ) ; std :: vector < size_t > configurable_child_instances = module_manager . region_configurable_child_instances ( parent_module , config_region ) ; ModulePortId parent_addr_port = module_manager . find_module_port ( parent_module , std :: string ( DECODER_ADDRESS_PORT_NAME ) ) ; BasicPort parent_addr_port_info = module_manager . module_port ( parent_module , parent_addr_port ) ; size_t addr_size = find_mux_local_decoder_addr_size ( configurable_children . size ( ) ) ; size_t data_size = configurable_children . size ( ) ; DecoderId decoder_id = decoder_lib . find_decoder ( addr_size , data_size , true , false , false ) ; if ( DecoderId :: INVALID ( ) == decoder_id ) { decoder_id = decoder_lib . add_decoder ( addr_size , data_size , true , false , false ) ; } VTR_ASSERT ( DecoderId :: INVALID ( ) != decoder_id ) ; std :: string decoder_module_name = generate_memory_decoder_subckt_name ( addr_size , data_size ) ; ModuleId decoder_module = module_manager . find_module ( decoder_module_name ) ; if ( ModuleId :: INVALID ( ) == decoder_module ) { decoder_module = build_frame_memory_decoder_module ( module_manager , decoder_lib , decoder_id ) ; } VTR_ASSERT ( ModuleId :: INVALID ( ) != decoder_module ) ; size_t decoder_instance = module_manager . num_instance ( parent_module , decoder_module ) ; module_manager . add_child_module ( parent_module , decoder_module ) ; ModulePortId parent_en_port = module_manager . find_module_port ( parent_module , std :: string ( DECODER_ENABLE_PORT_NAME ) ) ; ModulePortId decoder_en_port = module_manager . find_module_port ( decoder_module , std :: string ( DECODER_ENABLE_PORT_NAME ) ) ; add_module_bus_nets ( module_manager , parent_module , parent_module , 0 , parent_en_port , decoder_module , decoder_instance , decoder_en_port ) ; ModulePortId decoder_addr_port = module_manager . find_module_port ( decoder_module , std :: string ( DECODER_ADDRESS_PORT_NAME ) ) ; BasicPort decoder_addr_port_info = module_manager . module_port ( decoder_module , decoder_addr_port ) ; for ( size_t ipin = 0 ; ipin < decoder_addr_port_info . get_width ( ) ; ++ ipin ) { ModuleNetId addr_net = create_module_source_pin_net ( module_manager , parent_module , parent_module , 0 , parent_addr_port , parent_addr_port_info . pins ( ) [ parent_addr_port_info . get_width ( ) - 1 - ipin ] ) ; VTR_ASSERT ( ModuleNetId :: INVALID ( ) != addr_net ) ; module_manager . add_module_net_sink ( parent_module , addr_net , decoder_module , decoder_instance , decoder_addr_port , decoder_addr_port_info . pins ( ) [ decoder_addr_port_info . get_width ( ) - 1 - ipin ] ) ; } for ( size_t mem_index = 0 ; mem_index < configurable_children . size ( ) ; ++ mem_index ) { ModuleId child_module = configurable_children [ mem_index ] ; size_t child_instance = configurable_child_instances [ mem_index ] ; ModulePortId child_addr_port = module_manager . find_module_port ( child_module , std :: string ( DECODER_ADDRESS_PORT_NAME ) ) ; BasicPort child_addr_port_info = module_manager . module_port ( child_module , child_addr_port ) ; for ( size_t ipin = 0 ; ipin < child_addr_port_info . get_width ( ) ; ++ ipin ) { ModuleNetId addr_net = create_module_source_pin_net ( module_manager , parent_module , parent_module , 0 , parent_addr_port , parent_addr_port_info . pins ( ) [ ipin ] ) ; VTR_ASSERT ( ModuleNetId :: INVALID ( ) != addr_net ) ; module_manager . add_module_net_sink ( parent_module , addr_net , child_module , child_instance , child_addr_port , child_addr_port_info . pins ( ) [ ipin ] ) ; } } ModulePortId parent_din_port = module_manager . find_module_port ( parent_module , std :: string ( DECODER_DATA_IN_PORT_NAME ) ) ; BasicPort parent_din_port_info = module_manager . module_port ( parent_module , parent_din_port ) ; for ( size_t mem_index = 0 ; mem_index < configurable_children . size ( ) ; ++ mem_index ) { ModuleId child_module = configurable_children [ mem_index ] ; size_t child_instance = module_manager . configurable_child_instances ( parent_module ) [ mem_index ] ; ModulePortId child_din_port = module_manager . find_module_port ( child_module , std :: string ( DECODER_DATA_IN_PORT_NAME ) ) ; BasicPort child_din_port_info = module_manager . module_port ( child_module , child_din_port ) ; VTR_ASSERT ( size_t ( config_region ) < parent_din_port_info . get_width ( ) ) ; VTR_ASSERT ( 1 == child_din_port_info . get_width ( ) ) ; ModuleNetId din_net = create_module_source_pin_net ( module_manager , parent_module , parent_module , 0 , parent_din_port , parent_din_port_info . pins ( ) [ size_t ( config_region ) ] ) ; VTR_ASSERT ( ModuleNetId :: INVALID ( ) != din_net ) ; module_manager . add_module_net_sink ( parent_module , din_net , child_module , child_instance , child_din_port , child_din_port_info . pins ( ) [ 0 ] ) ; } ModulePortId decoder_dout_port = module_manager . find_module_port ( decoder_module , std :: string ( DECODER_DATA_OUT_PORT_NAME ) ) ; BasicPort decoder_dout_port_info = module_manager . module_port ( decoder_module , decoder_dout_port ) ; VTR_ASSERT ( decoder_dout_port_info . get_width ( ) == configurable_children . size ( ) ) ; for ( size_t mem_index = 0 ; mem_index < configurable_children . size ( ) ; ++ mem_index ) { ModuleId child_module = configurable_children [ mem_index ] ; size_t child_instance = module_manager . configurable_child_instances ( parent_module ) [ mem_index ] ; ModulePortId child_en_port = module_manager . find_module_port ( child_module , std :: string ( DECODER_ENABLE_PORT_NAME ) ) ; BasicPort child_en_port_info = module_manager . module_port ( child_module , child_en_port ) ; for ( size_t ipin = 0 ; ipin < child_en_port_info . get_width ( ) ; ++ ipin ) { ModuleNetId en_net = create_module_source_pin_net ( module_manager , parent_module , decoder_module , decoder_instance , decoder_dout_port , decoder_dout_port_info . pins ( ) [ mem_index ] ) ; VTR_ASSERT ( ModuleNetId :: INVALID ( ) != en_net ) ; module_manager . add_module_net_sink ( parent_module , en_net , child_module , child_instance , child_en_port , child_en_port_info . pins ( ) [ ipin ] ) ; } } module_manager . add_configurable_child ( parent_module , decoder_module , decoder_instance ) ; module_manager . add_configurable_child_to_region ( parent_module , config_region , decoder_module , decoder_instance , module_manager . configurable_children ( parent_module ) . size ( ) - 1 ) ; }
This function will
 - Add a frame decoder to the parent module
   - If the decoder exists in the library, we use the module
   - If the decoder does not exist, we create a new module and use it
 - Create nets for the following types of connections:
   - Connect the EN signal, first few bits of address of parent module
     to the frame decoder inputs
     Note that the top-level module may have more address bits than
     what is required for this configuration region.
This function will - Add a frame decoder to the parent module - If the decoder exists in the library we use the module - If the decoder does not exist we create a new module and use it - Create nets for the following types of connections : - Connect the EN signal first few bits of address of parent module to the frame decoder inputs Note that the top - level module may have more address bits than what is required for this configuration region .
/* Find the decoder specification */ /* Data input should match the WL (data_in) of a SRAM */ /* Search the decoder library and try to find one 
   * If not found, create a new module and add it to the module manager 
   */ /* Create a module if not existed yet */ /* Instanciate the decoder module here */ /* Connect the enable (EN) port of memory modules under the parent module
   * to the frame decoder inputs
   */ /* Connect the address port of the parent module to the frame decoder address port
   * Note that we only connect to the first few bits of address port
   */ /* Create a net for the addr pin */ /* Configure the net sink */ /* Connect the address port of the parent module to the address port of configurable children
   * Note that we only connect to the last few bits of address port
   */ /* Configure the net sink */ /* Connect the data_in (Din) of parent module to the data_in of the all
   * the memory modules
   */ /* Ensure pin indices are in range! */ /* Create a net for the Din[config_region] pin */ /* Configure the net sink */ /* Connect the data_out port of the decoder module 
   * to the enable port of configurable children
   */ /* Configure the net sink */ /* Add the decoder as the last configurable children */ /* Register the configurable child to configuration region */