openfpga/src/fabric/build_mux_modules.cpp
/*********************************************************************
 * Generate a module of a RRAM-based multiplexer with the given size 
 * The module will consist of three parts:
 * 1. instances of the branch circuits of multiplexers which are generated before  
 *    This builds up the 4T1R-based multiplexing structure
 *
 *                    BLB   WL
 *                     |    |       ...
 *                     v    v
 *                   +--------+            
 *           in[0]-->|        |            BLB   WL 
 *                ...| Branch |-----+       |    |
 *             in -->|   0    |     |       v    v
 *            [N-1]  +--------+     |     +--------+
 *                      ...            -->|        |
 *                    BLBs WLs         ...| Branch |
 *                     |    |    ...   -->|   X    |
 *                     v    v             +--------+
 *                   +--------+    |
 *                -->|        |    |
 *                ...| Branch |----+
 *                -->|   i    |
 *                   +--------+
 *
 * 2. Input buffers/inverters
 * 3. Output buffers/inverters
 *********************************************************************/
Generate a module of a RRAM-based multiplexer with the given size
The module will consist of three parts:
1. instances of the branch circuits of multiplexers which are generated before
This builds up the 4T1R-based multiplexing structure



2. Input buffers/inverters
3. Output buffers/inverters
Generate a module of a RRAM - based multiplexer with the given size The module will consist of three parts : 1 . instances of the branch circuits of multiplexers which are generated before This builds up the 4T1R - based multiplexing structure 2 . Input buffers / inverters 3 . Output buffers / inverters
static 
void build_rram_mux_module(ModuleManager& module_manager,
                           const CircuitLibrary& circuit_lib, 
                           const CircuitModelId& circuit_model, 
                           const std::string& module_name, 
                           const MuxGraph& mux_graph) {
  if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
    VTR_LOGF_ERROR(__FILE__, __LINE__, "RRAM-based LUT is not supported for circuit model '%s')!\n",
                  circuit_lib.model_name(circuit_model).c_str());
    exit(1);
  }
  std::vector<CircuitPortId> mux_global_ports = circuit_lib.model_global_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true, true);
  std::vector<CircuitPortId> mux_input_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_INPUT, true);
  std::vector<CircuitPortId> mux_output_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_OUTPUT, true);
  std::vector<CircuitPortId> mux_blb_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_BLB, true);
  std::vector<CircuitPortId> mux_wl_ports = circuit_lib.model_ports_by_type(circuit_model, CIRCUIT_MODEL_PORT_WL, true);
  size_t num_inputs = find_mux_num_datapath_inputs(circuit_lib, circuit_model, mux_graph.num_inputs());
  size_t num_outputs = mux_graph.num_outputs();
  size_t num_mems = mux_graph.num_memory_bits();
  VTR_ASSERT(1 == mux_input_ports.size());
  VTR_ASSERT(1 == mux_blb_ports.size());
  VTR_ASSERT(1 == mux_wl_ports.size());
  ModuleId module_id = module_manager.add_module(module_name); 
  VTR_ASSERT(ModuleId::INVALID() != module_id);
  module_manager.set_module_usage(module_id, ModuleManager::MODULE_INTERC);
  for (const auto& port : mux_global_ports) {
    BasicPort global_port(circuit_lib.port_prefix(port), circuit_lib.port_size(port));
    module_manager.add_port(module_id, global_port, ModuleManager::MODULE_GLOBAL_PORT);
  }
  size_t input_port_cnt = 0;
  for (const auto& port : mux_input_ports) {
    BasicPort input_port(circuit_lib.port_prefix(port), num_inputs);
    module_manager.add_port(module_id, input_port, ModuleManager::MODULE_INPUT_PORT);
    input_port_cnt++;
  }
  VTR_ASSERT(1 == input_port_cnt);
  for (const auto& port : mux_output_ports) {
    BasicPort output_port(circuit_lib.port_prefix(port), num_outputs);
    if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
      output_port.set_width(circuit_lib.port_size(port));
    }
    module_manager.add_port(module_id, output_port, ModuleManager::MODULE_OUTPUT_PORT);
  }
  for (const auto& port : mux_blb_ports) {
    BasicPort blb_port(circuit_lib.port_prefix(port), num_mems + mux_graph.num_levels());
    module_manager.add_port(module_id, blb_port, ModuleManager::MODULE_INPUT_PORT);
  }
  for (const auto& port : mux_wl_ports) {
    BasicPort wl_port(circuit_lib.port_prefix(port), num_mems + mux_graph.num_levels());
    module_manager.add_port(module_id, wl_port, ModuleManager::MODULE_INPUT_PORT);
  }
}
static void build_rram_mux_module ( ModuleManager & module_manager , const CircuitLibrary & circuit_lib , const CircuitModelId & circuit_model , const std :: string & module_name , const MuxGraph & mux_graph ) { if ( CIRCUIT_MODEL_LUT == circuit_lib . model_type ( circuit_model ) ) { VTR_LOGF_ERROR ( __FILE__ , __LINE__ , " \n " , circuit_lib . model_name ( circuit_model ) . c_str ( ) ) ; exit ( 1 ) ; } std :: vector < CircuitPortId > mux_global_ports = circuit_lib . model_global_ports_by_type ( circuit_model , CIRCUIT_MODEL_PORT_INPUT , true , true ) ; std :: vector < CircuitPortId > mux_input_ports = circuit_lib . model_ports_by_type ( circuit_model , CIRCUIT_MODEL_PORT_INPUT , true ) ; std :: vector < CircuitPortId > mux_output_ports = circuit_lib . model_ports_by_type ( circuit_model , CIRCUIT_MODEL_PORT_OUTPUT , true ) ; std :: vector < CircuitPortId > mux_blb_ports = circuit_lib . model_ports_by_type ( circuit_model , CIRCUIT_MODEL_PORT_BLB , true ) ; std :: vector < CircuitPortId > mux_wl_ports = circuit_lib . model_ports_by_type ( circuit_model , CIRCUIT_MODEL_PORT_WL , true ) ; size_t num_inputs = find_mux_num_datapath_inputs ( circuit_lib , circuit_model , mux_graph . num_inputs ( ) ) ; size_t num_outputs = mux_graph . num_outputs ( ) ; size_t num_mems = mux_graph . num_memory_bits ( ) ; VTR_ASSERT ( 1 == mux_input_ports . size ( ) ) ; VTR_ASSERT ( 1 == mux_blb_ports . size ( ) ) ; VTR_ASSERT ( 1 == mux_wl_ports . size ( ) ) ; ModuleId module_id = module_manager . add_module ( module_name ) ; VTR_ASSERT ( ModuleId :: INVALID ( ) != module_id ) ; module_manager . set_module_usage ( module_id , ModuleManager :: MODULE_INTERC ) ; for ( const auto & port : mux_global_ports ) { BasicPort global_port ( circuit_lib . port_prefix ( port ) , circuit_lib . port_size ( port ) ) ; module_manager . add_port ( module_id , global_port , ModuleManager :: MODULE_GLOBAL_PORT ) ; } size_t input_port_cnt = 0 ; for ( const auto & port : mux_input_ports ) { BasicPort input_port ( circuit_lib . port_prefix ( port ) , num_inputs ) ; module_manager . add_port ( module_id , input_port , ModuleManager :: MODULE_INPUT_PORT ) ; input_port_cnt ++ ; } VTR_ASSERT ( 1 == input_port_cnt ) ; for ( const auto & port : mux_output_ports ) { BasicPort output_port ( circuit_lib . port_prefix ( port ) , num_outputs ) ; if ( CIRCUIT_MODEL_LUT == circuit_lib . model_type ( circuit_model ) ) { output_port . set_width ( circuit_lib . port_size ( port ) ) ; } module_manager . add_port ( module_id , output_port , ModuleManager :: MODULE_OUTPUT_PORT ) ; } for ( const auto & port : mux_blb_ports ) { BasicPort blb_port ( circuit_lib . port_prefix ( port ) , num_mems + mux_graph . num_levels ( ) ) ; module_manager . add_port ( module_id , blb_port , ModuleManager :: MODULE_INPUT_PORT ) ; } for ( const auto & port : mux_wl_ports ) { BasicPort wl_port ( circuit_lib . port_prefix ( port ) , num_mems + mux_graph . num_levels ( ) ) ; module_manager . add_port ( module_id , wl_port , ModuleManager :: MODULE_INPUT_PORT ) ; } }
Generate a module of a RRAM-based multiplexer with the given size
 The module will consist of three parts:
 1. instances of the branch circuits of multiplexers which are generated before
    This builds up the 4T1R-based multiplexing structure
