Skip to content

Commit 20a8ab1

Browse files
Merge branch 'master' into swap_evaluator
2 parents 9860308 + f9d73eb commit 20a8ab1

44 files changed

Lines changed: 1314 additions & 1481 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/src/arch/reference.rst

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1724,13 +1724,24 @@ A pack pattern is a power user feature directing that the CAD tool should group
17241724
This allows the architect to help the CAD tool recognize structures that have limited flexibility so that netlist atoms that fit those structures be kept together as though they are one unit.
17251725
This tag impacts the CAD tool only, there is no architectural impact from defining molecules.
17261726

1727-
.. arch:tag:: <pack_pattern name="string" in_port="string" out_port="string"/>
1727+
.. arch:tag:: <pack_pattern name="string" in_port="string" out_port="string" allow_multi_fanout="bool"/>
17281728
17291729
.. warning:: This is a power user option. Unless you know why you need it, you probably shouldn't specify it.
17301730

17311731
:req_param name: The name of the pattern.
17321732
:req_param in_port: The input pins of the edges for this pattern.
17331733
:req_param out_port: Which output pins of the edges for this pattern.
1734+
:opt_param allow_multi_fanout:
1735+
1736+
Controls whether a molecule can still be formed over this pattern connection when the netlist signal carrying it also drives other logic.
1737+
1738+
By default (``false``), the packer only matches this connection if the net driving it has exactly one sink, i.e. the signal goes straight from the source primitive to the destination primitive and nowhere else.
1739+
If the net fans out to additional sinks, the molecule is cut at this connection.
1740+
1741+
When set to ``true``, the packer will match this connection even if the net drives multiple sinks: the sink that fits the pattern becomes part of the molecule, and the remaining sinks are routed normally outside of it.
1742+
Only set this on connections where the architecture actually provides a path for that extra fanout to leave the pattern (see *Multi-fanout connections* below).
1743+
1744+
**Default:** ``false``
17341745

17351746
This tag gives a hint to the CAD tool that certain architectural structures should stay together during packing.
17361747
The tag labels interconnect edges with a pack pattern name.
@@ -1744,6 +1755,31 @@ This tag impacts the CAD tool only, there is no architectural impact from defini
17441755
Pack patterns with more primitives take priority over pack patterns with less primitives.
17451756
In the event that the number of primitives is the same, the pack pattern with less inputs takes priority over pack patterns with more inputs.
17461757

1758+
**Multi-fanout connections:**
1759+
1760+
By default, the prepacker assumes each pack pattern connection is point-to-point: if the netlist net implementing a connection fans out to more than one sink, no molecule is formed over that connection.
1761+
This is a conservative assumption — a net with extra fanout may not be routable through the dedicated intra-block interconnect the pattern describes, since the other sinks also need to be reached.
1762+
1763+
If the architecture can absorb the extra fanout (e.g., the block provides paths from the pattern connection to general routing), the architect can mark the ``<pack_pattern>`` annotation with ``allow_multi_fanout="true"``.
1764+
The prepacker will then form molecules over this connection even when its net drives multiple sinks; among the sinks, the one matching the pattern's destination primitive continues the molecule, and the remaining sinks are left to be routed outside the pattern.
1765+
1766+
Note that the attribute is written on individual interconnect edges, but its effect is defined at the level of a *primitive-to-primitive connection*.
1767+
Such a connection may pass through several interconnect edges when the two primitives are not directly wired together (e.g., the signal traverses intermediate modes or levels of the pb_type hierarchy).
1768+
The architect does not need to annotate every edge along that path: if any annotated edge on the connection's path is marked ``allow_multi_fanout="true"``, the entire primitive-to-primitive connection allows multi-fanout.
1769+
1770+
.. note::
1771+
1772+
If several sinks match the pattern's destination primitive, only one joins the molecule.
1773+
For example, with a ``LUT -> FF`` pack pattern and a LUT driving two FFs, the prepacker picks the last matching FF added to the netlist to form the molecule; the other FF is packed as a separate atom.
1774+
1775+
For example, in a carry chain where each adder's ``cout`` may also feed look-ahead logic in addition to the next adder's ``cin``, marking the chain's ``cout`` link keeps chain molecules together despite the extra fanout:
1776+
1777+
.. code-block:: xml
1778+
1779+
<direct name="carry_out" input="adder.cout" output="arithmetic.cout">
1780+
<pack_pattern name="chain" in_port="adder.cout" out_port="arithmetic.cout" allow_multi_fanout="true"/>
1781+
</direct>
1782+
17471783
**Special Case:**
17481784

