openfpga/src/fpga_sdc/sdc_mux_utils.cpp
/********************************************************************
 * Break combinational loops in FPGA fabric, which mainly come from 
 * loops of multiplexers.
 * To handle this, we disable the timing at outputs of routing multiplexers
 *******************************************************************/
Break combinational loops in FPGA fabric, which mainly come from
loops of multiplexers.
To handle this, we disable the timing at outputs of routing multiplexers
Break combinational loops in FPGA fabric which mainly come from loops of multiplexers . To handle this we disable the timing at outputs of routing multiplexers
void print_sdc_disable_routing_multiplexer_outputs(const std::string& sdc_dir,
                                                   const bool& flatten_names,
                                                   const MuxLibrary& mux_lib,
                                                   const CircuitLibrary& circuit_lib,
                                                   const ModuleManager& module_manager,
                                                   const ModuleId& top_module) {
  std::string sdc_fname(sdc_dir + std::string(SDC_DISABLE_MUX_OUTPUTS_FILE_NAME));
  std::string timer_message = std::string("Write SDC to disable routing multiplexer outputs for P&R flow '") + sdc_fname + std::string("'");
  vtr::ScopedStartFinishTimer timer(timer_message);
  std::fstream fp;
  fp.open(sdc_fname, std::fstream::out | std::fstream::trunc);
  check_file_stream(sdc_fname.c_str(), fp);
  print_sdc_file_header(fp, std::string("Disable routing multiplexer outputs for PnR"));
  for (const MuxId& mux_id : mux_lib.muxes()) {
    const CircuitModelId& mux_model = mux_lib.mux_circuit_model(mux_id);
    if (CIRCUIT_MODEL_MUX != circuit_lib.model_type(mux_model)) {
      continue;
    }
    const MuxGraph& mux_graph = mux_lib.mux_graph(mux_id);
    std::string mux_module_name = generate_mux_subckt_name(circuit_lib, mux_model, 
                                                           find_mux_num_datapath_inputs(circuit_lib, mux_model, mux_graph.num_inputs()), 
                                                           std::string(""));
    ModuleId mux_module = module_manager.find_module(mux_module_name);
    VTR_ASSERT(true == module_manager.valid_module_id(mux_module));
    for (const BasicPort& output_port : module_manager.module_ports_by_type(mux_module, ModuleManager::MODULE_OUTPUT_PORT)) {
      rec_print_sdc_disable_timing_for_module_ports(fp,
                                                    flatten_names,
                                                    module_manager,
                                                    top_module,
                                                    mux_module,
                                                    format_dir_path(module_manager.module_name(top_module)),
                                                    output_port.get_name());
    }
  }
  fp.close();
}
void print_sdc_disable_routing_multiplexer_outputs ( const std :: string & sdc_dir , const bool & flatten_names , const MuxLibrary & mux_lib , const CircuitLibrary & circuit_lib , const ModuleManager & module_manager , const ModuleId & top_module ) { std :: string sdc_fname ( sdc_dir + std :: string ( SDC_DISABLE_MUX_OUTPUTS_FILE_NAME ) ) ; std :: string timer_message = std :: string ( " " ) + sdc_fname + std :: string ( " " ) ; vtr :: ScopedStartFinishTimer timer ( timer_message ) ; std :: fstream fp ; fp . open ( sdc_fname , std :: fstream :: out | std :: fstream :: trunc ) ; check_file_stream ( sdc_fname . c_str ( ) , fp ) ; print_sdc_file_header ( fp , std :: string ( " " ) ) ; for ( const MuxId & mux_id : mux_lib . muxes ( ) ) { const CircuitModelId & mux_model = mux_lib . mux_circuit_model ( mux_id ) ; if ( CIRCUIT_MODEL_MUX != circuit_lib . model_type ( mux_model ) ) { continue ; } const MuxGraph & mux_graph = mux_lib . mux_graph ( mux_id ) ; std :: string mux_module_name = generate_mux_subckt_name ( circuit_lib , mux_model , find_mux_num_datapath_inputs ( circuit_lib , mux_model , mux_graph . num_inputs ( ) ) , std :: string ( " " ) ) ; ModuleId mux_module = module_manager . find_module ( mux_module_name ) ; VTR_ASSERT ( true == module_manager . valid_module_id ( mux_module ) ) ; for ( const BasicPort & output_port : module_manager . module_ports_by_type ( mux_module , ModuleManager :: MODULE_OUTPUT_PORT ) ) { rec_print_sdc_disable_timing_for_module_ports ( fp , flatten_names , module_manager , top_module , mux_module , format_dir_path ( module_manager . module_name ( top_module ) ) , output_port . get_name ( ) ) ; } } fp . close ( ) ; }
Break combinational loops in FPGA fabric, which mainly come from
 loops of multiplexers.
Break combinational loops in FPGA fabric which mainly come from loops of multiplexers .
/* Create the file name for Verilog netlist */ /* Start time count */ /* Create the file stream */ /* Generate the descriptions*/ /* Iterate over the MUX modules */ /* Skip LUTs, we only care about multiplexers here */ /* Find the module name in module manager */ /* Go recursively in the module manager, 
     * starting from the top-level module: instance id of the top-level module is 0 by default 
     * Disable all the outputs of child modules that matches the mux_module id
     */ /* Close file handler */