Generate a module of a RRAM - based multiplexer with the given size The module will consist of three parts : 1 . instances of the branch circuits of multiplexers which are generated before This builds up the 4T1R - based multiplexing structure
/* Error out for the conditions where we are not yet supported! */ /* RRAM LUT is not supported now... */ /* Get the global ports required by MUX (and any submodules) */ /* Get the input ports from the mux */ /* Get the output ports from the mux */ /* Get the BL and WL ports from the mux */ /* Generate the Verilog netlist according to the mux_graph */ /* Find out the number of data-path inputs */ /* Find out the number of outputs */ /* Find out the number of memory bits */ /* Check codes to ensure the port of Verilog netlists will match */ /* MUX graph must have only 1 input and 1 BLB and 1 WL port */ /* Create a Verilog Module based on the circuit model, and add to module manager */ /* Label module usage */ /* Add module ports */ /* Add each global port */ /* Configure each global port */ /* Add each input port */ /* Update counter */ /* Double check: We should have only 1 input port generated here! */ /* BLB port */ /* IMPORTANT: RRAM-based MUX has an additional BLB pin per level 
     * So, the actual port width of BLB should be added by the number of levels of the MUX graph 
     */ /* WL port */ /* IMPORTANT: RRAM-based MUX has an additional WL pin per level 
     * So, the actual port width of WL should be added by the number of levels of the MUX graph 
     */ /* TODO: Add the input and output buffers in Verilog codes */ /* TODO: Print the internal logic in Verilog codes */