openfpga/src/annotation/annotate_simulation_setting.cpp
/********************************************************************
 * Annotate simulation setting based on VPR results
 *  - If the operating clock frequency is set to follow the vpr timing results,
 *    we will set a new operating clock frequency here
 *  - If the number of clock cycles in simulation is set to be automatically determined,
 *    we will infer the number based on the average signal density
 *******************************************************************/
Annotate simulation setting based on VPR results
- If the operating clock frequency is set to follow the vpr timing results,
we will set a new operating clock frequency here
- If the number of clock cycles in simulation is set to be automatically determined,
we will infer the number based on the average signal density
Annotate simulation setting based on VPR results - If the operating clock frequency is set to follow the vpr timing results we will set a new operating clock frequency here - If the number of clock cycles in simulation is set to be automatically determined we will infer the number based on the average signal density
int annotate_simulation_setting(const AtomContext& atom_ctx, 
                                const std::unordered_map<AtomNetId, t_net_power>& net_activity, 
                                SimulationSetting& sim_setting) {
  if (0. == sim_setting.default_operating_clock_frequency()) {
    VTR_LOG("User specified the operating clock frequency to use VPR results\n");
    vtr::vector<ClusterNetId, float*> net_delay;
    vtr::t_chunk net_delay_ch;
    net_delay = alloc_net_delay(&net_delay_ch);
    load_net_delay_from_routing(net_delay);
    auto analysis_delay_calc = std::make_shared<AnalysisDelayCalculator>(atom_ctx.nlist, atom_ctx.lookup, net_delay);
    auto timing_info = make_setup_hold_timing_info(analysis_delay_calc);
    timing_info->update();
    float T_crit = timing_info->least_slack_critical_path().delay() * (1. + sim_setting.operating_clock_frequency_slack());
    sim_setting.set_default_operating_clock_frequency(1 / T_crit); 
    VTR_LOG("Use VPR critical path delay %g [ns] with a %g [%] slack in OpenFPGA.\n",
            T_crit / 1e9, sim_setting.operating_clock_frequency_slack() * 100);
  }
  VTR_LOG("Will apply operating clock frequency %g [MHz] to simulations\n",
          sim_setting.default_operating_clock_frequency() / 1e6);
  for (const SimulationClockId& clock_id : sim_setting.clocks()) {
    if (0. == sim_setting.clock_frequency(clock_id)) {
      sim_setting.set_clock_frequency(clock_id, sim_setting.default_operating_clock_frequency());
    }
    VTR_LOG("Will apply clock frequency %g [MHz] to clock '%s[%d:%d]' in simulations\n",
            sim_setting.clock_frequency(clock_id) / 1e6,
            sim_setting.clock_port(clock_id).get_name().c_str(),
            sim_setting.clock_port(clock_id).get_lsb(),
            sim_setting.clock_port(clock_id).get_msb());
  }
  if (0. == sim_setting.num_clock_cycles()) {
    VTR_LOG("User specified the number of operating clock cycles to be inferred from signal activities\n");
    if (true == net_activity.empty()) {
      VTR_LOG_ERROR("Signal activities are not defined!\nPlease check if activity file is given and properly generated!\n");
      return CMD_EXEC_FATAL_ERROR;
    }
    size_t num_clock_cycles = recommend_num_sim_clock_cycle(atom_ctx,
                                                            net_activity, 
                                                            0.5);
    sim_setting.set_num_clock_cycles(num_clock_cycles);
  }
  if (MIN_NUM_SIM_OPERATING_CLOCK_CYCLES > sim_setting.num_clock_cycles()) {
    VTR_LOG_ERROR("Minimum number of operating clock cycles applicable to simulations is %d, while the specified number is %lu!\n",
                  MIN_NUM_SIM_OPERATING_CLOCK_CYCLES,
                  sim_setting.num_clock_cycles());
    return CMD_EXEC_FATAL_ERROR;
  }
  VTR_LOG("Will apply %lu operating clock cycles to simulations\n",
          sim_setting.num_clock_cycles());
  return CMD_EXEC_SUCCESS;
}
int annotate_simulation_setting ( const AtomContext & atom_ctx , const std :: unordered_map < AtomNetId , t_net_power > & net_activity , SimulationSetting & sim_setting ) { if ( 0. == sim_setting . default_operating_clock_frequency ( ) ) { VTR_LOG ( " \n " ) ; vtr :: vector < ClusterNetId , float * > net_delay ; vtr :: t_chunk net_delay_ch ; net_delay = alloc_net_delay ( & net_delay_ch ) ; load_net_delay_from_routing ( net_delay ) ; auto analysis_delay_calc = std :: make_shared < AnalysisDelayCalculator > ( atom_ctx . nlist , atom_ctx . lookup , net_delay ) ; auto timing_info = make_setup_hold_timing_info ( analysis_delay_calc ) ; timing_info -> update ( ) ; float T_crit = timing_info -> least_slack_critical_path ( ) . delay ( ) * ( 1. + sim_setting . operating_clock_frequency_slack ( ) ) ; sim_setting . set_default_operating_clock_frequency ( 1 / T_crit ) ; VTR_LOG ( " \n " , T_crit / 1e9 , sim_setting . operating_clock_frequency_slack ( ) * 100 ) ; } VTR_LOG ( " \n " , sim_setting . default_operating_clock_frequency ( ) / 1e6 ) ; for ( const SimulationClockId & clock_id : sim_setting . clocks ( ) ) { if ( 0. == sim_setting . clock_frequency ( clock_id ) ) { sim_setting . set_clock_frequency ( clock_id , sim_setting . default_operating_clock_frequency ( ) ) ; } VTR_LOG ( " \n " , sim_setting . clock_frequency ( clock_id ) / 1e6 , sim_setting . clock_port ( clock_id ) . get_name ( ) . c_str ( ) , sim_setting . clock_port ( clock_id ) . get_lsb ( ) , sim_setting . clock_port ( clock_id ) . get_msb ( ) ) ; } if ( 0. == sim_setting . num_clock_cycles ( ) ) { VTR_LOG ( " \n " ) ; if ( true == net_activity . empty ( ) ) { VTR_LOG_ERROR ( " \n \n " ) ; return CMD_EXEC_FATAL_ERROR ; } size_t num_clock_cycles = recommend_num_sim_clock_cycle ( atom_ctx , net_activity , 0.5 ) ; sim_setting . set_num_clock_cycles ( num_clock_cycles ) ; } if ( MIN_NUM_SIM_OPERATING_CLOCK_CYCLES > sim_setting . num_clock_cycles ( ) ) { VTR_LOG_ERROR ( " \n " , MIN_NUM_SIM_OPERATING_CLOCK_CYCLES , sim_setting . num_clock_cycles ( ) ) ; return CMD_EXEC_FATAL_ERROR ; } VTR_LOG ( " \n " , sim_setting . num_clock_cycles ( ) ) ; return CMD_EXEC_SUCCESS ; }
Annotate simulation setting based on VPR results
  - If the operating clock frequency is set to follow the vpr timing results,
    we will set a new operating clock frequency here
  - If the number of clock cycles in simulation is set to be automatically determined,
    we will infer the number based on the average signal density
Annotate simulation setting based on VPR results - If the operating clock frequency is set to follow the vpr timing results we will set a new operating clock frequency here - If the number of clock cycles in simulation is set to be automatically determined we will infer the number based on the average signal density
/* Find if the operating frequency is binded to vpr results */ /* Run timing analysis and collect critical path delay
     * This code is copied from function vpr_analysis() in vpr_api.h 
     * Should keep updated to latest VPR code base
     * Note:
     *   - MUST mention in documentation that VPR should be run in timing enabled mode
     */ /* Load the net delays */ /* Do final timing analysis */ /* Get critical path delay. Update simulation settings */ /* Walk through all the clock information */ /* Find the number of clock cycles to be used in simulation 
     * by average over the signal activity 
     */ /* Error out if net activity is not defined */ /* Use a fixed simulation window size now. TODO: this could be specified by users */ /* Minimum number of clock cycles should be at least 2
   * so that self-testing testbench can work!!!
   */