Skip to content

Commit 1983615

Browse files
authored
Merge pull request #1355 from tangxifan/pb_pin_fixup
Post routing cluster block pin fix-up
2 parents bd0c0e0 + 801848d commit 1983615

21 files changed

+2534
-12
lines changed

doc/src/vpr/file_formats.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,14 @@ The io pad is set to inpad mode and is driven by the inpad:
585585
</block>
586586
...
587587
588+
.. note:: ``.net`` files may be outputted at two stages:
589+
- After packing is completed, the packing results will be outputted. The ``.net`` file can be loaded as an input for placer, router and analyzer. Note that the file may **not** represent the final packing results as the analyzer will apply synchronization between packing and routing results.
590+
- After analysis is completed, updated packing results will be outputted. This is due to that VPR router may swap pin mapping in packing results for optimizations. In such cases, packing results are synchronized with routing results. The outputted ``.net`` file will have a postfix of ``.post_routing`` as compared to the original packing results. It could happen that VPR router does not apply any pin swapping and the two ``.net`` files are the same. In both cases, the post-analysis ``.net`` file should be considered to be **the final packing results** for downstream tools, e.g., bitstream generator. Users may load the post-routing ``.net`` file in VPR's analysis flow to sign-off the final results.
591+
592+
.. warning:: Currently, the packing result synchronization is only applicable to input pins which may be remapped to different nets during routing optimization. If your architecture defines `link_instance_pin_xml_syntax_` equivalence for output pins, the packing results still mismatch the routing results!
593+
594+
.. _link_instance_pin_xml_syntax: https://docs.verilogtorouting.org/en/latest/arch/reference/#tag-%3Coutputname=
595+
588596
.. _vpr_place_file:
589597

590598
Placement File Format (.place)

