Skip to content

Commit dd861ea

Browse files
litghostkmurray
authored andcommitted
Add metadata support to architecture and rr_graph XML. (#473)
* Add metadata support to architecture and rr_graph XML. The metadata is unused by the core VPR algorithms, but can be attached at useful points throughout the architecture and rr_graph XML to enable bitstream export. Signed-off-by: Keith Rothman <[email protected]>
1 parent e418cf4 commit dd861ea

25 files changed

+944
-119
lines changed

doc/src/arch/reference.rst

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ The following tags are common to all <pb_type> tags:
905905
Input logical equivalence means that the pin order can be swapped without changing functionality.
906906
For example, an AND gate has logically equivalent inputs because you can swap the order of the inputs and it’s still correct; an adder, on the otherhand, is not logically equivalent because if you swap the MSB with the LSB, the results are completely wrong.
907907
LUTs are also considered logically equivalent since the logic function (LUT mask) can be rotated to account for pin swapping.
908-
908+
909909
* ``none``: No input pins are logically equivalent.
910910
911911
Input pins can not be swapped by the router. (Generates a unique SINK rr-node for each block input port pin.)
@@ -945,12 +945,12 @@ The following tags are common to all <pb_type> tags:
945945
946946
* ``full``: All output pins are considered logically equivalent.
947947
948-
All output pins can be swapped without limitation by the router. For example, this option would be appropriate to model an output port which has a full crossbar between it and the logic within the block that drives it. (Generates a single SRC rr-node shared by each output port pin.)
948+
All output pins can be swapped without limitation by the router. For example, this option would be appropriate to model an output port which has a full crossbar between it and the logic within the block that drives it. (Generates a single SRC rr-node shared by each output port pin.)
949949
950950
* ``instance``: Models that sub-instances within a block (e.g. LUTs/BLEs) can be swapped to achieve a limited form of output pin logical equivalence.
951-
952-
Like ``full``, this generates a single SRC rr-node shared by each output port pin. However, each net originating from this source can use only one output pin from the equivalence group. This can be useful in modeling more complex forms of equivalence in which you can swap which BLE implements which function to gain access to different inputs.
953-
951+
952+
Like ``full``, this generates a single SRC rr-node shared by each output port pin. However, each net originating from this source can use only one output pin from the equivalence group. This can be useful in modeling more complex forms of equivalence in which you can swap which BLE implements which function to gain access to different inputs.
953+
954954
.. warning:: When using ``instance`` equivalence you must be careful to ensure output swapping would not make the cluster internal routing (previously computed by the clusterer) illegal; the tool does not update the cluster internal routing due to output pin swapping.
955955
956956
**Default:** ``none``
@@ -1051,7 +1051,7 @@ They describe how a complex block interfaces with the inter-block world.
10511051
<fc in_type="frac" in_val="0.1" out_type="abs" out_val="25">
10521052
10531053
The above specifies that each:
1054-
1054+
10551055
* input pin connects to 20 L4 tracks (10% of the 200 L4s) and 5 L16 tracks (10% of the 50 L16s), and
10561056
10571057
* output pin connects to 25 L4 tracks and 25 L16 tracks.
@@ -1921,7 +1921,7 @@ The full format is documented below.
19211921
:width: 100%
19221922

19231923
Examples:
1924-
1924+
19251925
* ``min(from,to)`` -- Creates number of switchblock edges equal to the minimum of the 'from' and 'to' set sizes.
19261926

19271927
This ensures *no* element of the 'from' or 'to' sets is connected to multiple elements in the opposing set.
@@ -2036,3 +2036,51 @@ The full format is documented below.
20362036
This specifies that the 'from' set is the union of L4 switchpoints 0, 1, 2 and 3; and L16 switchpoints 0, 4, 8 and 12.
20372037
The 'to' set is all L4 switchpoint 0's.
20382038
Note that since different switchpoints are selected from different segment types it is not possible to specify this without using ``<from>`` sub-tags.
2039+
2040+
.. _arch_metadata:
2041+
2042+
Architecture metadata
2043+
---------------------
2044+
2045+
Architecture metadata enables tagging of architecture or routing graph
2046+
information that exists outside of the normal VPR flow (e.g. pack, place,
2047+
route, etc). For example this could be used to enable bitstream generation by
2048+
tagging routing edges and pb_type features.
2049+
2050+
The metadata will not be used by the vpr executable, but can be leveraged by
2051+
new tools using the libvpr library. These new tools can access the metadata
2052+
on the various VPR internal data structures.
2053+
2054+
To enable tagging of architecture structures with metadata, the ``<metadata>``
2055+
tag can be inserted under the following XML tags:
2056+
2057+
* ``<pb_type>``
2058+
* Any tag under ``<interconnect>`` (``<direct>``, ``<mux>``, etc).
2059+
* ``<mode>``
2060+
* Any grid location type (``<perimeter>``, ``<fill>``, ``<corners>``, ``<single>``, ``<col>``, ``<row>``, ``<region>``)
2061+
2062+
.. arch:tag:: <metadata>
2063+
2064+
Specifies the root of a metadata block. Can have 0 or more ``<meta>`` Children.
2065+
2066+
.. arch:tag:: <meta name="string" >
2067+
2068+
:req_param name: Key name of this metadata value.
2069+
2070+
Specifies a value within a metadata block. The name is a key
2071+
for looking up the value contained within the ``<meta>`` tag. Keys can be
2072+
repeated, and will be stored in a vector in order of occurrence.
2073+
2074+
The value of the ``<meta>`` is the text in the block. Both the ``name`` and
2075+
``<meta>`` value will be stored as a string. XML children are not supported
2076+
in the ``<meta>`` tag.
2077+
2078+
Example of a metadata block with 2 keys:
2079+
2080+
.. code-block:: xml
2081+
2082+
<metadata>
2083+
<meta name="some_key">Some value</meta>
2084+
<meta name="other key!">Other value!</meta>
2085+
</metadata>
2086+

doc/src/vpr/file_formats.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,12 @@ The final subtag is the ``rr_edges`` tag that encloses information about all the
795795
:req_param switch_id:
796796
The type of switch that connects the two nodes.
797797

798+
Node and Edge Metadata
799+
^^^^^^^^^^^^^^^^^^^^^^
800+
801+
``metadata`` blocks (see :ref:`arch_metadata`) are supported under both ``node`` and ``edge`` tags.
802+
803+
798804
Routing Resource Graph Format Example
799805
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
800806

libs/libarchfpga/src/arch_util.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -420,12 +420,12 @@ static void free_pb_type(t_pb_type *pb_type) {
420420
vtr::free(pb_type->modes[i].interconnect[j].interconnect_power);
421421
}
422422
if (pb_type->modes[i].interconnect)
423-
vtr::free(pb_type->modes[i].interconnect);
423+
delete [] pb_type->modes[i].interconnect;
424424
if (pb_type->modes[i].mode_power)
425425
vtr::free(pb_type->modes[i].mode_power);
426426
}
427427
if (pb_type->modes)
428-
vtr::free(pb_type->modes);
428+
delete [] pb_type->modes;
429429