17491785
To specify carry chains, we use a special case of a pack pattern.

doc/src/vpr/custom_rr_graph_generator.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,6 @@ following arguments in the VPR command line:
179179

180180
- ``--sb_maps <switch_block_map_file>``
181181
- ``--sb_templates <switch_block_template_directory>``
182-
- ``--sb_count_dir <switch_block_count_directory>`` (optional):
183-
If provided, VPR generates a CSV file for each switch block template,
184-
showing how many times each switch specified in the template is used in the
185-
final routing results.
186182

187183
For additional arguments, refer to the command-line usage section in
188184
:ref:`vpr_command_line_usage`.

libs/libarchfpga/src/device_grid.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <utility>
55
#include <vector>
66
#include "physical_types.h"
7+
#include "vtr_assert.h"
78
#include "vtr_expr_eval.h"
89
#include "vtr_ndmatrix.h"
910
#include "grid_util.h"
@@ -162,6 +163,40 @@ bool DeviceGrid::are_locs_on_same_die(t_physical_tile_loc loc_a, t_physical_tile
162163
return first_id == second_id;
163164
}
164165

166+
bool DeviceGrid::do_locs_cross_vertical_cut(t_physical_tile_loc loc_a, t_physical_tile_loc loc_b) const {
167+
VTR_ASSERT_SAFE_MSG(loc_a.layer_num == loc_b.layer_num,
168+
"This method currently always returns true if loc_a and "
169+
"loc_b are on different layers. This method takes shortcuts "
170+
"to quickly find cuts on 2D devices; it needs to be updated "
171+
"to also handle 3D devices.");
172+
173+
// Dice are guaranteed to be axis-aligned rectangles, so checking the die at loc_a's row
174+
// is sufficient to tell whether a vertical cut separates the two locations' x coordinates;
175+
// this is well-defined even when loc_a.y != loc_b.y.
176+
int y = loc_a.y;
177+
const DeviceDieId first_id = die_id_matrix_[loc_a.layer_num][loc_a.x][y];
178+
const DeviceDieId second_id = die_id_matrix_[loc_b.layer_num][loc_b.x][y];
179+
180+
return first_id != second_id;
181+
}
182+
183+
bool DeviceGrid::do_locs_cross_horizontal_cut(t_physical_tile_loc loc_a, t_physical_tile_loc loc_b) const {
184+
VTR_ASSERT_SAFE_MSG(loc_a.layer_num == loc_b.layer_num,
185+
"This method currently always returns true if loc_a and "
186+
"loc_b are on different layers. This method takes shortcuts "
187+
"to quickly find cuts on 2D devices; it needs to be updated "
188+
"to also handle 3D devices.");
189+
190+
// Dice are guaranteed to be axis-aligned rectangles, so checking the die at loc_a's column
191+
// is sufficient to tell whether a horizontal cut separates the two locations' y coordinates;
192+
// this is well-defined even when loc_a.x != loc_b.x.
193+
int x = loc_a.x;
194+
const DeviceDieId first_id = die_id_matrix_[loc_a.layer_num][x][loc_a.y];
195+
const DeviceDieId second_id = die_id_matrix_[loc_b.layer_num][x][loc_b.y];
196+
197+
return first_id != second_id;
198+
}
199+
165200
DeviceDieId DeviceGrid::get_loc_die_id(t_physical_tile_loc loc) const {
166201
return die_id_matrix_[loc.layer_num][loc.x][loc.y];
167202
}