vpr/src/base/netlist_writer.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,17 @@ class NetlistWriterVisitor : public NetlistVisitor {
18641864
if (impl_input_net_id) {
18651865
//If there is a valid net connected in the implementation
18661866
AtomNetId logical_net_id = atom_ctx.nlist.port_net(port_id, orig_index);
1867-
VTR_ASSERT(impl_input_net_id == logical_net_id);
1867+
1868+
// Fatal error should be flagged when the net marked in implementation
1869+
// does not match the net marked in input netlist
1870+
if (impl_input_net_id != logical_net_id) {
1871+
VPR_FATAL_ERROR(VPR_ERROR_IMPL_NETLIST_WRITER,
1872+
"Unmatch:\n\tlogical net is '%s' at pin '%lu'\n\timplmented net is '%s' at pin '%s'\n",
1873+
atom_ctx.nlist.net_name(logical_net_id).c_str(),
1874+
size_t(orig_index),
1875+
atom_ctx.nlist.net_name(impl_input_net_id).c_str(),
1876+
gpin->to_string().c_str());
1877+
}
18681878

18691879
//Mark the permutation.
18701880
// The net originally located at orig_index in the atom netlist

vpr/src/base/vpr_api.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "constant_nets.h"
6868
#include "atom_netlist_utils.h"
6969
#include "cluster.h"
70+
#include "output_clustering.h"
7071

7172
#include "pack_report.h"
7273
#include "overuse_report.h"
@@ -81,6 +82,8 @@
8182

8283
#include "arch_util.h"
8384

85+
#include "post_routing_pb_pin_fixup.h"
86+
8487
#include "log.h"
8588
#include "iostream"
8689

@@ -587,6 +590,10 @@ void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) {
587590

588591
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
589592

593+
/* Ensure we have a clean start with void net remapping information */
594+
cluster_ctx.post_routing_clb_pin_nets.clear();
595+
cluster_ctx.pre_routing_net_pin_mapping.clear();
596+
590597
cluster_ctx.clb_nlist = read_netlist(vpr_setup.FileNameOpts.NetFile.c_str(),
591598
&arch,
592599
vpr_setup.FileNameOpts.verify_file_digests,
@@ -743,8 +750,6 @@ RouteStatus vpr_route_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
743750
}
744751
}
745752

746-
VTR_LOG("\n");
747-
748753
//Echo files
749754
if (vpr_setup.Timing.timing_analysis_enabled) {
750755
if (isEchoFileEnabled(E_ECHO_FINAL_ROUTING_TIMING_GRAPH)) {
@@ -1183,6 +1188,30 @@ bool vpr_analysis_flow(t_vpr_setup& vpr_setup, const t_arch& Arch, const RouteSt
11831188
VTR_LOG("*****************************************************************************************\n");
11841189
}
11851190

1191+
/* If routing is successful, apply post-routing annotations
1192+
* - apply logic block pin fix-up
1193+
*
1194+
* Note:
1195+
* - Turn on verbose output when users require verbose output
1196+
* for packer (default verbosity is set to 2 for compact logs)
1197+
*/
1198+
if (route_status.success()) {
1199+
sync_netlists_to_routing(g_vpr_ctx.device(),
1200+
g_vpr_ctx.mutable_atom(),
1201+
g_vpr_ctx.mutable_clustering(),
1202+
g_vpr_ctx.placement(),
1203+
g_vpr_ctx.routing(),
1204+
vpr_setup.PackerOpts.pack_verbosity > 2);
1205+
1206+
std::string post_routing_packing_output_file_name = vpr_setup.PackerOpts.output_file + ".post_routing";
1207+
write_packing_results_to_xml(vpr_setup.PackerOpts.global_clocks,
1208+
Arch.architecture_id,
1209+
post_routing_packing_output_file_name.c_str());
1210+
} else {
1211+
VTR_LOG_WARN("Sychronization between packing and routing results is not applied due to illegal circuit implementation\n");
1212+
}
1213+
VTR_LOG("\n");
1214+
11861215
vpr_analysis(vpr_setup, Arch, route_status);
11871216

11881217
return true;

vpr/src/base/vpr_context.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,16 @@ struct ClusteringContext : public Context {
268268

269269
///@brief New netlist class derived from Netlist
270270
ClusteredNetlist clb_nlist;
271+
272+
/* Database for nets of each clb block pin after routing stage
273+
* - post_routing_clb_pin_nets:
274+
* mapping of pb_type pins to clustered net ids
275+
* - pre_routing_net_pin_mapping:
276+
* a copy of mapping for current pb_route index to previous pb_route index
277+
* Record the previous pin mapping for finding the correct pin index during timing analysis
278+
*/
279+
std::map<ClusterBlockId, std::map<int, ClusterNetId>> post_routing_clb_pin_nets;
280+
std::map<ClusterBlockId, std::map<int, int>> pre_routing_net_pin_mapping;
271281
};
272282

273283
/**

vpr/src/base/vpr_types.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ t_mode* t_pb::get_mode() const {
7070
}
7171

7272
/**
73-
* @brief Returns the t_pb associated with the specified gnode which is contained
73+
* @brief Returns the read-only t_pb associated with the specified gnode which is contained
7474
* within the current pb
7575
*/
7676
const t_pb* t_pb::find_pb(const t_pb_graph_node* gnode) const {
@@ -96,6 +96,33 @@ const t_pb* t_pb::find_pb(const t_pb_graph_node* gnode) const {
9696
return nullptr; //Not found
9797
}
9898

99+
/**
100+
* @brief Returns the mutable t_pb associated with the specified gnode which is contained
101+
* within the current pb
102+
*/
103+
t_pb* t_pb::find_mutable_pb(const t_pb_graph_node* gnode) {
104+
//Base case
105+
if (pb_graph_node == gnode) {
106+
return this;
107+
}
108+
109+
//Search recursively
110+
for (int ichild_type = 0; ichild_type < get_num_child_types(); ++ichild_type) {
111+
if (child_pbs[ichild_type] == nullptr) continue;
112+
113+
for (int ipb = 0; ipb < get_num_children_of_type(ichild_type); ++ipb) {
114+
t_pb* child_pb = &child_pbs[ichild_type][ipb];
115+
116+
t_pb* found_pb = child_pb->find_mutable_pb(gnode);
117+
if (found_pb != nullptr) {
118+
VTR_ASSERT(found_pb->pb_graph_node == gnode);
119+
return found_pb; //Found
120+
}
121+
}
122+
}
123+
return nullptr; //Not found
124+
}
125+
99126
const t_pb* t_pb::find_pb_for_model(const std::string& blif_model) const {
100127
//Base case
101128
const t_model* model = pb_graph_node->pb_type->model;

vpr/src/base/vpr_types.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,17 @@ class t_pb {
325325
t_mode* get_mode() const;
326326

327327
/**
328-
* @brief Returns the t_pb associated with the specified gnode which is contained
328+
* @brief Returns the read-only t_pb associated with the specified gnode which is contained
329329
* within the current pb
330330
*/
331331
const t_pb* find_pb(const t_pb_graph_node* gnode) const;
332332

333+
/**
334+
* @brief Returns the mutable t_pb associated with the specified gnode which is contained
335+
* within the current pb
336+
*/
337+
t_pb* find_mutable_pb(const t_pb_graph_node* gnode);
338+
333339
const t_pb* find_pb_for_model(const std::string& blif_model) const;
334340

335341
///@brief Returns the root pb containing this pb

vpr/src/pack/output_clustering.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "output_clustering.h"
2727
#include "read_xml_arch_file.h"
2828
#include "vpr_utils.h"
29+
#include "pack.h"
2930

3031
#define LINELENGTH 1024
3132
#define TAB_LENGTH 4
@@ -615,3 +616,26 @@ void output_clustering(const vtr::vector<ClusterBlockId, std::vector<t_intra_lb_
615616
}
616617
}
617618
}
619+
620+
/********************************************************************
621+
* An useful API to output packing results to a XML file
622+
* This function is a wrapper for the function output_clustering()
623+
* but remove all the requirements on input data structures that
624+
* have to be built with other APIs
625+
*
626+
* As such, this function is expected to be a standard API
627+
* which can be called anytime and anywhere after packing is finished.
628+
********************************************************************/
629+
void write_packing_results_to_xml(const bool& global_clocks,
630+
const std::string& architecture_id,
631+
const char* out_fname) {
632+
vtr::vector<ClusterBlockId, std::vector<t_intra_lb_net>*> intra_lb_routing_placeholder;
633+
std::unordered_set<AtomNetId> is_clock = alloc_and_load_is_clock(global_clocks);
634+
635+
output_clustering(intra_lb_routing_placeholder,
636+
global_clocks,
637+
is_clock,
638+
architecture_id,
639+
out_fname,
640+
false);
641+
}

vpr/src/pack/output_clustering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@
77

88
void output_clustering(const vtr::vector<ClusterBlockId, std::vector<t_intra_lb_net>*>& intra_lb_routing, bool global_clocks, const std::unordered_set<AtomNetId>& is_clock, const std::string& architecture_id, const char* out_fname, bool skip_clustering);
99

10+
void write_packing_results_to_xml(const bool& global_clocks, const std::string& architecture_id, const char* out_fname);
11+
1012
#endif

vpr/src/pack/pack.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
/* #define DUMP_PB_GRAPH 1 */
2727
/* #define DUMP_BLIF_INPUT 1 */
2828

29-
static std::unordered_set<AtomNetId> alloc_and_load_is_clock(bool global_clocks);
3029
static bool try_size_device_grid(const t_arch& arch, const std::map<t_logical_block_type_ptr, size_t>& num_type_instances, float target_device_utilization, std::string device_layout_name);
3130

3231
static t_ext_pin_util_targets parse_target_external_pin_util(std::vector<std::string> specs);

vpr/src/pack/pack.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#ifndef PACK_H
22
#define PACK_H
33
#include <vector>
4+
#include <unordered_set>
45
#include "vpr_types.h"
6+
#include "atom_netlist_fwd.h"
57

68
bool try_pack(t_packer_opts* packer_opts,
79
const t_analysis_opts* analysis_opts,
@@ -13,4 +15,6 @@ bool try_pack(t_packer_opts* packer_opts,
1315

1416
float get_arch_switch_info(short switch_index, int switch_fanin, float& Tdel_switch, float& R_switch, float& Cout_switch);
1517

18+
std::unordered_set<AtomNetId> alloc_and_load_is_clock(bool global_clocks);
19+
1620
#endif

0 commit comments

Comments
 (0)