diff --git a/openfpga/src/annotation/annotate_rr_graph.cpp b/openfpga/src/annotation/annotate_rr_graph.cpp index 880edc74d..4af681c71 100644 --- a/openfpga/src/annotation/annotate_rr_graph.cpp +++ b/openfpga/src/annotation/annotate_rr_graph.cpp @@ -387,12 +387,12 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx, /* For each switch block, determine the size of array */ for (size_t ix = 0; ix < gsb_range.x(); ++ix) { for (size_t iy = 0; iy < gsb_range.y(); ++iy) { - /* Here we give the builder the fringe coordinates so that it can handle the GSBs at the borderside correctly */ + /* Here we give the builder the fringe coordinates so that it can handle the GSBs at the borderside correctly + * sort drive_rr_nodes should be called if required by users + */ const RRGSB& rr_gsb = build_rr_gsb(vpr_device_ctx, vtr::Point(vpr_device_ctx.grid.width() - 2, vpr_device_ctx.grid.height() - 2), vtr::Point(ix, iy)); - /* TODO: sort drive_rr_nodes should be done when building the tileable rr_graph */ - //sort_rr_gsb_drive_rr_nodes(rr_gsb); /* Add to device_rr_gsb */ vtr::Point gsb_coordinate = rr_gsb.get_sb_coordinate(); @@ -409,6 +409,27 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx, gsb_range.x() * gsb_range.y()); } +/******************************************************************** + * Sort all the incoming edges for each channel node which are + * output ports of the GSB + *******************************************************************/ +void sort_device_rr_gsb_chan_node_in_edges(const RRGraph& rr_graph, + DeviceRRGSB& device_rr_gsb) { + vtr::ScopedStartFinishTimer timer("Sort incoming edges for each routing track output node of General Switch Block(GSB)"); + + /* Note that the GSB array is smaller than the grids by 1 column and 1 row!!! */ + vtr::Point gsb_range = device_rr_gsb.get_gsb_range(); + + /* For each switch block, determine the size of array */ + for (size_t ix = 0; ix < gsb_range.x(); ++ix) { + for (size_t iy = 0; iy < gsb_range.y(); ++iy) { + vtr::Point gsb_coordinate(ix, iy); + RRGSB& rr_gsb = device_rr_gsb.get_mutable_gsb(gsb_coordinate); + rr_gsb.sort_chan_node_in_edges(rr_graph); + } + } +} + /******************************************************************** * Build the link between rr_graph switches to their physical circuit models * The binding is done based on the name of rr_switches defined in the diff --git a/openfpga/src/annotation/annotate_rr_graph.h b/openfpga/src/annotation/annotate_rr_graph.h index d4550639f..69346a481 100644 --- a/openfpga/src/annotation/annotate_rr_graph.h +++ b/openfpga/src/annotation/annotate_rr_graph.h @@ -19,6 +19,9 @@ void annotate_device_rr_gsb(const DeviceContext& vpr_device_ctx, DeviceRRGSB& device_rr_gsb, const bool& verbose_output); +void sort_device_rr_gsb_chan_node_in_edges(const RRGraph& rr_graph, + DeviceRRGSB& device_rr_gsb); + void annotate_rr_graph_circuit_models(const DeviceContext& vpr_device_ctx, const Arch& openfpga_arch, VprDeviceAnnotation& vpr_device_annotation, diff --git a/openfpga/src/annotation/device_rr_gsb.cpp b/openfpga/src/annotation/device_rr_gsb.cpp index 6fa808823..1fcb16109 100644 --- a/openfpga/src/annotation/device_rr_gsb.cpp +++ b/openfpga/src/annotation/device_rr_gsb.cpp @@ -28,13 +28,13 @@ vtr::Point DeviceRRGSB::get_gsb_range() const { } /* Get a rr switch block in the array with a coordinate */ -const RRGSB DeviceRRGSB::get_gsb(const vtr::Point& coordinate) const { +const RRGSB& DeviceRRGSB::get_gsb(const vtr::Point& coordinate) const { VTR_ASSERT(validate_coordinate(coordinate)); return rr_gsb_[coordinate.x()][coordinate.y()]; } /* Get a rr switch block in the array with a coordinate */ -const RRGSB DeviceRRGSB::get_gsb(const size_t& x, const size_t& y) const { +const RRGSB& DeviceRRGSB::get_gsb(const size_t& x, const size_t& y) const { vtr::Point coordinate(x, y); return get_gsb(coordinate); } @@ -87,7 +87,7 @@ size_t DeviceRRGSB::get_num_gsb_unique_module() const { } /* Get a rr switch block which a unique mirror */ -const RRGSB DeviceRRGSB::get_sb_unique_module(const size_t& index) const { +const RRGSB& DeviceRRGSB::get_sb_unique_module(const size_t& index) const { VTR_ASSERT (validate_sb_unique_module_index(index)); return rr_gsb_[sb_unique_module_[index].x()][sb_unique_module_[index].y()]; @@ -130,7 +130,7 @@ const RRGSB& DeviceRRGSB::get_cb_unique_module(const t_rr_type& cb_type, const v } /* Give a coordinate of a rr switch block, and return its unique mirror */ -const RRGSB DeviceRRGSB::get_sb_unique_module(const vtr::Point& coordinate) const { +const RRGSB& DeviceRRGSB::get_sb_unique_module(const vtr::Point& coordinate) const { VTR_ASSERT(validate_coordinate(coordinate)); size_t sb_unique_module_id = sb_unique_module_id_[coordinate.x()][coordinate.y()]; return get_sb_unique_module(sb_unique_module_id); @@ -193,6 +193,18 @@ void DeviceRRGSB::add_rr_gsb(const vtr::Point& coordinate, rr_gsb_[coordinate.x()][coordinate.y()] = rr_gsb; } +/* Get a rr switch block in the array with a coordinate */ +RRGSB& DeviceRRGSB::get_mutable_gsb(const vtr::Point& coordinate) { + VTR_ASSERT(validate_coordinate(coordinate)); + return rr_gsb_[coordinate.x()][coordinate.y()]; +} + +/* Get a rr switch block in the array with a coordinate */ +RRGSB& DeviceRRGSB::get_mutable_gsb(const size_t& x, const size_t& y) { + vtr::Point coordinate(x, y); + return get_mutable_gsb(coordinate); +} + /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */ void DeviceRRGSB::build_cb_unique_module(const RRGraph& rr_graph, const t_rr_type& cb_type) { /* Make sure a clean start */ diff --git a/openfpga/src/annotation/device_rr_gsb.h b/openfpga/src/annotation/device_rr_gsb.h index eae0afa1d..4d8aad401 100644 --- a/openfpga/src/annotation/device_rr_gsb.h +++ b/openfpga/src/annotation/device_rr_gsb.h @@ -28,12 +28,12 @@ class DeviceRRGSB { public: /* Contructors */ public: /* Accessors */ vtr::Point get_gsb_range() const; /* get the max coordinate of the switch block array */ - const RRGSB get_gsb(const vtr::Point& coordinate) const; /* Get a rr switch block in the array with a coordinate */ - const RRGSB get_gsb(const size_t& x, const size_t& y) const; /* Get a rr switch block in the array with a coordinate */ + const RRGSB& get_gsb(const vtr::Point& coordinate) const; /* Get a rr switch block in the array with a coordinate */ + const RRGSB& get_gsb(const size_t& x, const size_t& y) const; /* Get a rr switch block in the array with a coordinate */ size_t get_num_gsb_unique_module() const; /* get the number of unique mirrors of GSB */ size_t get_num_sb_unique_module() const; /* get the number of unique mirrors of switch blocks */ - const RRGSB get_sb_unique_module(const size_t& index) const; /* Get a rr switch block which a unique mirror */ - const RRGSB get_sb_unique_module(const vtr::Point& coordinate) const; /* Get a rr switch block which a unique mirror */ + const RRGSB& get_sb_unique_module(const size_t& index) const; /* Get a rr switch block which a unique mirror */ + const RRGSB& get_sb_unique_module(const vtr::Point& coordinate) const; /* Get a rr switch block which a unique mirror */ const RRGSB& get_cb_unique_module(const t_rr_type& cb_type, const size_t& index) const; /* Get a rr switch block which a unique mirror */ const RRGSB& get_cb_unique_module(const t_rr_type& cb_type, const vtr::Point& coordinate) const; size_t get_num_cb_unique_module(const t_rr_type& cb_type) const; /* get the number of unique mirrors of CBs */ @@ -43,6 +43,8 @@ class DeviceRRGSB { void reserve_sb_unique_submodule_id(const vtr::Point& coordinate); /* Pre-allocate the rr_sb_unique_module_id matrix that the device requires */ void resize_upon_need(const vtr::Point& coordinate); /* Resize the rr_switch_block array if needed */ void add_rr_gsb(const vtr::Point& coordinate, const RRGSB& rr_gsb); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */ + RRGSB& get_mutable_gsb(const vtr::Point& coordinate); /* Get a rr switch block in the array with a coordinate */ + RRGSB& get_mutable_gsb(const size_t& x, const size_t& y); /* Get a rr switch block in the array with a coordinate */ void build_unique_module(const RRGraph& rr_graph); /* Add a switch block to the array, which will automatically identify and update the lists of unique mirrors and rotatable mirrors */ void clear(); /* clean the content */ private: /* Internal cleaners */ diff --git a/openfpga/src/base/openfpga_link_arch.cpp b/openfpga/src/base/openfpga_link_arch.cpp index e0e52f878..5c0d6c582 100644 --- a/openfpga/src/base/openfpga_link_arch.cpp +++ b/openfpga/src/base/openfpga_link_arch.cpp @@ -65,6 +65,7 @@ void link_arch(OpenfpgaContext& openfpga_ctx, vtr::ScopedStartFinishTimer timer("Link OpenFPGA architecture to VPR architecture"); CommandOptionId opt_activity_file = cmd.option("activity_file"); + CommandOptionId opt_sort_edge = cmd.option("sort_gsb_chan_node_in_edges"); CommandOptionId opt_verbose = cmd.option("verbose"); /* Annotate pb_type graphs @@ -111,6 +112,11 @@ void link_arch(OpenfpgaContext& openfpga_ctx, openfpga_ctx.mutable_device_rr_gsb(), cmd_context.option_enable(cmd, opt_verbose)); + if (true == cmd_context.option_enable(cmd, opt_sort_edge)) { + sort_device_rr_gsb_chan_node_in_edges(g_vpr_ctx.device().rr_graph, + openfpga_ctx.mutable_device_rr_gsb()); + } + /* Build multiplexer library */ openfpga_ctx.mutable_mux_lib() = build_device_mux_library(g_vpr_ctx.device(), const_cast(openfpga_ctx)); diff --git a/openfpga/src/base/openfpga_setup_command.cpp b/openfpga/src/base/openfpga_setup_command.cpp index 0d7393c26..0bbc8b2a2 100644 --- a/openfpga/src/base/openfpga_setup_command.cpp +++ b/openfpga/src/base/openfpga_setup_command.cpp @@ -78,6 +78,9 @@ ShellCommandId add_openfpga_link_arch_command(openfpga::Shell& CommandOptionId opt_act_file = shell_cmd.add_option("activity_file", true, "file path to the signal activity"); shell_cmd.set_option_require_value(opt_act_file, openfpga::OPT_STRING); + /* Add an option '--sort_gsb_chan_node_in_edges'*/ + shell_cmd.add_option("sort_gsb_chan_node_in_edges", false, "Sort all the incoming edges for each routing track output node in General Switch Blocks (GSBs)"); + /* Add an option '--verbose' */ shell_cmd.add_option("verbose", false, "Show verbose outputs"); diff --git a/openfpga/test_script/and_k6_frac.openfpga b/openfpga/test_script/and_k6_frac.openfpga index 4133dcea5..872af950d 100644 --- a/openfpga/test_script/and_k6_frac.openfpga +++ b/openfpga/test_script/and_k6_frac.openfpga @@ -8,7 +8,7 @@ read_openfpga_arch -f ./test_openfpga_arch/k6_frac_N10_40nm_openfpga.xml #write_openfpga_arch -f ./arch_echo.xml # Annotate the OpenFPGA architecture to VPR data base -link_openfpga_arch --activity_file ./test_blif/and.act #--verbose +link_openfpga_arch --activity_file ./test_blif/and.act --sort_gsb_chan_node_in_edges #--verbose # Check and correct any naming conflicts in the BLIF netlist check_netlist_naming_conflict --fix --report ./netlist_renaming.xml