libs/libarchfpga/src/device_grid.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,16 @@ class DeviceGrid {
325325
*/
326326
bool are_locs_on_same_die(t_physical_tile_loc loc_a, t_physical_tile_loc loc_b) const;
327327

328+
/**
329+
* @brief Returns true if the straight line between loc_a and loc_b crosses a vertical interposer cut.
330+
*/
331+
bool do_locs_cross_vertical_cut(t_physical_tile_loc loc_a, t_physical_tile_loc loc_b) const;
332+
333+
/**
334+
* @brief Returns true if the straight line between loc_a and loc_b crosses a horizontal interposer cut.
335+
*/
336+
bool do_locs_cross_horizontal_cut(t_physical_tile_loc loc_a, t_physical_tile_loc loc_b) const;
337+
328338
/**
329339
* @brief Get the die identifier of a location. In 2.5D and 3D architectures each die has its own unique identifier.
330340
*

libs/libarchfpga/src/physical_types.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,12 +1088,17 @@ struct t_pin_to_pin_annotation {
10881088
std::string output_pins;
10891089
std::string clock;
10901090

1091+
/* pack_pattern annotations only: nets on this pattern connection may drive
1092+
* multiple sinks, so the prepacker's single-fanout assumptions are lifted for it */
1093+
bool pack_pattern_allow_multi_fanout;
1094+
10911095
int line_num; /* used to report what line number this annotation is found in architecture file */
10921096

10931097
t_pin_to_pin_annotation() noexcept {
10941098
line_num = 0;
10951099
type = (e_pin_to_pin_annotation_type)0;
10961100
format = (e_pin_to_pin_annotation_format)0;
1101+
pack_pattern_allow_multi_fanout = false;
10971102
}
10981103
};
10991104

