diff --git a/CMakeLists.txt b/CMakeLists.txt index d591cb84..6c907248 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,30 +130,25 @@ FILE(COPY ${EBLIF_TRANSFORM_SRC_H} DESTINATION ${EBLIF_TRANSFORM_DEST}) -message(STATUS "NOTE: PATCHING VPR pack/pb_pin_fixup\n") -FILE(COPY ${PACKER_SRC_DIR}/post_routing_pb_pin_fixup.cpp +# patch VPR +FILE(COPY ${PACKER_SRC_DIR}/cluster.cpp + ${PACKER_SRC_DIR}/cluster_util.cpp + ${PACKER_SRC_DIR}/cluster_util.h + ${PACKER_SRC_DIR}/output_clustering.cpp + ${PACKER_SRC_DIR}/output_clustering.h + ${PACKER_SRC_DIR}/cluster_router.cpp + ${PACKER_SRC_DIR}/post_routing_pb_pin_fixup.cpp DESTINATION ${VPR_DEST_DIR}/src/pack) -# patch VPR -#FILE(COPY ${PACKER_SRC_DIR}/cluster.cpp -# ${PACKER_SRC_DIR}/cluster_util.cpp -# ${PACKER_SRC_DIR}/cluster_util.h -# ${PACKER_SRC_DIR}/output_clustering.cpp -# ${PACKER_SRC_DIR}/output_clustering.h -# ${PACKER_SRC_DIR}/cluster_router.cpp -# ${PACKER_SRC_DIR}/post_routing_pb_pin_fixup.cpp -# DESTINATION -# ${VPR_DEST_DIR}/src/pack) - # add to VPR/pack -#FILE(COPY ${PACKER_SRC_DIR}/nl_Par.h -# ${PACKER_SRC_DIR}/nl_Par.cpp -# ${PACKER_SRC_DIR}/pinc_log.h -# ${PACKER_SRC_DIR}/pinc_log.cpp -# DESTINATION -# ${VPR_DEST_DIR}/src/pack) -#message(STATUS "NOTE: ADDED to VPR src/pack: nl_Par.cpp,h pinc_log.cpp,h") +FILE(COPY ${PACKER_SRC_DIR}/nl_Par.h + ${PACKER_SRC_DIR}/nl_Par.cpp + ${PACKER_SRC_DIR}/pinc_log.h + ${PACKER_SRC_DIR}/pinc_log.cpp + DESTINATION + ${VPR_DEST_DIR}/src/pack) +message(STATUS "NOTE: ADDED to VPR src/pack: nl_Par.cpp,h pinc_log.cpp,h") # add to VPR/base file(COPY @@ -174,7 +169,7 @@ message(STATUS "NOTE: OVERWRITING netlist_writer.cpp") file(COPY ${PATCH_DIR}/base_fix/PATCHED/netlist_writer.cpp DESTINATION ${TARGET_DIR}) message(STATUS "NOTE: COPIED ${PATCH_DIR}/base_fix/PATCHED/netlist_writer.cpp\n to ${TARGET_DIR}/\n") -#message(STATUS "NOTE: PATCHING base/vpr_api.cpp ..") +message(STATUS "NOTE: PATCHING-COPYING base/vpr_api.cpp ..") #set(DIFF_FILE ${PATCH_DIR}/base_fix/DIFF/vpr_api_cpp.diff) #apply_patch(${DIFF_FILE} ${TARGET_DIR} "base/vpr_api.cpp") @@ -213,26 +208,9 @@ set(DIFF_FILE ${PATCH_DIR}/libpugiutil_fix/DIFF/pugixml_util_cpp.diff) apply_patch(${DIFF_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/OpenFPGA/vtr-verilog-to-routing/libs/libpugiutil/src "pugixml_util.cpp") # copy RS additions and patch CMakefiles -message(STATUS "NOTE: COPYING/PATCHING OpenFPGA CMakefiles..") +message(STATUS "NOTE: COPYING OpenFPGA CMakefile..") #set(DIFF_FILE ${PATCH_DIR}/CMAKE_fix/OpenFPGA_CMake.diff) #apply_patch(${DIFF_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/OpenFPGA "OpenFPGA CMakefile") -set(DIFF_FILE ${PATCH_DIR}/CMAKE_fix/PATCHED_OpenFPGA/libs_cmakefile.diff) -apply_patch(${DIFF_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/OpenFPGA/libs "OpenFPGA/libs CMakefile") - -set(DIFF_FILE ${PATCH_DIR}/CMAKE_fix/PATCHED_OpenFPGA/openfpga_src_CMakefile.diff) -apply_patch(${DIFF_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/OpenFPGA/openfpga "OpenFPGA/openfpga CMakefile") - -file(COPY - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx.capnp - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx.capnp.c++ - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx.capnp.h - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx_capnp.h - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx_capnp_impl.h - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx.cpp - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx.h - ${PATCH_DIR}/openfpga/annotation/unique_blocks_uxsdcxx_interface.h - DESTINATION - ${CMAKE_CURRENT_SOURCE_DIR}/OpenFPGA/openfpga/src/annotation) # temporarily swithed to copying because of "partial patch" issue in Raptor build. file(COPY @@ -298,7 +276,7 @@ FILE(COPY ${TATUM_SRC_DIR}/TimingReporter.hpp ${OPENFPGA_DEST_DIR}/vtr-verilog-to-routing/libs/EXTERNAL/libtatum/libtatum/tatum ) -# Logical Levels +## Logical Levels FILE(COPY ${UTIL_SRC_DIR}/rsbe_utils.cpp ${UTIL_SRC_DIR}/rsbe_utils.h DESTINATION diff --git a/OpenFPGA b/OpenFPGA index 7c3de4c1..7fff106a 160000 --- a/OpenFPGA +++ b/OpenFPGA @@ -1 +1 @@ -Subproject commit 7c3de4c113af31957664e3b9dab82ab02664893e +Subproject commit 7fff106a4511a9cbb8518f7c144ef2de9864eeb8 diff --git a/include/CMAKE_fix/PATCHED_VPR/CMakeLists.txt b/include/CMAKE_fix/PATCHED_VPR/CMakeLists.txt index c36661c4..f7cecb8b 100644 --- a/include/CMAKE_fix/PATCHED_VPR/CMakeLists.txt +++ b/include/CMAKE_fix/PATCHED_VPR/CMakeLists.txt @@ -99,26 +99,15 @@ add_library(libvpr STATIC target_include_directories(libvpr PUBLIC ${LIB_INCLUDE_DIRS}) target_include_directories(libvpr PUBLIC ${READ_EDIF_SRC_DIR}) -# Find if Eigen is installed. Eigen is used within the Analytical Solver of the -# Analytical Placement flow. If Eigen is not installed, certain solvers cannot -# be used. -find_package(Eigen3 3.3 NO_MODULE) -if (TARGET Eigen3::Eigen) - target_link_libraries (libvpr Eigen3::Eigen) - target_compile_definitions(libvpr PUBLIC -DEIGEN_INSTALLED) - message(STATUS "Eigen3: Found") -else () - message(STATUS "Eigen3: Not Found. Some features may be disabled.") -endif (TARGET Eigen3::Eigen) - #VPR_ANALYTIC_PLACE is initialized in the root CMakeLists -# NOTE: This is the cluster-level Analytical Placement which existed before the -# flat Analytical Placement flow. +#Check Eigen dependency if(${VPR_ANALYTIC_PLACE}) message(STATUS "VPR Analytic Placement: Requested") + find_package(Eigen3 3.3 NO_MODULE) if (TARGET Eigen3::Eigen) message(STATUS "VPR Analytic Placement dependency (Eigen3): Found") message(STATUS "VPR Analytic Placement: Enabled") + target_link_libraries (libvpr Eigen3::Eigen) target_compile_definitions(libvpr PUBLIC -DENABLE_ANALYTIC_PLACE) else () message(STATUS "VPR Analytic Placement dependency (Eigen3): Not Found (Download manually with sudo apt install libeigen3-dev, and rebuild)") @@ -143,21 +132,19 @@ endif () set_target_properties(libvpr PROPERTIES PREFIX "") #Avoid extra 'lib' prefix #Specify link-time dependencies -find_package(ZLIB) target_link_libraries(libvpr - libvtrutil - libarchfpga - libsdcparse - libblifparse - libtatum - libargparse - libpugixml - librrgraph - libreadedif - ${OPENSSL_LIBRARIES} - ${VERIFIC_LIBS} - ZLIB::ZLIB dl - ) + libvtrutil + libarchfpga + libsdcparse + libblifparse + libtatum + libargparse + libpugixml + librrgraph + libreadedif + ${OPENSSL_LIBRARIES} + ${VERIFIC_LIBS} dl +) if(VPR_USE_SERVER) target_link_libraries(libvpr @@ -343,7 +330,7 @@ file(GLOB_RECURSE TEST_SOURCES test/*.cpp) add_executable(test_vpr ${TEST_SOURCES}) target_link_libraries(test_vpr Catch2::Catch2WithMain - libvpr -lz) + libvpr) #Suppress IPO link warnings if IPO is enabled get_target_property(TEST_VPR_USES_IPO vpr INTERPROCEDURAL_OPTIMIZATION) diff --git a/include/analysis_fix/timing_reports.cpp b/include/analysis_fix/timing_reports.cpp index 8eb6e540..d3de4a06 100644 --- a/include/analysis_fix/timing_reports.cpp +++ b/include/analysis_fix/timing_reports.cpp @@ -12,18 +12,13 @@ #include "VprTimingGraphResolver.h" -void generate_setup_timing_stats(const std::string& prefix, - const SetupTimingInfo& timing_info, - const AnalysisDelayCalculator& delay_calc, - const t_analysis_opts& analysis_opts, - bool is_flat, - const BlkLocRegistry& blk_loc_registry) { +void generate_setup_timing_stats(const std::string& prefix, const SetupTimingInfo& timing_info, const AnalysisDelayCalculator& delay_calc, const t_analysis_opts& analysis_opts, bool is_flat) { auto& timing_ctx = g_vpr_ctx.timing(); auto& atom_ctx = g_vpr_ctx.atom(); print_setup_timing_summary(*timing_ctx.constraints, *timing_info.setup_analyzer(), "Final ", analysis_opts.write_timing_summary); - VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat, blk_loc_registry); + VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat); resolver.set_detail_level(analysis_opts.timing_report_detail); tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph, *timing_ctx.constraints); @@ -37,18 +32,13 @@ void generate_setup_timing_stats(const std::string& prefix, timing_reporter.report_unconstrained_setup(prefix + "report_unconstrained_timing.setup.rpt", *timing_info.setup_analyzer()); } -void generate_hold_timing_stats(const std::string& prefix, - const HoldTimingInfo& timing_info, - const AnalysisDelayCalculator& delay_calc, - const t_analysis_opts& analysis_opts, - bool is_flat, - const BlkLocRegistry& blk_loc_registry) { +void generate_hold_timing_stats(const std::string& prefix, const HoldTimingInfo& timing_info, const AnalysisDelayCalculator& delay_calc, const t_analysis_opts& analysis_opts, bool is_flat) { auto& timing_ctx = g_vpr_ctx.timing(); auto& atom_ctx = g_vpr_ctx.atom(); print_hold_timing_summary(*timing_ctx.constraints, *timing_info.hold_analyzer(), "Final "); - VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat, blk_loc_registry); + VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc, is_flat); resolver.set_detail_level(analysis_opts.timing_report_detail); tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph, *timing_ctx.constraints); diff --git a/include/base_fix/PATCHED/SetupVPR.cpp b/include/base_fix/PATCHED/SetupVPR.cpp index d4b3ce9a..52235134 100644 --- a/include/base_fix/PATCHED/SetupVPR.cpp +++ b/include/base_fix/PATCHED/SetupVPR.cpp @@ -87,90 +87,86 @@ static void do_reachability_analysis(t_physical_tile_type* physical_tile, * Does not do any error checking as this should have been done by * the various input checkers */ -void SetupVPR(const t_options* options, - const bool timingenabled, +void SetupVPR(const t_options* Options, + const bool TimingEnabled, const bool readArchFile, - t_file_name_opts* fileNameOpts, - t_arch* arch, + t_file_name_opts* FileNameOpts, + t_arch* Arch, t_model** user_models, t_model** library_models, - t_netlist_opts* netlistOpts, - t_packer_opts* packerOpts, - t_placer_opts* placerOpts, - t_ap_opts* apOpts, - t_annealing_sched* annealSched, - t_router_opts* routerOpts, - t_analysis_opts* analysisOpts, - t_noc_opts* nocOpts, - t_server_opts* serverOpts, - t_det_routing_arch* routingArch, - std::vector** packerRRGraphs, - std::vector& segments, - t_timing_inf* timing, - bool* showGraphics, - int* graphPause, - bool* saveGraphics, - std::string* graphicsCommands, - t_power_opts* powerOpts, + t_netlist_opts* NetlistOpts, + t_packer_opts* PackerOpts, + t_placer_opts* PlacerOpts, + t_annealing_sched* AnnealSched, + t_router_opts* RouterOpts, + t_analysis_opts* AnalysisOpts, + t_noc_opts* NocOpts, + t_server_opts* ServerOpts, + t_det_routing_arch* RoutingArch, + std::vector** PackerRRGraphs, + std::vector& Segments, + t_timing_inf* Timing, + bool* ShowGraphics, + int* GraphPause, + bool* SaveGraphics, + std::string* GraphicsCommands, + t_power_opts* PowerOpts, t_vpr_setup* vpr_setup) { using argparse::Provenance; auto& device_ctx = g_vpr_ctx.mutable_device(); - if (options->CircuitName.value() == "") { + if (Options->CircuitName.value() == "") { VPR_FATAL_ERROR(VPR_ERROR_BLIF_F, "No blif file found in arguments (did you specify an architecture file?)\n"); } - alloc_and_load_output_file_names(options->CircuitName); - - //TODO: Move fileNameOpts setup into separate function - fileNameOpts->CircuitName = options->CircuitName; - fileNameOpts->ArchFile = options->ArchFile; - fileNameOpts->CircuitFile = options->CircuitFile; - fileNameOpts->NetFile = options->NetFile; - fileNameOpts->FlatPlaceFile = options->FlatPlaceFile; - fileNameOpts->PlaceFile = options->PlaceFile; - fileNameOpts->RouteFile = options->RouteFile; - fileNameOpts->ActFile = options->ActFile; - fileNameOpts->PowerFile = options->PowerFile; - fileNameOpts->CmosTechFile = options->CmosTechFile; - fileNameOpts->out_file_prefix = options->out_file_prefix; - fileNameOpts->read_vpr_constraints_file = options->read_vpr_constraints_file; - fileNameOpts->write_vpr_constraints_file = options->write_vpr_constraints_file; - fileNameOpts->write_constraints_file = options->write_constraints_file; - fileNameOpts->write_flat_place_file = options->write_flat_place_file; - fileNameOpts->write_block_usage = options->write_block_usage; - - fileNameOpts->verify_file_digests = options->verify_file_digests; - - SetupNetlistOpts(*options, *netlistOpts); - SetupPlacerOpts(*options, placerOpts); - SetupAnnealSched(*options, annealSched); - SetupRouterOpts(*options, routerOpts); - SetupAnalysisOpts(*options, *analysisOpts); - SetupPowerOpts(*options, powerOpts, arch); - SetupNocOpts(*options, nocOpts); - SetupServerOpts(*options, serverOpts); - - //save the device layout, which is required to parse the architecture file - arch->device_layout = options->device_layout; + alloc_and_load_output_file_names(Options->CircuitName); + + //TODO: Move FileNameOpts setup into separate function + FileNameOpts->CircuitName = Options->CircuitName; + FileNameOpts->ArchFile = Options->ArchFile; + FileNameOpts->CircuitFile = Options->CircuitFile; + FileNameOpts->NetFile = Options->NetFile; + FileNameOpts->FlatPlaceFile = Options->FlatPlaceFile; + FileNameOpts->PlaceFile = Options->PlaceFile; + FileNameOpts->RouteFile = Options->RouteFile; + FileNameOpts->ActFile = Options->ActFile; + FileNameOpts->PowerFile = Options->PowerFile; + FileNameOpts->CmosTechFile = Options->CmosTechFile; + FileNameOpts->out_file_prefix = Options->out_file_prefix; + FileNameOpts->read_vpr_constraints_file = Options->read_vpr_constraints_file; + FileNameOpts->write_vpr_constraints_file = Options->write_vpr_constraints_file; + FileNameOpts->write_constraints_file = Options->write_constraints_file; + FileNameOpts->write_flat_place_file = Options->write_flat_place_file; + FileNameOpts->write_block_usage = Options->write_block_usage; + + FileNameOpts->verify_file_digests = Options->verify_file_digests; + + SetupNetlistOpts(*Options, *NetlistOpts); + SetupPlacerOpts(*Options, PlacerOpts); + SetupAnnealSched(*Options, AnnealSched); + SetupRouterOpts(*Options, RouterOpts); + SetupAnalysisOpts(*Options, *AnalysisOpts); + SetupPowerOpts(*Options, PowerOpts, Arch); + SetupNocOpts(*Options, NocOpts); + SetupServerOpts(*Options, ServerOpts); if (readArchFile == true) { vtr::ScopedStartFinishTimer t("Loading Architecture Description"); - switch (options->arch_format) { + switch (Options->arch_format) { case e_arch_format::VTR: - XmlReadArch(options->ArchFile.value().c_str(), - timingenabled, - arch, + XmlReadArch(Options->ArchFile.value().c_str(), + TimingEnabled, + Arch, device_ctx.physical_tile_types, device_ctx.logical_block_types); break; case e_arch_format::FPGAInterchange: VTR_LOG("Use FPGA Interchange device\n"); - FPGAInterchangeReadArch(options->ArchFile.value().c_str(), - timingenabled, - arch, + FPGAInterchangeReadArch(Options->ArchFile.value().c_str(), + TimingEnabled, + Arch, device_ctx.physical_tile_types, device_ctx.logical_block_types); break; @@ -180,8 +176,8 @@ void SetupVPR(const t_options* options, } VTR_LOG("\n"); - *user_models = arch->models; - *library_models = arch->model_library; + *user_models = Arch->models; + *library_models = Arch->model_library; device_ctx.EMPTY_PHYSICAL_TILE_TYPE = nullptr; int num_inputs = 0; @@ -230,119 +226,109 @@ void SetupVPR(const t_options* options, "Architecture contains no top-level block type containing '.output' models"); } - segments = arch->Segments; + Segments = Arch->Segments; - SetupSwitches(*arch, routingArch, arch->Switches, arch->num_switches); - SetupRoutingArch(*arch, routingArch); - SetupTiming(*options, timingenabled, timing); - SetupPackerOpts(*options, packerOpts); - routingArch->write_rr_graph_filename = options->write_rr_graph_file; - routingArch->read_rr_graph_filename = options->read_rr_graph_file; + SetupSwitches(*Arch, RoutingArch, Arch->Switches, Arch->num_switches); + SetupRoutingArch(*Arch, RoutingArch); + SetupTiming(*Options, TimingEnabled, Timing); + SetupPackerOpts(*Options, PackerOpts); + RoutingArch->write_rr_graph_filename = Options->write_rr_graph_file; + RoutingArch->read_rr_graph_filename = Options->read_rr_graph_file; - for (auto has_global_routing : arch->layer_global_routing) { + for (auto has_global_routing : Arch->layer_global_routing) { device_ctx.inter_cluster_prog_routing_resources.emplace_back(has_global_routing); } //Setup the default flow, if no specific stages specified //do all - if (!options->do_packing - && !options->do_legalize - && !options->do_placement - && !options->do_analytical_placement - && !options->do_routing - && !options->do_analysis) { + if (!Options->do_packing + && !Options->do_legalize + && !Options->do_placement + && !Options->do_routing + && !Options->do_analysis) { //run all stages if none specified - packerOpts->doPacking = STAGE_DO; - placerOpts->doPlacement = STAGE_DO; - apOpts->doAP = STAGE_SKIP; // AP not default. - routerOpts->doRouting = STAGE_DO; - analysisOpts->doAnalysis = STAGE_AUTO; //Deferred until implementation status known + PackerOpts->doPacking = STAGE_DO; + PlacerOpts->doPlacement = STAGE_DO; + RouterOpts->doRouting = STAGE_DO; + AnalysisOpts->doAnalysis = STAGE_AUTO; //Deferred until implementation status known } else { //We run all stages up to the specified stage //Note that by checking in reverse order (i.e. analysis to packing) //we ensure that earlier stages override the default 'LOAD' action //set by later stages - if (options->do_analysis) { - packerOpts->doPacking = STAGE_LOAD; - placerOpts->doPlacement = STAGE_LOAD; - routerOpts->doRouting = STAGE_LOAD; - analysisOpts->doAnalysis = STAGE_DO; + if (Options->do_analysis) { + PackerOpts->doPacking = STAGE_LOAD; + PlacerOpts->doPlacement = STAGE_LOAD; + RouterOpts->doRouting = STAGE_LOAD; + AnalysisOpts->doAnalysis = STAGE_DO; } - if (options->do_routing) { - packerOpts->doPacking = STAGE_LOAD; - placerOpts->doPlacement = STAGE_LOAD; - routerOpts->doRouting = STAGE_DO; - analysisOpts->doAnalysis = ((options->do_analysis) ? STAGE_DO : STAGE_AUTO); //Always run analysis after routing + if (Options->do_routing) { + PackerOpts->doPacking = STAGE_LOAD; + PlacerOpts->doPlacement = STAGE_LOAD; + RouterOpts->doRouting = STAGE_DO; + AnalysisOpts->doAnalysis = ((Options->do_analysis) ? STAGE_DO : STAGE_AUTO); //Always run analysis after routing } - if (options->do_placement) { - packerOpts->doPacking = STAGE_LOAD; - placerOpts->doPlacement = STAGE_DO; + if (Options->do_placement) { + PackerOpts->doPacking = STAGE_LOAD; + PlacerOpts->doPlacement = STAGE_DO; } - if (options->do_analytical_placement) { - // In the Analytical Placement flow, packing and placement are - // integrated. Thus, these stages are skipped. - packerOpts->doPacking = STAGE_SKIP; - placerOpts->doPlacement = STAGE_SKIP; - apOpts->doAP = STAGE_DO; + if (Options->do_packing) { + PackerOpts->doPacking = STAGE_DO; } - if (options->do_packing) { - packerOpts->doPacking = STAGE_DO; - } - - if (options->do_legalize) { - packerOpts->doPacking = STAGE_LOAD; - packerOpts->load_flat_placement = true; + if (Options->do_legalize) { + PackerOpts->doPacking = STAGE_LOAD; + PackerOpts->load_flat_placement = true; } } ShowSetup(*vpr_setup); /* init global variables */ - vtr::out_file_prefix = options->out_file_prefix; + vtr::out_file_prefix = Options->out_file_prefix; /* Set seed for pseudo-random placement, default seed to 1 */ - vtr::srandom(placerOpts->seed); + vtr::srandom(PlacerOpts->seed); { vtr::ScopedStartFinishTimer t("Building complex block graph"); - alloc_and_load_all_pb_graphs(powerOpts->do_power, routerOpts->flat_routing); - *packerRRGraphs = alloc_and_load_all_lb_type_rr_graph(); + alloc_and_load_all_pb_graphs(PowerOpts->do_power, RouterOpts->flat_routing); + *PackerRRGraphs = alloc_and_load_all_lb_type_rr_graph(); } - if (routerOpts->flat_routing) { + if (RouterOpts->flat_routing) { vtr::ScopedStartFinishTimer timer("Allocate intra-cluster resources"); // The following two functions should be called when the data structured related to t_pb_graph_node, t_pb_type, // and t_pb_graph_edge are initialized - alloc_and_load_intra_cluster_resources(routerOpts->has_choking_spot); + alloc_and_load_intra_cluster_resources(RouterOpts->has_choking_spot); add_intra_tile_switches(); } - if ((options->clock_modeling == ROUTED_CLOCK) || (options->clock_modeling == DEDICATED_NETWORK)) { + if ((Options->clock_modeling == ROUTED_CLOCK) || (Options->clock_modeling == DEDICATED_NETWORK)) { ClockModeling::treat_clock_pins_as_non_globals(); } if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_LB_TYPE_RR_GRAPH)) { - echo_lb_type_rr_graphs(getEchoFileName(E_ECHO_LB_TYPE_RR_GRAPH), *packerRRGraphs); + echo_lb_type_rr_graphs(getEchoFileName(E_ECHO_LB_TYPE_RR_GRAPH), *PackerRRGraphs); } if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_PB_GRAPH)) { echo_pb_graph(getEchoFileName(E_ECHO_PB_GRAPH)); } - *graphPause = options->GraphPause; + *GraphPause = Options->GraphPause; - *showGraphics = options->show_graphics; + *ShowGraphics = Options->show_graphics; - *saveGraphics = options->save_graphics; - *graphicsCommands = options->graphics_commands; + *SaveGraphics = Options->save_graphics; + *GraphicsCommands = Options->graphics_commands; if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_ARCH)) { - EchoArch(getEchoFileName(E_ECHO_ARCH), device_ctx.physical_tile_types, device_ctx.logical_block_types, arch); + EchoArch(getEchoFileName(E_ECHO_ARCH), device_ctx.physical_tile_types, device_ctx.logical_block_types, Arch); } } @@ -437,7 +423,6 @@ static void SetupRoutingArch(const t_arch& Arch, /* Copy the tileable routing setting */ RoutingArch->tileable = Arch.tileable; - RoutingArch->perimeter_cb = Arch.perimeter_cb; RoutingArch->shrink_boundary = Arch.shrink_boundary; RoutingArch->through_channel = Arch.through_channel; RoutingArch->opin2all_sides = Arch.opin2all_sides; @@ -448,7 +433,6 @@ static void SetupRoutingArch(const t_arch& Arch, static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) { RouterOpts->do_check_rr_graph = Options.check_rr_graph; RouterOpts->astar_fac = Options.astar_fac; - RouterOpts->astar_offset = Options.astar_offset; RouterOpts->router_profiler_astar_fac = Options.router_profiler_astar_fac; RouterOpts->bb_factor = Options.bb_factor; RouterOpts->criticality_exp = Options.criticality_exp; @@ -460,7 +444,6 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->pres_fac_mult = Options.pres_fac_mult; RouterOpts->max_pres_fac = Options.max_pres_fac; RouterOpts->route_type = Options.RouteType; - RouterOpts->route_verbosity = Options.route_verbosity; RouterOpts->full_stats = Options.full_stats; @@ -527,7 +510,6 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts) RouterOpts->generate_rr_node_overuse_report = Options.generate_rr_node_overuse_report; RouterOpts->flat_routing = Options.flat_routing; RouterOpts->has_choking_spot = Options.has_choking_spot; - RouterOpts->custom_3d_sb_fanin_fanout = Options.custom_3d_sb_fanin_fanout; RouterOpts->with_timing_analysis = Options.timing_analysis; } @@ -675,8 +657,6 @@ static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts) PlacerOpts->write_initial_place_file = Options.write_initial_place_file; - PlacerOpts->read_initial_place_file = Options.read_initial_place_file; - PlacerOpts->pad_loc_type = Options.pad_loc_type; PlacerOpts->place_chan_width = Options.PlaceChanWidth; diff --git a/include/base_fix/PATCHED/read_options.cpp b/include/base_fix/PATCHED/read_options.cpp index c1024caa..9e5b32dd 100644 --- a/include/base_fix/PATCHED/read_options.cpp +++ b/include/base_fix/PATCHED/read_options.cpp @@ -548,9 +548,9 @@ struct ParseFixPins { ConvertedValue from_str(const std::string& str) { ConvertedValue conv_value; if (str == "free") - conv_value.set_value(e_pad_loc_type::FREE); + conv_value.set_value(FREE); else if (str == "random") - conv_value.set_value(e_pad_loc_type::RANDOM); + conv_value.set_value(RANDOM); else { std::stringstream msg; msg << "Invalid conversion from '" << str << "' to e_router_algorithm (expected one of: " << argparse::join(default_choices(), ", ") << ")"; @@ -561,10 +561,10 @@ struct ParseFixPins { ConvertedValue to_str(e_pad_loc_type val) { ConvertedValue conv_value; - if (val == e_pad_loc_type::FREE) + if (val == FREE) conv_value.set_value("free"); else { - VTR_ASSERT(val == e_pad_loc_type::RANDOM); + VTR_ASSERT(val == RANDOM); conv_value.set_value("random"); } return conv_value; @@ -1077,8 +1077,6 @@ struct ParseRouterHeap { ConvertedValue conv_value; if (str == "binary") conv_value.set_value(e_heap_type::BINARY_HEAP); - else if (str == "four_ary") - conv_value.set_value(e_heap_type::FOUR_ARY_HEAP); else if (str == "bucket") conv_value.set_value(e_heap_type::BUCKET_HEAP_APPROXIMATION); else { @@ -1093,8 +1091,6 @@ struct ParseRouterHeap { ConvertedValue conv_value; if (val == e_heap_type::BINARY_HEAP) conv_value.set_value("binary"); - else if (val == e_heap_type::FOUR_ARY_HEAP) - conv_value.set_value("four_ary"); else { VTR_ASSERT(val == e_heap_type::BUCKET_HEAP_APPROXIMATION); conv_value.set_value("bucket"); @@ -1103,7 +1099,7 @@ struct ParseRouterHeap { } std::vector default_choices() { - return {"binary", "four_ary", "bucket"}; + return {"binary", "bucket"}; } }; @@ -1340,11 +1336,6 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .action(argparse::Action::STORE_TRUE) .default_value("off"); - stage_grp.add_argument(args.do_analytical_placement, "--analytical_place") - .help("Run analytical placement. Analytical Placement uses an integrated packing and placement algorithm, using information from the primitive level to improve clustering and placement.") - .action(argparse::Action::STORE_TRUE) - .default_value("off"); - stage_grp.add_argument(args.do_routing, "--route") .help("Run routing") .action(argparse::Action::STORE_TRUE) @@ -1657,11 +1648,6 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .metavar("INITIAL_PLACE_FILE") .show_in(argparse::ShowIn::HELP_ONLY); - file_grp.add_argument(args.read_initial_place_file, "--read_initial_place_file") - .help("Reads the initial placement and continues the rest of the placement process from there.") - .metavar("INITIAL_PLACE_FILE") - .show_in(argparse::ShowIn::HELP_ONLY); - file_grp.add_argument(args.read_vpr_constraints_file, "--read_vpr_constraints") .help("Reads the floorplanning constraints that packing and placement must respect from the specified XML file.") .show_in(argparse::ShowIn::HELP_ONLY); @@ -2198,20 +2184,20 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio place_grp.add_argument(args.place_constraint_expand, "--place_constraint_expand") .help( - "The value used to decide how much to expand the floorplan constraint region when writing " - "a floorplan constraint XML file. Takes in an integer value from zero to infinity. " - "If the value is zero, the block stays at the same x, y location. If it is " - "greater than zero the constraint region expands by the specified value in each direction. " - "For example, if 1 was specified, a block at the x, y location (1, 1) would have a constraint region " + "The value used to decide how much to expand the floorplan constraint region when writing" + "a floorplan constraint XML file. Takes in an integer value from zero to infinity." + "If the value is zero, the block stays at the same x, y location. If it is" + "greater than zero the constraint region expands by the specified value in each direction." + "For example, if 1 was specified, a block at the x, y location (1, 1) would have a constraint region" "of 2x2 centered around (1, 1), from (0, 0) to (2, 2).") .default_value("0") .show_in(argparse::ShowIn::HELP_ONLY); place_grp.add_argument(args.place_constraint_subtile, "--place_constraint_subtile") .help( - "The bool used to say whether to print subtile constraints when printing a floorplan constraints XML file. " - "If it is off, no subtile locations are specified when printing the floorplan constraints. " - "If it is on, the floorplan constraints are printed with the subtiles from current placement. ") + "The bool used to say whether to print subtile constraints when printing a floorplan constraints XML file." + "If it is off, no subtile locations are specified when printing the floorplan constraints." + "If it is on, the floorplan constraints are printed with the subtiles from current placement.") .default_value("off") .show_in(argparse::ShowIn::HELP_ONLY); @@ -2324,7 +2310,7 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio " * 'simple' uses map router lookahead\n" " * 'delta' uses differences in position only\n" " * 'delta_override' uses differences in position with overrides for direct connects\n") - .default_value("simple") + .default_value("delta") .show_in(argparse::ShowIn::HELP_ONLY); place_timing_grp.add_argument(args.place_delay_model_reducer, "--place_delay_model_reducer") @@ -2538,18 +2524,6 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("false") .show_in(argparse::ShowIn::HELP_ONLY); - - route_grp.add_argument(args.route_verbosity, "--route_verbosity") - .help("Controls the verbosity of routing's output. Higher values produce more output (useful for debugging routing problems)") - .default_value("1") - .show_in(argparse::ShowIn::HELP_ONLY); - route_grp.add_argument(args.custom_3d_sb_fanin_fanout, "--custom_3d_sb_fanin_fanout") - .help( - "Specifies the number of tracks that can drive a 3D switch block connection" - "and the number of tracks that can be driven by a 3D switch block connection") - .default_value("1") - .show_in(argparse::ShowIn::HELP_ONLY); - auto& route_timing_grp = parser.add_argument_group("timing-driven routing options"); route_timing_grp.add_argument(args.astar_fac, "--astar_fac") @@ -2559,14 +2533,6 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .default_value("1.2") .show_in(argparse::ShowIn::HELP_ONLY); - route_timing_grp.add_argument(args.astar_offset, "--astar_offset") - .help( - "Controls the directedness of the timing-driven router's exploration." - " It is a subtractive adjustment to the lookahead heuristic." - " Values between 0 and 1e-9 are resonable; higher values may increase quality at the expense of run-time.") - .default_value("0.0") - .show_in(argparse::ShowIn::HELP_ONLY); - route_timing_grp.add_argument(args.router_profiler_astar_fac, "--router_profiler_astar_fac") .help( "Controls the directedness of the timing-driven router's exploration" @@ -2720,16 +2686,15 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio .help( "Controls what type of heap to use for timing driven router.\n" " * binary: A binary heap is used.\n" - " * four_ary: A four_ary heap is used.\n" " * bucket: A bucket heap approximation is used. The bucket heap\n" " * is faster because it is only a heap approximation.\n" " * Testing has shown the approximation results in\n" - " * similar QoR with less CPU work.\n") - .default_value("four_ary") + " * similiar QoR with less CPU work.\n") + .default_value("binary") .show_in(argparse::ShowIn::HELP_ONLY); route_timing_grp.add_argument(args.router_first_iteration_timing_report_file, "--router_first_iter_timing_report") - .help("Name of the post first routing iteration timing report file (not generated if unspecified)") + .help("Name of the post first routing iteration timing report file (not generated if unspecfied)") .default_value("") .show_in(argparse::ShowIn::HELP_ONLY); @@ -3140,13 +3105,6 @@ void set_conditional_defaults(t_options& args) { } } - // If MAP Router lookahead is not used, we cannot use simple place delay lookup - if (args.place_delay_model.provenance() != Provenance::SPECIFIED) { - if (args.router_lookahead_type != e_router_lookahead::MAP) { - args.place_delay_model.set(PlaceDelayModelType::DELTA, Provenance::INFERRED); - } - } - // Check for correct options combinations // If you are running WLdriven placement, the RL reward function should be // either basic or nonPenalizing basic diff --git a/include/base_fix/PATCHED/read_options.h b/include/base_fix/PATCHED/read_options.h index 5ea360cb..6396de7f 100644 --- a/include/base_fix/PATCHED/read_options.h +++ b/include/base_fix/PATCHED/read_options.h @@ -29,7 +29,6 @@ struct t_options { argparse::ArgValue write_rr_graph_file; argparse::ArgValue read_rr_graph_file; argparse::ArgValue write_initial_place_file; - argparse::ArgValue read_initial_place_file; argparse::ArgValue read_vpr_constraints_file; argparse::ArgValue write_vpr_constraints_file; argparse::ArgValue write_constraints_file; @@ -50,7 +49,6 @@ struct t_options { argparse::ArgValue do_packing; argparse::ArgValue do_legalize; argparse::ArgValue do_placement; - argparse::ArgValue do_analytical_placement; argparse::ArgValue do_routing; argparse::ArgValue do_analysis; argparse::ArgValue do_power; @@ -225,12 +223,9 @@ struct t_options { argparse::ArgValue reorder_rr_graph_nodes_seed; argparse::ArgValue flat_routing; argparse::ArgValue has_choking_spot; - argparse::ArgValue route_verbosity; - argparse::ArgValue custom_3d_sb_fanin_fanout; /* Timing-driven router options only */ argparse::ArgValue astar_fac; - argparse::ArgValue astar_offset; argparse::ArgValue router_profiler_astar_fac; argparse::ArgValue max_criticality; argparse::ArgValue criticality_exp; diff --git a/include/base_fix/PATCHED/vpr_api.cpp b/include/base_fix/PATCHED/vpr_api.cpp index a56f3241..bf393a98 100644 --- a/include/base_fix/PATCHED/vpr_api.cpp +++ b/include/base_fix/PATCHED/vpr_api.cpp @@ -15,8 +15,6 @@ #include #include -#include "cluster_util.h" -#include "vpr_context.h" #include "vtr_assert.h" #include "vtr_math.h" #include "vtr_log.h" @@ -69,7 +67,6 @@ #include "place_constraints.h" #include "place_util.h" #include "timing_fail_error.h" -#include "analytical_placement_flow.h" #include "vpr_constraints_writer.h" @@ -286,7 +283,6 @@ void vpr_init_with_options(const t_options* options, t_vpr_setup* vpr_setup, t_a &vpr_setup->NetlistOpts, &vpr_setup->PackerOpts, &vpr_setup->PlacerOpts, - &vpr_setup->APOpts, &vpr_setup->AnnealSched, &vpr_setup->RouterOpts, &vpr_setup->AnalysisOpts, @@ -309,7 +305,6 @@ void vpr_init_with_options(const t_options* options, t_vpr_setup* vpr_setup, t_a /* Verify settings don't conflict or otherwise not make sense */ CheckSetup(vpr_setup->PackerOpts, vpr_setup->PlacerOpts, - vpr_setup->APOpts, vpr_setup->RouterOpts, vpr_setup->ServerOpts, vpr_setup->RoutingArch, vpr_setup->Segments, vpr_setup->Timing, arch->Chans); @@ -364,7 +359,9 @@ void vpr_init_with_options(const t_options* options, t_vpr_setup* vpr_setup, t_a fflush(stdout); + auto& helper_ctx = g_vpr_ctx.mutable_cl_helper(); auto& device_ctx = g_vpr_ctx.mutable_device(); + helper_ctx.lb_type_rr_graphs = vpr_setup->PackerRRGraph; device_ctx.pad_loc_type = vpr_setup->PlacerOpts.pad_loc_type; } @@ -380,8 +377,6 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) { tbb::global_control c(tbb::global_control::max_allowed_parallelism, vpr_setup.num_workers); #endif - g_vpr_ctx.mutable_logic_levels().levelize(); - { //Pack bool pack_success = vpr_pack_flow(vpr_setup, arch); @@ -407,23 +402,6 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) { return false; //Unimplementable } } - - { // Analytical Place - if (vpr_setup.APOpts.doAP == STAGE_DO) { - // TODO: Make this return a bool if the placement was successful or not. - run_analytical_placement_flow(vpr_setup); - } - // Print the placement generated by AP to a .place file. - auto& filename_opts = vpr_setup.FileNameOpts; - auto& cluster_ctx = g_vpr_ctx.clustering(); - const auto& block_locs = g_vpr_ctx.placement().block_locs(); - auto& placement_id = g_vpr_ctx.mutable_placement().placement_id; - placement_id = print_place(filename_opts.NetFile.c_str(), - cluster_ctx.clb_nlist.netlist_id().c_str(), - filename_opts.PlaceFile.c_str(), - block_locs); - } - bool is_flat = vpr_setup.RouterOpts.flat_routing; const Netlist<>& router_net_list = is_flat ? (const Netlist<>&)g_vpr_ctx.atom().nlist : (const Netlist<>&)g_vpr_ctx.clustering().clb_nlist; RouteStatus route_status; @@ -556,7 +534,7 @@ void vpr_setup_clock_networks(t_vpr_setup& vpr_setup, const t_arch& Arch) { * constraints. Additionally, the graphics state is updated * to include a NoC button to display it. * - * @param vpr_setup A data structure that stores all the user provided option + * @param vpr_setup A datastructure that stores all the user provided option * to vpr. * @param arch Contains the parsed information from the architecture * description file. @@ -590,12 +568,11 @@ void vpr_setup_noc(const t_vpr_setup& vpr_setup, const t_arch& arch) { * NoC routing algorithm */ void vpr_setup_noc_routing_algorithm(const std::string& noc_routing_algorithm_name) { - // Need to be able to modify the NoC context, since we will be adding the + // Need to be abke to modify the NoC context, since we will be adding the // newly created routing algorithm to it auto& noc_ctx = g_vpr_ctx.mutable_noc(); - noc_ctx.noc_flows_router = NocRoutingAlgorithmCreator::create_routing_algorithm(noc_routing_algorithm_name, - noc_ctx.noc_model); + noc_ctx.noc_flows_router = NocRoutingAlgorithmCreator::create_routing_algorithm(noc_routing_algorithm_name); } bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) { @@ -636,13 +613,12 @@ bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) { //Load a previous packing from the .net file vpr_load_packing(vpr_setup, arch); + //Load cluster_constraints data structure here since loading pack file + load_cluster_constraints(); } } - // Load cluster_constraints data structure. - load_cluster_constraints(); - /* Sanity check the resulting netlist */ check_netlist(packer_opts.pack_verbosity); @@ -720,7 +696,6 @@ void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) { "Must have valid .net filename to load packing"); auto& cluster_ctx = g_vpr_ctx.mutable_clustering(); - const AtomContext& atom_ctx = g_vpr_ctx.atom(); /* Ensure we have a clean start with void net remapping information */ cluster_ctx.post_routing_clb_pin_nets.clear(); @@ -731,11 +706,8 @@ void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) { vpr_setup.FileNameOpts.verify_file_digests, vpr_setup.PackerOpts.pack_verbosity); - /* Load the mapping between clusters and their atoms */ - init_clb_atoms_lookup(cluster_ctx.atoms_lookup, atom_ctx, cluster_ctx.clb_nlist); - process_constant_nets(g_vpr_ctx.mutable_atom().nlist, - atom_ctx.lookup, + g_vpr_ctx.atom().lookup, cluster_ctx.clb_nlist, vpr_setup.constant_net_method, vpr_setup.PackerOpts.pack_verbosity); @@ -817,7 +789,7 @@ bool vpr_place_flow(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_a void vpr_place(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_arch& arch) { bool is_flat = false; - if (vpr_setup.PlacerOpts.place_algorithm.is_timing_driven()) { + if (placer_needs_lookahead(vpr_setup)) { // Prime lookahead cache to avoid adding lookahead computation cost to // the placer timer. // Flat_routing is disabled in placement @@ -845,13 +817,10 @@ void vpr_place(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_arch& auto& filename_opts = vpr_setup.FileNameOpts; auto& cluster_ctx = g_vpr_ctx.clustering(); - const auto& block_locs = g_vpr_ctx.placement().block_locs(); - auto& placement_id = g_vpr_ctx.mutable_placement().placement_id; - placement_id = print_place(filename_opts.NetFile.c_str(), - cluster_ctx.clb_nlist.netlist_id().c_str(), - filename_opts.PlaceFile.c_str(), - block_locs); + print_place(filename_opts.NetFile.c_str(), + cluster_ctx.clb_nlist.netlist_id().c_str(), + filename_opts.PlaceFile.c_str()); } void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& arch) { @@ -862,14 +831,10 @@ void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& arch) { const auto& filename_opts = vpr_setup.FileNameOpts; //Initialize placement data structures, which will be filled when loading placement - auto& block_locs = place_ctx.mutable_block_locs(); - GridBlock& grid_blocks = place_ctx.mutable_grid_blocks(); - init_placement_context(block_locs, grid_blocks); + init_placement_context(); //Load an existing placement from a file - place_ctx.placement_id = read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(), - place_ctx.mutable_blk_loc_registry(), - filename_opts.verify_file_digests, device_ctx.grid); + read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(), filename_opts.verify_file_digests, device_ctx.grid); //Ensure placement macros are loaded so that they can be drawn after placement (e.g. during routing) place_ctx.pl_macros = alloc_and_load_placement_macros(arch.Directs, arch.num_directs); @@ -893,7 +858,7 @@ RouteStatus vpr_route_flow(const Netlist<>& net_list, route_status = RouteStatus(true, -1); } else { //Do or load - // set the net_is_ignored flag for nets that have route_model set to ideal in route constraints + // set the net_is_ignored flag for nets that that have route_model set to ideal in route constraints apply_route_constraints(g_vpr_ctx.routing().constraints); int chan_width = router_opts.fixed_channel_width; @@ -1107,7 +1072,7 @@ RouteStatus vpr_load_routing(t_vpr_setup& vpr_setup, net_delay); timing_info->update(); } - init_draw_coords(fixed_channel_width, g_vpr_ctx.placement().blk_loc_registry()); + init_draw_coords(fixed_channel_width); return RouteStatus(is_legal, fixed_channel_width); } @@ -1149,7 +1114,7 @@ void vpr_create_rr_graph(t_vpr_setup& vpr_setup, const t_arch& arch, int chan_wi &warnings, is_flat); //Initialize drawing, now that we have an RR graph - init_draw_coords(chan_width_fac, g_vpr_ctx.placement().blk_loc_registry()); + init_draw_coords(chan_width_fac); } void vpr_init_graphics(const t_vpr_setup& vpr_setup, const t_arch& arch, bool is_flat) { @@ -1315,8 +1280,8 @@ static void free_atoms() { static void free_placement() { auto& place_ctx = g_vpr_ctx.mutable_placement(); - place_ctx.mutable_block_locs().clear(); - place_ctx.mutable_grid_blocks().clear(); + place_ctx.block_locs.clear(); + place_ctx.grid_blocks.clear(); } static void free_routing() { @@ -1332,7 +1297,7 @@ static void free_routing() { } /** - * @brief handles the deletion of NoC related data structures. + * @brief handles the deletion of NoC related datastructures. */ static void free_noc() {} @@ -1379,7 +1344,6 @@ void vpr_setup_vpr(t_options* Options, t_netlist_opts* NetlistOpts, t_packer_opts* PackerOpts, t_placer_opts* PlacerOpts, - t_ap_opts* APOpts, t_annealing_sched* AnnealSched, t_router_opts* RouterOpts, t_analysis_opts* AnalysisOpts, @@ -1405,7 +1369,6 @@ void vpr_setup_vpr(t_options* Options, NetlistOpts, PackerOpts, PlacerOpts, - APOpts, AnnealSched, RouterOpts, AnalysisOpts, @@ -1430,22 +1393,14 @@ void vpr_check_arch(const t_arch& Arch) { ///@brief Verify settings don't conflict or otherwise not make sense void vpr_check_setup(const t_packer_opts& PackerOpts, const t_placer_opts& PlacerOpts, - const t_ap_opts& APOpts, const t_router_opts& RouterOpts, const t_server_opts& ServerOpts, const t_det_routing_arch& RoutingArch, const std::vector& Segments, const t_timing_inf& Timing, const t_chan_width_dist& Chans) { - CheckSetup(PackerOpts, - PlacerOpts, - APOpts, - RouterOpts, - ServerOpts, - RoutingArch, - Segments, - Timing, - Chans); + CheckSetup(PackerOpts, PlacerOpts, RouterOpts, ServerOpts, RoutingArch, + Segments, Timing, Chans); } ///@brief Show current setup @@ -1525,7 +1480,6 @@ void vpr_analysis(const Netlist<>& net_list, bool is_flat) { auto& route_ctx = g_vpr_ctx.routing(); auto& atom_ctx = g_vpr_ctx.atom(); - const auto& blk_loc_registry = g_vpr_ctx.placement().blk_loc_registry(); if (route_ctx.route_trees.empty()) { VPR_FATAL_ERROR(VPR_ERROR_ANALYSIS, "No routing loaded -- can not perform post-routing analysis"); @@ -1546,7 +1500,8 @@ void vpr_analysis(const Netlist<>& net_list, //Load the net delays NetPinsMatrix net_delay = make_net_pins_matrix(net_list); - load_net_delay_from_routing(net_list, net_delay); + load_net_delay_from_routing(net_list, + net_delay); //Do final timing analysis auto analysis_delay_calc = std::make_shared(atom_ctx.nlist, atom_ctx.lookup, net_delay, vpr_setup.RouterOpts.flat_routing); @@ -1561,10 +1516,10 @@ void vpr_analysis(const Netlist<>& net_list, //Timing stats VTR_LOG("\n"); - generate_hold_timing_stats(/*prefix=*/"", *timing_info, *analysis_delay_calc, - vpr_setup.AnalysisOpts, vpr_setup.RouterOpts.flat_routing, blk_loc_registry); - generate_setup_timing_stats(/*prefix=*/"", *timing_info, *analysis_delay_calc, - vpr_setup.AnalysisOpts, vpr_setup.RouterOpts.flat_routing, blk_loc_registry); + generate_hold_timing_stats(/*prefix=*/"", *timing_info, + *analysis_delay_calc, vpr_setup.AnalysisOpts, vpr_setup.RouterOpts.flat_routing); + generate_setup_timing_stats(/*prefix=*/"", *timing_info, + *analysis_delay_calc, vpr_setup.AnalysisOpts, vpr_setup.RouterOpts.flat_routing); //Write the post-synthesis netlist if (vpr_setup.AnalysisOpts.gen_post_synthesis_netlist) { @@ -1674,9 +1629,6 @@ void vpr_print_error(const VprError& vpr_error) { case VPR_ERROR_PLACE: error_type = "Placement"; break; - case VPR_ERROR_AP: - error_type = "Analytical Placement"; - break; case VPR_ERROR_ROUTE: error_type = "Routing"; break; diff --git a/include/base_fix/PATCHED/vpr_context.h b/include/base_fix/PATCHED/vpr_context.h index 00a10aa7..5a6ad393 100644 --- a/include/base_fix/PATCHED/vpr_context.h +++ b/include/base_fix/PATCHED/vpr_context.h @@ -5,12 +5,10 @@ #include #include -#include "prepack.h" #include "vpr_types.h" #include "vtr_ndmatrix.h" #include "vtr_optional.h" #include "vtr_vector.h" -#include "vtr_vector_map.h" #include "atom_netlist.h" #include "clustered_netlist.h" #include "rr_graph_view.h" @@ -35,7 +33,6 @@ #include "noc_traffic_flows.h" #include "noc_routing.h" #include "tatum/report/TimingPath.hpp" -#include "blk_loc_registry.h" #ifndef NO_SERVER @@ -76,11 +73,34 @@ struct AtomContext : public Context { /******************************************************************** * Atom Netlist ********************************************************************/ - /// @brief Atom netlist + /** + * @brief constructor + * + * In the constructor initialize the list of pack molecules to nullptr and defines a custom deletor for it + */ + AtomContext() + : list_of_pack_molecules(nullptr, free_pack_molecules) {} + + ///@brief Atom netlist AtomNetlist nlist; - /// @brief Mappings to/from the Atom Netlist to physically described .blif models + ///@brief Mappings to/from the Atom Netlist to physically described .blif models AtomLookup lookup; + + /** + * @brief The molecules associated with each atom block. + * + * This map is loaded in the pre-packing stage and freed at the very end of vpr flow run. + * The pointers in this multimap is shared with list_of_pack_molecules. + */ + std::multimap atom_molecules; + + /** + * @brief A linked list of all the packing molecules that are loaded in pre-packing stage. + * + * Is is useful in freeing the pack molecules at the destructor of the Atom context using free_pack_molecules. + */ + std::unique_ptr list_of_pack_molecules; }; /** @@ -139,9 +159,7 @@ struct DeviceContext : public Context { /** * @brief The device grid * - * This represents the physical layout of the device. - * To get the physical tile at each location (layer_num, x, y) the helper functions - * in this data structure should be used. + * This represents the physical layout of the device. To get the physical tile at each location (layer_num, x, y) the helper functions in this data structure should be used. */ DeviceGrid grid; /* @@ -291,23 +309,69 @@ struct ClusteringContext : public Context { * CLB Netlist ********************************************************************/ - /// @brief New netlist class derived from Netlist + ///@brief New netlist class derived from Netlist ClusteredNetlist clb_nlist; - /// @brief Database for nets of each clb block pin after routing stage. - /// - post_routing_clb_pin_nets: - /// mapping of pb_type pins to clustered net ids. - /// - pre_routing_net_pin_mapping: - /// a copy of mapping for current pb_route index to previous pb_route index - /// Record the previous pin mapping for finding the correct pin index during - /// timing analysis. + /* Database for nets of each clb block pin after routing stage + * - post_routing_clb_pin_nets: + * mapping of pb_type pins to clustered net ids + * - pre_routing_net_pin_mapping: + * a copy of mapping for current pb_route index to previous pb_route index + * Record the previous pin mapping for finding the correct pin index during timing analysis + */ std::map> post_routing_clb_pin_nets; std::map> pre_routing_net_pin_mapping; +}; + +/** + * @brief State relating to helper data structure using in the clustering stage + * + * This should contain helper data structures that are useful in the clustering/packing stage. + * They are encapsulated here as they are useful in clustering and reclustering algorithms that may be used + * in packing or placement stages. + */ +struct ClusteringHelperContext : public Context { + // A map used to save the number of used instances from each logical block type. + std::map num_used_type_instances; + + // Stats keeper for placement information during packing/clustering + t_cluster_placement_stats* cluster_placement_stats; + + // total number of models in the architecture + int num_models; + + int max_cluster_size; + t_pb_graph_node** primitives_list; + + bool enable_pin_feasibility_filter; + int feasible_block_array_size; + + // total number of CLBs + int total_clb_num; + + // A vector of routing resource nodes within each of logic cluster_ctx.blocks types [0 .. num_logical_block_type-1] + std::vector* lb_type_rr_graphs; + + // the utilization of external input/output pins during packing (between 0 and 1) + t_ext_pin_util_targets target_external_pin_util; - /// @brief A vector of unordered_sets of AtomBlockIds that are inside each - /// clustered block [0 .. num_clustered_blocks-1] - /// This is populated when the packing is loaded. + // During clustering, a block is related to un-clustered primitives with nets. + // This relation has three types: low fanout, high fanout, and transitive + // high_fanout_thresholds stores the threshold for nets to a block type to be considered high fanout + t_pack_high_fanout_thresholds high_fanout_thresholds; + + // A vector of unordered_sets of AtomBlockIds that are inside each clustered block [0 .. num_clustered_blocks-1] + // unordered_set for faster insertion/deletion during the iterative improvement process of packing vtr::vector> atoms_lookup; + + /** Stores the NoC group ID of each atom block. Atom blocks that belong + * to different NoC groups can't be clustered with each other into the + * same clustered block.*/ + vtr::vector atom_noc_grp_id; + + ~ClusteringHelperContext() { + delete[] primitives_list; + } }; /** @@ -327,48 +391,14 @@ struct PackingMultithreadingContext : public Context { * or related placer algorithm state. */ struct PlacementContext : public Context { - private: - /** - * Determines if blk_loc_registry_ can be accessed by calling getter methods. - * This flag should be set to false at the beginning of the placement stage, - * and set to true at the end of placement. This ensures that variables that - * are subject to change during placement are kept local to the placement stage. - */ - bool loc_vars_are_accessible_ = true; - - /** - * @brief Stores block location information, which is subject to change during the - * placement stage. - */ - BlkLocRegistry blk_loc_registry_; - - public: + ///@brief Clustered block placement locations + vtr::vector_map block_locs; - const vtr::vector_map& block_locs() const { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.block_locs(); } - vtr::vector_map& mutable_block_locs() { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.mutable_block_locs(); } - const GridBlock& grid_blocks() const { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.grid_blocks(); } - GridBlock& mutable_grid_blocks() { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.mutable_grid_blocks(); } - vtr::vector_map& mutable_physical_pins() { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.mutable_physical_pins(); } - const vtr::vector_map& physical_pins() const { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_.physical_pins(); } - BlkLocRegistry& mutable_blk_loc_registry() { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_; } - const BlkLocRegistry& blk_loc_registry() const { VTR_ASSERT_SAFE(loc_vars_are_accessible_); return blk_loc_registry_; } + ///@brief Clustered pin placement mapping with physical pin + vtr::vector_map physical_pins; - /** - * @brief Makes blk_loc_registry_ inaccessible through the getter methods. - * - * This method should be called at the beginning of the placement stage to - * guarantee that the placement stage code does not access block location variables - * stored in the global state. - */ - void lock_loc_vars() { VTR_ASSERT_SAFE(loc_vars_are_accessible_); loc_vars_are_accessible_ = false; } - - /** - * @brief Makes blk_loc_registry_ accessible through the getter methods. - * - * This method should be called at the end of the placement stage to - * make the block location information accessible for subsequent stages. - */ - void unlock_loc_vars() { VTR_ASSERT_SAFE(!loc_vars_are_accessible_); loc_vars_are_accessible_ = true; } + ///@brief Clustered block associated with each grid location (i.e. inverse of block_locs) + GridBlock grid_blocks; ///@brief The pl_macros array stores all the placement macros (usually carry chains). std::vector pl_macros; @@ -507,24 +537,15 @@ struct FloorplanningContext : public Context { /** * @brief Floorplanning constraints in the compressed grid coordinate system. * - * Indexing --> [0..grid.num_layers-1][0..numClusters-1] - * * Each clustered block has a logical type with a corresponding compressed grid. * Compressed floorplanning constraints are calculated by translating the grid locations * of floorplanning regions to compressed grid locations. To ensure regions do not enlarge: * - The bottom left corner is rounded up to the nearest compressed location. * - The top right corner is rounded down to the nearest compressed location. - * - * When the floorplanning constraint spans across multiple layers, a compressed - * constraints is created for each a layer that the original constraint includes. - * This is because blocks of the same type might have different (x, y) locations - * in different layers, and as result, their compressed locations in each layer - * may correspond to a different physical (x, y) location. - * */ - std::vector> compressed_cluster_constraints; + vtr::vector compressed_cluster_constraints; - std::vector overfull_partition_regions; + std::vector overfull_regions; }; /** @@ -550,8 +571,7 @@ struct NocContext : public Context { /** * @brief Stores all the communication happening between routers in the NoC * - * Contains all of the traffic flows that describe which pairs of logical routers are - * communicating and also some metrics and constraints on the data transfer between the two routers. + * Contains all of the traffic flows that describe which pairs of logical routers are communicating and also some metrics and constraints on the data transfer between the two routers. * * * This is created from a user supplied .flows file. @@ -688,6 +708,9 @@ class VprContext : public Context { const ClusteringContext& clustering() const { return clustering_; } ClusteringContext& mutable_clustering() { return clustering_; } + const ClusteringHelperContext& cl_helper() const { return helper_; } + ClusteringHelperContext& mutable_cl_helper() { return helper_; } + const PlacementContext& placement() const { return placement_; } PlacementContext& mutable_placement() { return placement_; } @@ -720,6 +743,8 @@ class VprContext : public Context { PowerContext power_; ClusteringContext clustering_; + ClusteringHelperContext helper_; + PlacementContext placement_; RoutingContext routing_; FloorplanningContext constraints_; diff --git a/include/base_fix/PATCHED/vpr_types.h b/include/base_fix/PATCHED/vpr_types.h index 28282924..d6c961c3 100644 --- a/include/base_fix/PATCHED/vpr_types.h +++ b/include/base_fix/PATCHED/vpr_types.h @@ -48,7 +48,6 @@ #include "rr_graph_fwd.h" #include "rr_graph_cost.h" #include "rr_graph_type.h" -#include "vtr_vector_map.h" /******************************************************************************* * Global data types and constants @@ -95,6 +94,12 @@ enum class ScreenUpdatePriority { /* Used to avoid floating-point errors when comparing values close to 0 */ #define EPSILON 1.e-15 +#define FIRST_ITER_WIRELENTH_LIMIT 0.85 /* If used wirelength exceeds this value in first iteration of routing, do not route */ + +/* Defining macros for the placement_ctx t_grid_blocks. Assumes that ClusterBlockId's won't exceed positive 32-bit integers */ +constexpr auto EMPTY_BLOCK_ID = ClusterBlockId(-1); +constexpr auto INVALID_BLOCK_ID = ClusterBlockId(-2); + /* * Files */ @@ -110,18 +115,12 @@ enum class ScreenUpdatePriority { # define UNDEFINED (-1) #endif -///@brief Router lookahead types. enum class e_router_lookahead { - ///@brief VPR's classic lookahead (assumes uniform wire types) - CLASSIC, - ///@brief Lookahead considering different wire types (see Oleg Petelin's MASc Thesis) - MAP, - ///@brief Similar to MAP, but use a sparse sampling of the chip - COMPRESSED_MAP, - ///@brief Lookahead with a more extensive node sampling method - EXTENDED_MAP, - ///@brief A no-operation lookahead which always returns zero - NO_OP + CLASSIC, ///> valid_primitives; + + public: + // Moves primitives that are inflight to the tried map + void move_inflight_to_tried(); + + /** + * @brief Move the primitive at (it) to inflight and increment the current iterator. + * + * Because the element at (it) is deleted from valid_primitives, (it) is incremented to keep it valid and pointing at the next element. + * + * @param pb_type_index: is the index of this pb_type in valid_primitives vector + * @param it: is the iterator pointing at the element that needs to be moved to inflight + */ + void move_primitive_to_inflight(int pb_type_index, std::unordered_multimap::iterator& it); + + /** + * @brief Move the primitive at (it) to invalid and increment the current iterator + * + * Because the element at (it) is deleted from valid_primitives, (it) is incremented to keep it valid and pointing at the next element. + * + * @param pb_type_index: is the index of this pb_type in valid_primitives vector + * @param it: is the iterator pointing at the element that needs to be moved to invalid + */ + void invalidate_primitive_and_increment_iterator(int pb_type_index, std::unordered_multimap::iterator& it); + + /** + * @brief Add a primitive in its correct location in valid_primitives vector based on its pb_type + * + * @param cluster_placement_primitive: a pair of the cluster_placement_primtive and its corresponding index(for reference in pb_graph_node) + */ + void insert_primitive_in_valid_primitives(std::pair cluster_placement_primitive); + + /** + * @brief Move all the primitives from (in_flight and tried) maps to valid primitives and clear (in_flight and tried) + */ + void flush_intermediate_queues(); + + /** + * @brief Move all the primitives from invalid to valid_primitives and clear the invalid map + */ + void flush_invalid_queue(); + + /** + * @brief Return true if the in_flight map is empty (no primitive is in_flight currently) + */ + bool in_flight_empty(); + + /** + * @brief Return the type of the first element of the primitives currently being considered + */ + t_pb_type* in_flight_type(); + + /** + * @brief free the dynamically allocated memory for primitives + */ + void free_primitives(); + + private: + std::unordered_multimap in_flight; /// tried; /// invalid; ///& queue); +}; + /****************************************************************** * Timing data types *******************************************************************/ @@ -535,7 +627,6 @@ struct t_2D_bb { VTR_ASSERT(ymax_ >= ymin_); VTR_ASSERT(layer_num_ >= 0); } - int xmin = OPEN; int xmax = OPEN; int ymin = OPEN; @@ -742,6 +833,73 @@ struct t_block_loc { bool is_fixed = false; }; +///@brief Stores the clustered blocks placed at a particular grid location +struct t_grid_blocks { + int usage; ///capacity] + */ + std::vector blocks; + + /** + * @brief Test if a subtile at a grid location is occupied by a block. + * + * Returns true if the subtile corresponds to the passed-in id is not + * occupied by a block at this grid location. The subtile id serves + * as the z-dimensional offset in the grid indexing. + */ + inline bool subtile_empty(size_t isubtile) const { + return blocks[isubtile] == EMPTY_BLOCK_ID; + } +}; + +class GridBlock { + public: + GridBlock() = default; + + GridBlock(size_t width, size_t height, size_t layers) { + grid_blocks_.resize({layers, width, height}); + } + + inline void initialized_grid_block_at_location(const t_physical_tile_loc& loc, int num_sub_tiles) { + grid_blocks_[loc.layer_num][loc.x][loc.y].blocks.resize(num_sub_tiles, EMPTY_BLOCK_ID); + } + + inline void set_block_at_location(const t_pl_loc& loc, ClusterBlockId blk_id) { + grid_blocks_[loc.layer][loc.x][loc.y].blocks[loc.sub_tile] = blk_id; + } + + inline ClusterBlockId block_at_location(const t_pl_loc& loc) const { + return grid_blocks_[loc.layer][loc.x][loc.y].blocks[loc.sub_tile]; + } + + inline size_t num_blocks_at_location(const t_physical_tile_loc& loc) const { + return grid_blocks_[loc.layer_num][loc.x][loc.y].blocks.size(); + } + + inline int set_usage(const t_physical_tile_loc loc, int usage) { + return grid_blocks_[loc.layer_num][loc.x][loc.y].usage = usage; + } + + inline int get_usage(const t_physical_tile_loc loc) const { + return grid_blocks_[loc.layer_num][loc.x][loc.y].usage; + } + + inline bool is_sub_tile_empty(const t_physical_tile_loc loc, int sub_tile) const { + return grid_blocks_[loc.layer_num][loc.x][loc.y].subtile_empty(sub_tile); + } + + inline void clear() { + grid_blocks_.clear(); + } + + private: + vtr::NdMatrix grid_blocks_; +}; + ///@brief Names of various files struct t_file_name_opts { std::string ArchFile; @@ -944,7 +1102,7 @@ class t_place_algorithm { e_place_algorithm algo = e_place_algorithm::CRITICALITY_TIMING_PLACE; }; -enum class e_pad_loc_type { +enum e_pad_loc_type { FREE, RANDOM }; @@ -1077,7 +1235,6 @@ struct t_placer_opts { enum e_pad_loc_type pad_loc_type; std::string constraints_file; std::string write_initial_place_file; - std::string read_initial_place_file; enum pfreq place_freq; int recompute_crit_iter; int inner_loop_recompute_divider; @@ -1150,26 +1307,6 @@ struct t_placer_opts { bool enable_cascade_placer = false; }; - -/****************************************************************** - * Analytical Placer data types - *******************************************************************/ - -/** - * @brief Various options for the Analytical Placer. - * - * @param doAnalyticalPlacement - * True if analytical placement is supposed to be done in the CAD - * flow. False if otherwise. - */ -struct t_ap_opts { - e_stage_action doAP; -}; - -/****************************************************************** - * Router data types - *******************************************************************/ - /* All the parameters controlling the router's operation are in this * * structure. * * first_iter_pres_fac: Present sharing penalty factor used for the * @@ -1207,8 +1344,6 @@ struct t_ap_opts { * an essentially breadth-first search, astar_fac = 1 is near * * the usual astar algorithm and astar_fac > 1 are more * * aggressive. * - * astar_offset: Offset that is subtracted from the lookahead (expected * - * future costs) in the timing-driven router. * * max_criticality: The maximum criticality factor (from 0 to 1) any sink * * will ever have (i.e. clip criticality to this number). * * criticality_exp: Set criticality to (path_length(sink) / longest_path) ^ * @@ -1299,7 +1434,6 @@ struct t_router_opts { enum e_router_algorithm router_algorithm; enum e_base_cost_type base_cost_type; float astar_fac; - float astar_offset; float router_profiler_astar_fac; float max_criticality; float criticality_exp; @@ -1324,7 +1458,6 @@ struct t_router_opts { int router_debug_iteration; e_router_lookahead lookahead_type; int max_convergence_count; - int route_verbosity; float reconvergence_cpd_threshold; e_router_initial_timing initial_timing; bool update_lower_bound_delays; @@ -1350,8 +1483,6 @@ struct t_router_opts { bool flat_routing; bool has_choking_spot; - int custom_3d_sb_fanin_fanout = 1; - bool with_timing_analysis; // Options related to rr_node reordering, for testing and possible cache optimization @@ -1380,22 +1511,22 @@ struct t_analysis_opts { // used to store NoC specific options, when supplied as an input by the user struct t_noc_opts { - bool noc; ///>> t_clb_op typedef std::vector> t_arch_switch_fanin; -struct pair_hash { - std::size_t operator()(const std::pair& p) const noexcept { - return std::hash()(p.first) ^ (std::hash()(p.second) << 1); - } -}; +/** + * @brief Free the linked list that saves all the packing molecules. + */ +void free_pack_molecules(t_pack_molecule* list_of_pack_molecules); + +/** + * @brief Free the linked lists to placement locations based on status of primitive inside placement stats data structure. + */ +void free_cluster_placement_stats(t_cluster_placement_stats* cluster_placement_stats); #endif diff --git a/include/packer_fix/post_routing_pb_pin_fixup.cpp b/include/packer_fix/post_routing_pb_pin_fixup.cpp index 674b22c2..15a137fa 100644 --- a/include/packer_fix/post_routing_pb_pin_fixup.cpp +++ b/include/packer_fix/post_routing_pb_pin_fixup.cpp @@ -80,7 +80,7 @@ static bool check_pb_route_for_block(ClusterBlockId clb_id, PB_route_error& err) { err.reset(); err.clb_id_ = clb_id; - err.clbLoc_ = plCon.block_locs()[clb_id]; + err.clbLoc_ = plCon.block_locs[clb_id]; const t_pb& clb = *clCon.clb_nlist.block_pb(clb_id); VTR_ASSERT(clb.name); @@ -260,7 +260,7 @@ static void update_cluster_pin_with_post_routing_results(const Netlist<>& net_li * Deposit all the sides */ if (wanted_sides.empty()) { - for (e_side side : TOTAL_2D_SIDES) { + for (e_side side : {TOP, BOTTOM, LEFT, RIGHT}) { wanted_sides.push_back(side); } } @@ -309,49 +309,55 @@ static void update_cluster_pin_with_post_routing_results(const Netlist<>& net_li ParentNetId routing_net_id = ParentNetId::INVALID(); std::vector visited_rr_nodes; short valid_routing_net_cnt = 0; - for (const e_side& pin_side : pin_sides) { - /* Find the net mapped to this pin in routing results */ - RRNodeId rr_node = node_lookup.find_node(coord_layer, coord_x, coord_y, rr_node_type, physical_pin, pin_side); - - /* Bypass invalid nodes, after that we must have a valid rr_node id */ - if (!rr_node) { - continue; - } - VTR_ASSERT((size_t)rr_node < device_ctx.rr_graph.num_nodes()); + int addToY = 0, addToX = 0; + addToY = physical_tile->height; + addToX = physical_tile->width; + for (int ix = 0; ix < addToX; ix++) { + for (int iy = 0; iy < addToY; iy++) { + for (const e_side& pin_side : pin_sides) { + /* Find the net mapped to this pin in routing results */ + RRNodeId rr_node = node_lookup.find_node(coord_layer, coord_x + ix, coord_y + iy, rr_node_type, physical_pin, pin_side); + + /* Bypass invalid nodes, after that we must have a valid rr_node id */ + if (!rr_node) { + continue; + } + VTR_ASSERT((size_t)rr_node < device_ctx.rr_graph.num_nodes()); - /* If the node has been visited on the other side, we just skip it */ - if (visited_rr_nodes.end() != std::find(visited_rr_nodes.begin(), visited_rr_nodes.end(), RRNodeId(rr_node))) { - continue; - } + /* If the node has been visited on the other side, we just skip it */ + if (visited_rr_nodes.end() != std::find(visited_rr_nodes.begin(), visited_rr_nodes.end(), RRNodeId(rr_node))) { + continue; + } - /* Get the cluster net id which has been mapped to this net - * In general, there is only one valid rr_node among all the sides. - * However, we have an exception in the Stratix-IV arch modeling, - * where a pb_pin may exist in two different sides but - * router will only map to 1 rr_node - * Therefore, it is better to compare the routing nets - * for all the sides and pick - * - The unique valid net id (others should be all invalid) - * assume that this pin is used by router - * - A invalid net id (others should be all invalid as well) - * assume that this pin is not used by router - */ - if (rr_node_nets[rr_node]) { - if (routing_net_id) { - if (routing_net_id != rr_node_nets[rr_node]) { - VTR_LOG_ERROR("Pin '%s' is mapped to two nets: '%s' and '%s'\n", - pb_graph_pin->to_string().c_str(), - net_list.net_name(routing_net_id).c_str(), - net_list.net_name(rr_node_nets[rr_node]).c_str()); + /* Get the cluster net id which has been mapped to this net + * In general, there is only one valid rr_node among all the sides. + * However, we have an exception in the Stratix-IV arch modeling, + * where a pb_pin may exist in two different sides but + * router will only map to 1 rr_node + * Therefore, it is better to compare the routing nets + * for all the sides and pick + * - The unique valid net id (others should be all invalid) + * assume that this pin is used by router + * - A invalid net id (others should be all invalid as well) + * assume that this pin is not used by router + */ + if (rr_node_nets[rr_node]) { + if (routing_net_id) { + if (routing_net_id != rr_node_nets[rr_node]) { + VTR_LOG_ERROR("Pin '%s' is mapped to two nets: '%s' and '%s'\n", + pb_graph_pin->to_string().c_str(), + net_list.net_name(routing_net_id).c_str(), + net_list.net_name(rr_node_nets[rr_node]).c_str()); + } + VTR_ASSERT(routing_net_id == rr_node_nets[rr_node]); + } + routing_net_id = rr_node_nets[rr_node]; + valid_routing_net_cnt++; + visited_rr_nodes.push_back(rr_node); } - VTR_ASSERT(routing_net_id == rr_node_nets[rr_node]); } - routing_net_id = rr_node_nets[rr_node]; - valid_routing_net_cnt++; - visited_rr_nodes.push_back(rr_node); } } - VTR_ASSERT((0 == valid_routing_net_cnt) || (1 == valid_routing_net_cnt)); /* Find the net mapped to this pin in clustering results*/ @@ -929,7 +935,8 @@ static void update_cluster_regular_routing_traces_with_post_routing_results(Atom */ VTR_ASSERT(sink_pb_route == sink_pb_pin_to_add->pin_count_in_cluster); t_pb_graph_pin* new_sink_pb_pin_to_add = sink_pb_pin_to_add; - VTR_ASSERT(is_single_fanout_pb_pin(const_cast(new_sink_pb_pin_to_add))); + //VTR_ASSERT(is_single_fanout_pb_pin(const_cast(new_sink_pb_pin_to_add))); + VTR_ASSERT(new_sink_pb_pin_to_add->output_edges[0]->num_output_pins == 1); int new_driver_pb_pin = pb_graph_pin->pin_count_in_cluster; while (1) { int new_sink_pb_route_id = new_sink_pb_pin_to_add->pin_count_in_cluster; @@ -1038,7 +1045,7 @@ static void update_cluster_regular_routing_traces_with_post_routing_results(Atom for (int& sink_pb_route : new_pb_route.sink_pb_pin_ids) { usedItems.push_back(sink_pb_route); } - + VTR_LOGV(verbose, "Remap clustered block '%s' routing trace[%d] to net '%s'\n", clustering_ctx.clb_nlist.block_pb(blk_id)->name, @@ -1257,6 +1264,8 @@ void sync_netlists_to_routing(const Netlist<>& net_list, clb_blk_id = convert_to_cluster_block_id(blk_id); } VTR_ASSERT(clb_blk_id != ClusterBlockId::INVALID()); + // vtr::Point grid_coord(placement_ctx.block_locs[clb_blk_id].loc.x, + // placement_ctx.block_locs[clb_blk_id].loc.y); if (seen_block_ids.insert(clb_blk_id).second) { update_cluster_pin_with_post_routing_results(net_list, @@ -1264,8 +1273,9 @@ void sync_netlists_to_routing(const Netlist<>& net_list, device_ctx, clustering_ctx, rr_node_nets, - placement_ctx.block_locs()[clb_blk_id].loc, + placement_ctx.block_locs[clb_blk_id].loc, clb_blk_id, + // placement_ctx.block_locs[clb_blk_id].loc.sub_tile, num_mismatches, verbose, is_flat); diff --git a/include/tatum_fix/TimingReporter.cpp b/include/tatum_fix/TimingReporter.cpp index 7b734710..38184f30 100644 --- a/include/tatum_fix/TimingReporter.cpp +++ b/include/tatum_fix/TimingReporter.cpp @@ -610,7 +610,7 @@ Time TimingReporter::report_timing_data_arrival_subpath(std::ostream& os, { //Input constraint - TATUM_ASSERT(!subpath.elements().empty()); + TATUM_ASSERT(subpath.elements().size() > 0); const TimingPathElem& path_elem = *(subpath.elements().begin()); Time input_constraint; @@ -716,7 +716,7 @@ bool TimingReporter::nearly_equal(const Time& lhs, const Time& rhs) const { size_t TimingReporter::estimate_point_print_width(const TimingPath& path) const { size_t width = 60; //default - for(const auto& subpath : {path.clock_launch_path(), path.data_arrival_path(), path.clock_capture_path()}) { + for(auto subpath : {path.clock_launch_path(), path.data_arrival_path(), path.clock_capture_path()}) { for(auto elem : subpath.elements()) { //Take the longest typical point name std::string point = name_resolver_.node_name(elem.node()) + " (" + name_resolver_.node_type_name(elem.node()) + ")"; diff --git a/include/util_fix/rsbe_utils.cpp b/include/util_fix/rsbe_utils.cpp index f7e806b6..78fd1fbf 100644 --- a/include/util_fix/rsbe_utils.cpp +++ b/include/util_fix/rsbe_utils.cpp @@ -20,6 +20,7 @@ #include "pack_types.h" #include "device_grid.h" #include "timing_fail_error.h" +#include "re_cluster_util.h" namespace rsbe {