openfpga/src/fabric/build_mux_modules.cpp
/*********************************************************************
 * This function will add nets and input buffers (if needed) 
 * to a mux module 
 * Module net represents the connections when there are no output buffers
 *
 *             mux_output_net[0]
 * ------------+   |
 *             |   v
 *             |--------> mux_output[0]
 *             |
 *             |
 * Multiplexer | ...
 * Strcuture   |
 *             |--------> mux_output[i]
 *             |   ^
 *             |   |
 * ------------+  mux_output_net[i]
 *
 * Module net represents the connections when there are output buffers
 *
 *              mux_output_net[0]
 * ------------+    |
 *             |    |
 *             |    v   +------------------+   
 *             |------->| output_buffer[0] |------> mux_output[0]
 *             |        +------------------+  
 *             |
 * Multiplexer |        ...
 * Strcuture   |
 *             |        +------------------+   
 *             |------->| output_buffer[i] |------> mux_output[i]
 *             |    ^   +------------------+    
 *             |    |
 *             |    |
 * ------------+   mux_output_net[i]

 *
 *********************************************************************/
This function will add nets and input buffers (if needed)
to a mux module
Module net represents the connections when there are no output buffers



Module net represents the connections when there are output buffers


This function will add nets and input buffers ( if needed ) to a mux module Module net represents the connections when there are no output buffers Module net represents the connections when there are output buffers
static 
vtr::vector<MuxOutputId, ModuleNetId> build_mux_module_output_buffers(ModuleManager& module_manager, 
                                                                      const CircuitLibrary& circuit_lib, 
                                                                      const ModuleId& mux_module, 
                                                                      const CircuitModelId& mux_model, 
                                                                      const MuxGraph& mux_graph) {
  vtr::vector<MuxOutputId, ModuleNetId> mux_output_nets(mux_graph.num_outputs(), ModuleNetId::INVALID());
  std::vector<CircuitPortId> mux_output_ports;
  if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model)) {
     mux_output_ports = find_lut_circuit_model_output_port(circuit_lib, mux_model, false, true);
  } else {
     VTR_ASSERT(CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model));
     mux_output_ports = circuit_lib.model_ports_by_type(mux_model, CIRCUIT_MODEL_PORT_OUTPUT, false);
  }
  for (const auto& output_port : mux_output_ports) {
    ModulePortId module_output_port_id = module_manager.find_module_port(mux_module, circuit_lib.port_prefix(output_port));
    VTR_ASSERT(ModulePortId::INVALID() != module_output_port_id);
    BasicPort module_output_port = module_manager.module_port(mux_module, module_output_port_id);
    for (const size_t& pin : circuit_lib.pins(output_port)) {
      size_t output_node_level = mux_graph.num_node_levels() - 1; 
      if (size_t(-1) != circuit_lib.port_lut_frac_level(output_port)) {
        output_node_level = circuit_lib.port_lut_frac_level(output_port);
      }
      size_t output_node_index_at_level = 0; 
      if (!circuit_lib.port_lut_output_mask(output_port).empty()) {
        output_node_index_at_level = circuit_lib.port_lut_output_mask(output_port).at(pin);
      } 
      MuxNodeId node_id = mux_graph.node_id(output_node_level, output_node_index_at_level);
      VTR_ASSERT(MuxNodeId::INVALID() != node_id);
      MuxOutputId output_index = mux_graph.output_id(node_id);
      BasicPort instance_output_port(module_output_port.get_name(), pin, pin);
      if (false == circuit_lib.is_output_buffered(mux_model)) {
        ModuleNetId output_net = module_manager.create_module_net(mux_module);
        module_manager.add_module_net_sink(mux_module, output_net, mux_module, 0, module_output_port_id, pin);
        mux_output_nets[output_index] = output_net;
        continue; 
      }
      CircuitModelId buffer_model = circuit_lib.output_buffer_model(mux_model);
      VTR_ASSERT(CircuitModelId::INVALID() != buffer_model);
      ModuleNetId input_net = module_manager.create_module_net(mux_module);
      ModuleNetId output_net = add_inverter_buffer_child_module_and_nets(module_manager, mux_module, circuit_lib, buffer_model, input_net); 
      module_manager.add_module_net_sink(mux_module, output_net, mux_module, 0, module_output_port_id, pin);
      mux_output_nets[output_index] = input_net;
    }
  }
  return mux_output_nets;
}
static vtr :: vector < MuxOutputId , ModuleNetId > build_mux_module_output_buffers ( ModuleManager & module_manager , const CircuitLibrary & circuit_lib , const ModuleId & mux_module , const CircuitModelId & mux_model , const MuxGraph & mux_graph ) { vtr :: vector < MuxOutputId , ModuleNetId > mux_output_nets ( mux_graph . num_outputs ( ) , ModuleNetId :: INVALID ( ) ) ; std :: vector < CircuitPortId > mux_output_ports ; if ( CIRCUIT_MODEL_LUT == circuit_lib . model_type ( mux_model ) ) { mux_output_ports = find_lut_circuit_model_output_port ( circuit_lib , mux_model , false , true ) ; } else { VTR_ASSERT ( CIRCUIT_MODEL_MUX == circuit_lib . model_type ( mux_model ) ) ; mux_output_ports = circuit_lib . model_ports_by_type ( mux_model , CIRCUIT_MODEL_PORT_OUTPUT , false ) ; } for ( const auto & output_port : mux_output_ports ) { ModulePortId module_output_port_id = module_manager . find_module_port ( mux_module , circuit_lib . port_prefix ( output_port ) ) ; VTR_ASSERT ( ModulePortId :: INVALID ( ) != module_output_port_id ) ; BasicPort module_output_port = module_manager . module_port ( mux_module , module_output_port_id ) ; for ( const size_t & pin : circuit_lib . pins ( output_port ) ) { size_t output_node_level = mux_graph . num_node_levels ( ) - 1 ; if ( size_t ( -1 ) != circuit_lib . port_lut_frac_level ( output_port ) ) { output_node_level = circuit_lib . port_lut_frac_level ( output_port ) ; } size_t output_node_index_at_level = 0 ; if ( ! circuit_lib . port_lut_output_mask ( output_port ) . empty ( ) ) { output_node_index_at_level = circuit_lib . port_lut_output_mask ( output_port ) . at ( pin ) ; } MuxNodeId node_id = mux_graph . node_id ( output_node_level , output_node_index_at_level ) ; VTR_ASSERT ( MuxNodeId :: INVALID ( ) != node_id ) ; MuxOutputId output_index = mux_graph . output_id ( node_id ) ; BasicPort instance_output_port ( module_output_port . get_name ( ) , pin , pin ) ; if ( false == circuit_lib . is_output_buffered ( mux_model ) ) { ModuleNetId output_net = module_manager . create_module_net ( mux_module ) ; module_manager . add_module_net_sink ( mux_module , output_net , mux_module , 0 , module_output_port_id , pin ) ; mux_output_nets [ output_index ] = output_net ; continue ; } CircuitModelId buffer_model = circuit_lib . output_buffer_model ( mux_model ) ; VTR_ASSERT ( CircuitModelId :: INVALID ( ) != buffer_model ) ; ModuleNetId input_net = module_manager . create_module_net ( mux_module ) ; ModuleNetId output_net = add_inverter_buffer_child_module_and_nets ( module_manager , mux_module , circuit_lib , buffer_model , input_net ) ; module_manager . add_module_net_sink ( mux_module , output_net , mux_module , 0 , module_output_port_id , pin ) ; mux_output_nets [ output_index ] = input_net ; } } return mux_output_nets ; }
This function will add nets and input buffers (if needed)
 to a mux module
 Module net represents the connections when there are no output buffers
This function will add nets and input buffers ( if needed ) to a mux module Module net represents the connections when there are no output buffers
/* Create module nets for output ports */ /* Get the output ports from the mux:
   * - LUT may have ports that are driven by harden logic, 
   *   which should not be included when building the mux graph
   * - LUT may have global output ports that are wired directly to top-level module 
   */ /* Iterate over all the outputs in the MUX module */ /* Get the output port from MUX module */ /* Get the port from module */ /* Iterate over each pin of the output port */ /* Fetch fundamental information from MUX graph w.r.t. the input node */ /* Deposite the last level of the graph, which is a default value */ /* If there is a fracturable level specified for the output, we find the exact level */ /* Deposite a zero, which is a default value */ /* If there are output masks, we find the node_index */ /* Double check the node exists in the Mux Graph */ /* Create the port information of the module output at the given pin range, which is the output of buffer instance */ /* If the output is not supposed to be buffered, create a net for the input directly */ /* Finish here */ /* Reach here, we need a buffer, create a port-to-port map and output the buffer instance */ /* Now we need to add intermediate buffers by instanciating the modules */ /* We must have a valid model id */ /* Create a module net which sinks at buffer input */