@@ -1490,6 +1495,9 @@ class t_pb_graph_edge {
14901495
int num_pack_patterns;
14911496
std::vector<const char*> pack_pattern_names;
14921497
int* pack_pattern_indices;
1498+
/* [0..num_pack_patterns-1] parallel to pack_pattern_names: true if the
1499+
* pattern annotation on this edge is marked allow_multi_fanout */
1500+
std::vector<bool> pack_pattern_allow_multi_fanout;
14931501
bool infer_pattern;
14941502

14951503
int switch_type_idx = ARCH_FPGA_UNDEFINED_VAL; /* architecture switch id of the edge - used when flat_routing is enabled */
@@ -1797,12 +1805,6 @@ struct t_arch_switch_inf {
17971805
e_power_buffer_type power_buffer_type = POWER_BUFFER_TYPE_AUTO;
17981806
float power_buffer_size = 0.;
17991807

1800-
// The template ID of the switch. This is metadata stored for each switch to
1801-
// simplify certain analyses. For example, when generating the CRR graph, the
1802-
// template ID is used to determine which switch in the template is used most
1803-
// or least frequently.
1804-
std::string template_id = "";
1805-
18061808
bool intra_tile = false;
18071809

18081810
public:

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,8 @@ static void process_pin_to_pin_annotations(pugi::xml_node Parent,
11651165
prop = get_attribute(Parent, "out_port", loc_data).value();
11661166
annotation->output_pins = prop;
11671167

1168+
annotation->pack_pattern_allow_multi_fanout = get_attribute(Parent, "allow_multi_fanout", loc_data, ReqOpt::OPTIONAL).as_bool(false);
1169+
11681170
} else {
11691171
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
11701172
vtr::string_fmt("Unknown port type %s in %s in %s",

libs/librrgraph/src/base/rr_switch.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ struct t_rr_switch_inf {
3131
e_power_buffer_type power_buffer_type = POWER_BUFFER_TYPE_UNDEFINED;
3232
float power_buffer_size = 0.;
3333

34-
// The template ID of the switch. This is metadata stored for each switch to
35-
// simplify certain analyses. For example, when generating the CRR graph, the
36-
// template ID is used to determine which switch in the template is used most
37-
// or least frequently.
38-
std::string template_id = "";
39-
4034
/// Indicate whether this rr_switch is a switch type used inside clusters.
4135
/// These switch types are not specified in the architecture description file
4236
/// and are added when flat router is enabled.

libs/librrgraph/src/io/gen/rr_graph_uxsdcxx.h

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* https://github.com/duck2/uxsdcxx
55
* Modify only if your build process doesn't involve regenerating this file.
66
*
7-
* Cmdline: uxsdcxx/uxsdcxx.py C:/Users/OscarPC/source/repos/OpenFPGA/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
8-
* Input file: C:\Users\OscarPC\source\repos\OpenFPGA\vtr-verilog-to-routing\libs\librrgraph\src\io\rr_graph.xsd
9-
* md5sum of input file: f991ca82094c66d88dc58873b07cadda
7+
* Cmdline: uxsdcxx/uxsdcxx.py /home/amohaghegh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
8+
* Input file: /home/amohaghegh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
9+
* md5sum of input file: 4b2ef78f43cba03933974d33ee053c65
1010
*/
1111

1212
#include <functional>
@@ -245,8 +245,8 @@ constexpr const char *atok_lookup_t_sizing[] = {"buf_size", "mux_trans_size"};
245245

246246
enum class gtok_t_switch {TIMING, SIZING};
247247
constexpr const char *gtok_lookup_t_switch[] = {"timing", "sizing"};
248-
enum class atok_t_switch {ID, NAME, TEMPLATE_ID, TYPE};
249-
constexpr const char *atok_lookup_t_switch[] = {"id", "name", "template_id", "type"};
248+
enum class atok_t_switch {ID, NAME, TYPE};
249+
constexpr const char *atok_lookup_t_switch[] = {"id", "name", "type"};
250250

251251
enum class gtok_t_switches {SWITCH};
252252
constexpr const char *gtok_lookup_t_switches[] = {"switch"};
@@ -672,29 +672,6 @@ inline atok_t_switch lex_attr_t_switch(const char *in, const std::function<void(
672672
default: break;
673673
}
674674
break;
675-
case 11:
676-
switch(*((triehash_uu64*)&in[0])){
677-
case onechar('t', 0, 64) | onechar('e', 8, 64) | onechar('m', 16, 64) | onechar('p', 24, 64) | onechar('l', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64):
678-
switch(in[8]){
679-
case onechar('_', 0, 8):
680-
switch(in[9]){
681-
case onechar('i', 0, 8):
682-
switch(in[10]){
683-
case onechar('d', 0, 8):
684-
return atok_t_switch::TEMPLATE_ID;
685-
break;
686-
default: break;
687-
}
688-
break;
689-
default: break;
690-
}
691-
break;
692-
default: break;
693-
}
694-
break;
695-
default: break;
696-
}
697-
break;
698675
default: break;
699676
}
700677
noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of <switch>.").c_str());
@@ -2427,7 +2404,7 @@ inline void load_sizing_required_attributes(const pugi::xml_node &root, float *
24272404
}
24282405

24292406
inline void load_switch_required_attributes(const pugi::xml_node &root, int * id, const std::function<void(const char *)> * report_error){
2430-
std::bitset<4> astate = 0;
2407+
std::bitset<3> astate = 0;
24312408
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
24322409
atok_t_switch in = lex_attr_t_switch(attr.name(), report_error);
24332410
if(astate[(int)in] == 0) astate[(int)in] = 1;
@@ -2439,16 +2416,13 @@ inline void load_switch_required_attributes(const pugi::xml_node &root, int * id
24392416
case atok_t_switch::NAME:
24402417
/* Attribute name set after element init */
24412418
break;
2442-
case atok_t_switch::TEMPLATE_ID:
2443-
/* Attribute template_id set after element init */
2444-
break;
24452419
case atok_t_switch::TYPE:
24462420
/* Attribute type set after element init */
24472421
break;
24482422
default: break; /* Not possible. */
24492423
}
24502424
}
2451-
std::bitset<4> test_astate = astate | std::bitset<4>(0b1100);
2425+
std::bitset<3> test_astate = astate | std::bitset<3>(0b100);
24522426
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_switch, report_error);
24532427
}
24542428

@@ -2919,9 +2893,6 @@ inline void load_switch(const pugi::xml_node &root, T &out, Context &context, co
29192893
case atok_t_switch::NAME:
29202894
out.set_switch_name(attr.value(), context);
29212895
break;
2922-
case atok_t_switch::TEMPLATE_ID:
2923-
out.set_switch_template_id(attr.value(), context);
2924-
break;
29252896
case atok_t_switch::TYPE:
29262897
out.set_switch_type(lex_enum_switch_type(attr.value(), true, report_error), context);
29272898
break;
@@ -4107,8 +4078,6 @@ inline void write_switches(T &in, std::ostream &os, Context &context){
41074078
os << "<switch";
41084079
os << " id=\"" << in.get_switch_id(child_context) << "\"";
41094080
os << " name=\"" << in.get_switch_name(child_context) << "\"";
4110-
if((bool)in.get_switch_template_id(child_context))
4111-
os << " template_id=\"" << in.get_switch_template_id(child_context) << "\"";
41124081
if((bool)in.get_switch_type(child_context))
41134082
os << " type=\"" << lookup_switch_type[(int)in.get_switch_type(child_context)] << "\"";
41144083
os << ">";

libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_capnp.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* https://github.com/duck2/uxsdcxx
55
* Modify only if your build process doesn't involve regenerating this file.
66
*
7-
* Cmdline: uxsdcxx/uxsdcap.py C:/Users/OscarPC/source/repos/OpenFPGA/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
8-
* Input file: C:\Users\OscarPC\source\repos\OpenFPGA\vtr-verilog-to-routing\libs\librrgraph\src\io\rr_graph.xsd
9-
* md5sum of input file: f991ca82094c66d88dc58873b07cadda
7+
* Cmdline: uxsdcxx/uxsdcap.py /home/amohaghegh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
8+
* Input file: /home/amohaghegh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
9+
* md5sum of input file: 4b2ef78f43cba03933974d33ee053c65
1010
*/
1111

1212
#include <functional>
@@ -554,7 +554,6 @@ inline void load_switch_capnp_type(const ucap::Switch::Reader &root, T &out, Con
554554
(void)stack;
555555

556556
out.set_switch_name(root.getName().cStr(), context);
557-
out.set_switch_template_id(root.getTemplateId().cStr(), context);
558557
out.set_switch_type(conv_enum_switch_type(root.getType(), report_error), context);
559558
stack->push_back(std::make_pair("getTiming", 0));
560559
if (root.hasTiming()) {
@@ -1087,8 +1086,6 @@ inline void write_switches_capnp_type(T &in, ucap::Switches::Builder &root, Cont
10871086
auto child_context = in.get_switches_switch(i, context);
10881087
switches_switch.setId(in.get_switch_id(child_context));
10891088
switches_switch.setName(in.get_switch_name(child_context));
1090-
if((bool)in.get_switch_template_id(child_context))
1091-
switches_switch.setTemplateId(in.get_switch_template_id(child_context));
10921089
if((bool)in.get_switch_type(child_context))
10931090
switches_switch.setType(conv_to_enum_switch_type(in.get_switch_type(child_context)));
10941091
write_switch_capnp_type(in, switches_switch, child_context);

libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_interface.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
* https://github.com/duck2/uxsdcxx
55
* Modify only if your build process doesn't involve regenerating this file.
66
*
7-
* Cmdline: uxsdcxx/uxsdcxx.py C:/Users/OscarPC/source/repos/OpenFPGA/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
8-
* Input file: C:\Users\OscarPC\source\repos\OpenFPGA\vtr-verilog-to-routing\libs\librrgraph\src\io\rr_graph.xsd
9-
* md5sum of input file: f991ca82094c66d88dc58873b07cadda
7+
* Cmdline: uxsdcxx/uxsdcxx.py /home/amohaghegh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
8+
* Input file: /home/amohaghegh/vtr-verilog-to-routing/libs/librrgraph/src/io/rr_graph.xsd
9+
* md5sum of input file: 4b2ef78f43cba03933974d33ee053c65
1010
*/
1111

1212
#include <functional>
@@ -200,14 +200,11 @@ class RrGraphBase {
200200
* <xs:attribute name="name" type="xs:string" use="required" />
201201
*
202202
* <xs:attribute name="type" type="switch_type" />
203-
* <xs:attribute name="template_id" type="xs:string" />
204203
* </xs:complexType>
205204
*/
206205
virtual inline int get_switch_id(typename ContextTypes::SwitchReadContext &ctx) = 0;
207206
virtual inline const char * get_switch_name(typename ContextTypes::SwitchReadContext &ctx) = 0;
208207
virtual inline void set_switch_name(const char * name, typename ContextTypes::SwitchWriteContext &ctx) = 0;
209-
virtual inline const char * get_switch_template_id(typename ContextTypes::SwitchReadContext &ctx) = 0;
210-
virtual inline void set_switch_template_id(const char * template_id, typename ContextTypes::SwitchWriteContext &ctx) = 0;
211208
virtual inline enum_switch_type get_switch_type(typename ContextTypes::SwitchReadContext &ctx) = 0;
212209
virtual inline void set_switch_type(enum_switch_type type, typename ContextTypes::SwitchWriteContext &ctx) = 0;
213210
virtual inline typename ContextTypes::TimingWriteContext init_switch_timing(typename ContextTypes::SwitchWriteContext &ctx) = 0;

0 commit comments

Comments
 (0)