430430
for (int i = 0; i < pb_type->num_annotations; ++i) {
431431
for (int j = 0; j < pb_type->annotations[i].num_value_prop_pairs; ++j) {
@@ -641,8 +641,7 @@ void ProcessLutClass(t_pb_type *lut_pb_type) {
641641

642642
lut_pb_type->num_modes = 2;
643643
lut_pb_type->pb_type_power->leakage_default_mode = 1;
644-
lut_pb_type->modes = (t_mode*) vtr::calloc(lut_pb_type->num_modes,
645-
sizeof(t_mode));
644+
lut_pb_type->modes = new t_mode[lut_pb_type->num_modes];
646645

647646
/* First mode, route_through */
648647
lut_pb_type->modes[0].name = vtr::strdup("wire");
@@ -666,8 +665,7 @@ void ProcessLutClass(t_pb_type *lut_pb_type) {
666665
in_port = &lut_pb_type->ports[1];
667666
}
668667
lut_pb_type->modes[0].num_interconnect = 1;
669-
lut_pb_type->modes[0].interconnect = (t_interconnect*) vtr::calloc(1,
670-
sizeof(t_interconnect));
668+
lut_pb_type->modes[0].interconnect = new t_interconnect[1];
671669
lut_pb_type->modes[0].interconnect[0].name = (char*) vtr::calloc(
672670
strlen(lut_pb_type->name) + 10, sizeof(char));
673671
sprintf(lut_pb_type->modes[0].interconnect[0].name, "complete:%s",
@@ -767,8 +765,7 @@ void ProcessLutClass(t_pb_type *lut_pb_type) {
767765

768766
/* Process interconnect */
769767
lut_pb_type->modes[1].num_interconnect = 2;
770-
lut_pb_type->modes[1].interconnect = (t_interconnect*) vtr::calloc(2,
771-
sizeof(t_interconnect));
768+
lut_pb_type->modes[1].interconnect = new t_interconnect[lut_pb_type->modes[1].num_interconnect];
772769
lut_pb_type->modes[1].interconnect[0].name = (char*) vtr::calloc(
773770
strlen(lut_pb_type->name) + 10, sizeof(char));
774771
sprintf(lut_pb_type->modes[1].interconnect[0].name, "direct:%s",
@@ -831,7 +828,7 @@ void ProcessMemoryClass(t_pb_type *mem_pb_type) {
831828
default_name = vtr::strdup("memory_slice_1bit");
832829
}
833830

834-
mem_pb_type->modes = (t_mode*) vtr::calloc(1, sizeof(t_mode));
831+
mem_pb_type->modes = new t_mode[1];
835832
mem_pb_type->modes[0].name = vtr::strdup(default_name);
836833
mem_pb_type->modes[0].parent_pb_type = mem_pb_type;
837834
mem_pb_type->modes[0].index = 0;
@@ -869,8 +866,7 @@ void ProcessMemoryClass(t_pb_type *mem_pb_type) {
869866
mem_pb_type->model = nullptr;
870867

871868
mem_pb_type->modes[0].num_interconnect = mem_pb_type->num_ports * num_pb;
872-
mem_pb_type->modes[0].interconnect = (t_interconnect*) vtr::calloc(
873-
mem_pb_type->modes[0].num_interconnect, sizeof(t_interconnect));
869+
mem_pb_type->modes[0].interconnect = new t_interconnect[mem_pb_type->modes[0].num_interconnect];
874870

875871
for (i = 0; i < mem_pb_type->modes[0].num_interconnect; i++) {
876872
mem_pb_type->modes[0].interconnect[i].parent_mode_index = 0;

libs/libarchfpga/src/echo_arch.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void PrintArchInfo(FILE * Echo, const t_arch *arch) {
112112
fprintf(Echo, "Printing architecture... \n\n");
113113
//Layout
114114
fprintf(Echo, "*************************************************\n");
115-
for (auto grid_layout : arch->grid_layouts) {
115+
for (const auto &grid_layout : arch->grid_layouts) {
116116
if (grid_layout.grid_type == GridDefType::AUTO) {
117117
fprintf(Echo, "Layout: '%s' Type: auto Aspect_Ratio: %f\n", grid_layout.name.c_str(), grid_layout.aspect_ratio);
118118
} else {
@@ -250,7 +250,7 @@ void PrintArchInfo(FILE * Echo, const t_arch *arch) {
250250
fprintf(Echo, "*************************************************\n");
251251
fprintf(Echo, "Segment List:\n");
252252
for (i = 0; i < (int)(arch->Segments).size(); i++) {
253-
struct t_segment_inf seg = arch->Segments[i];
253+
const struct t_segment_inf &seg = arch->Segments[i];
254254
fprintf(Echo,
255255
"\tSegment[%d]: frequency %d length %d R_metal %e C_metal %e\n",
256256
i + 1, seg.frequency, seg.length,

0 commit comments

Comments
 (0)