Skip to content

Commit d912bdb

Browse files
authored
Merge pull request #1602 from verilog-to-routing/vpr_constraints_fixes
Vpr constraints fixes
2 parents b0223dc + 397ad0f commit d912bdb

9 files changed

+111
-24
lines changed

vpr/src/base/ShowSetup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void ShowSetup(const t_vpr_setup& vpr_setup) {
3131
VTR_LOG("Circuit placement file: %s\n", vpr_setup.FileNameOpts.PlaceFile.c_str());
3232
VTR_LOG("Circuit routing file: %s\n", vpr_setup.FileNameOpts.RouteFile.c_str());
3333
VTR_LOG("Circuit SDC file: %s\n", vpr_setup.Timing.SDCFile.c_str());
34-
VTR_LOG("Vpr Constraints file: %s\n", vpr_setup.FileNameOpts.read_vpr_constraints_file.c_str());
34+
VTR_LOG("Vpr floorplanning constraints file: %s\n", vpr_setup.FileNameOpts.read_vpr_constraints_file.c_str());
3535
VTR_LOG("\n");
3636

3737
VTR_LOG("Packer: %s\n", (vpr_setup.PackerOpts.doPacking ? "ENABLED" : "DISABLED"));

vpr/src/base/constraints_load.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void print_region(FILE* fp, Region region) {
2323

2424
void print_partition(FILE* fp, Partition part) {
2525
std::string name = part.get_name();
26-
fprintf(fp, "\npartition_name: %s\n", name.c_str());
26+
fprintf(fp, "partition_name: %s\n", name.c_str());
2727

2828
PartitionRegion pr = part.get_part_region();
2929

@@ -51,6 +51,7 @@ void print_constraints(FILE* fp, VprConstraints constraints, int num_parts) {
5151

5252
temp_part = constraints.get_partition(part_id);
5353

54+
fprintf(fp, "\npartition_id: %zu\n", size_t(part_id));
5455
print_partition(fp, temp_part);
5556

5657
atoms = constraints.get_part_atoms(part_id);

vpr/src/base/gen/vpr_constraints_uxsdcxx.h

Lines changed: 8 additions & 9 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.py ../vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
8-
* Input file: /home/khalid88/Documents/vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
9-
* md5sum of input file: 3e1f2692931484aa45dce794ba723aa9
7+
* Cmdline: uxsdcxx.py vpr_constraints.xsd
8+
* Input file: /home/khalid88/Documents/uxsdcxx/vpr_constraints.xsd
9+
* md5sum of input file: 6b6011a6e6446347b234da82e517422e
1010
*/
1111

1212
#include <functional>
@@ -521,12 +521,11 @@ inline void load_add_region(const pugi::xml_node& root, T& out, Context& context
521521
noreturn_report(report_error, "Unexpected child element in <add_region>.");
522522
}
523523

524-
constexpr int NUM_T_PARTITION_STATES = 3;
524+
constexpr int NUM_T_PARTITION_STATES = 2;
525525
constexpr const int NUM_T_PARTITION_INPUTS = 2;
526526
constexpr int gstate_t_partition[NUM_T_PARTITION_STATES][NUM_T_PARTITION_INPUTS] = {
527-
{-1, 0},
528-
{1, 0},
529-
{1, -1},
527+
{0, 0},
528+
{0, 0},
530529
};
531530
template<class T, typename Context>
532531
inline void load_partition(const pugi::xml_node& root, T& out, Context& context, const std::function<void(const char*)>* report_error, ptrdiff_t* offset_debug) {
@@ -552,7 +551,7 @@ inline void load_partition(const pugi::xml_node& root, T& out, Context& context,
552551
size_t add_atom_count = 0;
553552
size_t add_region_count = 0;
554553
{
555-
int next, state = 2;
554+
int next, state = 1;
556555
for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
557556
*offset_debug = node.offset_debug();
558557
gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
@@ -575,7 +574,7 @@ inline void load_partition(const pugi::xml_node& root, T& out, Context& context,
575574
out.preallocate_partition_add_atom(context, add_atom_count);
576575
out.preallocate_partition_add_region(context, add_region_count);
577576
}
578-
int next, state = 2;
577+
int next, state = 1;
579578
for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
580579
*offset_debug = node.offset_debug();
581580
gtok_t_partition in = lex_node_t_partition(node.name(), report_error);

vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h

Lines changed: 7 additions & 5 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.py ../vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
8-
* Input file: /home/khalid88/Documents/vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
9-
* md5sum of input file: 3e1f2692931484aa45dce794ba723aa9
7+
* Cmdline: uxsdcxx.py vpr_constraints.xsd
8+
* Input file: /home/khalid88/Documents/uxsdcxx/vpr_constraints.xsd
9+
* md5sum of input file: 6b6011a6e6446347b234da82e517422e
1010
*/
1111

1212
#include <functional>
@@ -68,8 +68,10 @@ class VprConstraintsBase {
6868
/** Generated for complex type "partition":
6969
* <xs:complexType name="partition">
7070
* <xs:sequence>
71-
* <xs:element maxOccurs="unbounded" name="add_atom" type="add_atom" />
72-
* <xs:element maxOccurs="unbounded" name="add_region" type="add_region" />
71+
* <xs:choice maxOccurs="unbounded">
72+
* <xs:element name="add_atom" type="add_atom" />
73+
* <xs:element name="add_region" type="add_region" />
74+
* </xs:choice>
7375
* </xs:sequence>
7476
* <xs:attribute name="name" type="xs:string" use="required" />
7577
* </xs:complexType>

vpr/src/base/read_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
13821382
.show_in(argparse::ShowIn::HELP_ONLY);
13831383

13841384
file_grp.add_argument(args.read_vpr_constraints_file, "--read_vpr_constraints")
1385-
.help("Reads the constraints data from the constraints file.")
1385+
.help("Reads the floorplanning constraints from the specified XML file.")
13861386
.show_in(argparse::ShowIn::HELP_ONLY);
13871387

13881388
file_grp.add_argument(args.read_router_lookahead, "--read_router_lookahead")

vpr/src/base/vpr_constraints.xsd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@
4343
the add_region elements. -->
4444
<xs:complexType name="partition">
4545
<xs:sequence>
46-
<xs:element name="add_atom" type="add_atom" maxOccurs="unbounded"/>
47-
<xs:element name="add_region" type="add_region" maxOccurs="unbounded"/>
46+
<xs:choice maxOccurs="unbounded">
47+
<xs:element name="add_atom" type="add_atom"/>
48+
<xs:element name="add_region" type="add_region"/>
49+
</xs:choice>
4850
</xs:sequence>
4951

5052
<xs:attribute name="name" type="xs:string" use="required"/>

vpr/src/base/vpr_constraints_reader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void load_vpr_constraints_file(const char* read_vpr_constraints_name) {
2727
} else {
2828
VTR_LOG_WARN(
2929
"VPR constraints file '%s' may be in incorrect format. "
30-
"Expecting .xml format\n",
30+
"Expecting .xml format. Not reading file.\n",
3131
read_vpr_constraints_name);
3232
}
3333

vpr/src/base/vpr_constraints_reader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
/* Defines the function used to load a vpr constraints file written in xml format into vpr*/
1+
/* Defines the function used to load a vpr constraints file written in XML format into vpr
2+
* The functions loads up the VprConstraints, Partition, Region, and PartitionRegion data structures
3+
* according to the data provided in the XML file*/
24

35
#ifndef VPR_CONSTRAINTS_READER_H_
46
#define VPR_CONSTRAINTS_READER_H_

vpr/src/base/vpr_constraints_serializer.h

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,44 @@
1212

1313
#include "vpr_constraints_uxsdcxx_interface.h"
1414

15+
/**
16+
* @file
17+
* @brief The reading of vpr floorplanning constraints is now done via uxsdcxx and the 'vpr_constraints.xsd' file.
18+
* The interface between the generated code and VPR is provided by VprConstraintsBase, which is in the
19+
* file 'vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h'.
20+
* This file implements the virtual functions from VprConstraintsBase.
21+
*
22+
* Overview
23+
* ========
24+
* 'vpr_constraints.xsd' is an XML schema that specifies the desired format for a VPR constraints file.
25+
* If this schema is changed, the following files must be regenerated: 'vpr/src/base/gen/vpr_constraints_uxsdcxx.h' and
26+
* 'vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h'.
27+
*
28+
* Instructions to Update the Files
29+
* ================================
30+
*
31+
* 1. Clone https://github.com/duck2/uxsdcxx/
32+
* 2. Run 'python3 -mpip install --user -r requirements.txt'
33+
* 3. Run 'python3 uxsdcxx.py vpr/src/base/vpr_constraints.xsd'
34+
* 4. Copy 'vpr_constraints_uxsdcxx.h' and 'vpr_constraints_uxsdcxx_interface.h' to vpr/src/base/gen
35+
* 5. Run 'make format'
36+
* 6. Update 'vpr/src/base/vpr_constraints_serializer.h' (this file) by adding or changing functions as needed.
37+
* If the schema has changed, the compiler will complain that virtual functions are missing if they are
38+
* not implemented here.
39+
*
40+
* Functions in this file
41+
* ======================
42+
*
43+
* This file implements all the functions that are necessary for the load/read interface of uxsdcxx. These are start_load, finish_load,
44+
* error_encountered, and any function starting with 'set', 'add', 'preallocate' or 'finish'. Some of the load functions (ex. finish_load and
45+
* the preallocate functions) have been stubbed out because the load could be successfully completed without implementing them.
46+
*
47+
* The functions related to the write interface have also been stubbed out because writing vpr_constraints XML files is not needed at this time.
48+
* These functions can be implemented to make the write interface if needed.
49+
*
50+
* For more detail on how the load and write interfaces work with uxsdcxx, refer to 'vpr/src/route/SCHEMA_GENERATOR.md'
51+
*/
52+
1553
struct VprConstraintsContextTypes : public uxsd::DefaultVprConstraintsContextTypes {
1654
using AddAtomReadContext = void*;
1755
using AddRegionReadContext = void*;
@@ -58,9 +96,38 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr
5896
virtual inline void set_add_atom_name_pattern(const char* name_pattern, void*& /*ctx*/) final {
5997
auto& atom_ctx = g_vpr_ctx.atom();
6098
std::string atom_name = name_pattern;
99+
100+
auto atom_name_regex = std::regex(atom_name);
101+
102+
atoms_.clear();
103+
61104
atom_id_ = atom_ctx.nlist.find_block(name_pattern);
62105

63-
if (atom_id_ == AtomBlockId::INVALID()) {
106+
/* The constraints file may either provide a specific atom name or a regex.
107+
* If the a valid atom ID is found for the atom name, then a specific atom name
108+
* must have been read in from the file. The if condition checks for this case.
109+
* The else statement checks for atoms that may match a regex.
110+
* This code may get slow if many regexes are given in the file.
111+
*/
112+
if (atom_id_ != AtomBlockId::INVALID()) {
113+
atoms_.push_back(atom_id_);
114+
} else {
115+
/*If the atom name returns an invalid ID, it might be a regular expression, so loop through the atoms blocks
116+
* and see if any block names match atom_name_regex.
117+
*/
118+
for (auto block_id : atom_ctx.nlist.blocks()) {
119+
auto block_name = atom_ctx.nlist.block_name(block_id);
120+
121+
if (std::regex_search(block_name, atom_name_regex)) {
122+
atoms_.push_back(block_id);
123+
}
124+
}
125+
}
126+
127+
/*If the atoms_ vector is empty by this point, no atoms were found that matched the name,
128+
* so the name is invalid.
129+
*/
130+
if (atoms_.empty()) {
64131
VTR_LOG_WARN("Atom %s was not found, skipping atom.\n", name_pattern);
65132
}
66133
}
@@ -128,8 +195,8 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr
128195
virtual inline void finish_partition_add_atom(void*& /*ctx*/) final {
129196
PartitionId part_id(num_partitions_);
130197

131-
if (atom_id_ != AtomBlockId::INVALID()) {
132-
constraints_.add_constrained_atom(atom_id_, part_id);
198+
for (unsigned int i = 0; i < atoms_.size(); i++) {
199+
constraints_.add_constrained_atom(atoms_[i], part_id);
133200
}
134201
}
135202

@@ -211,6 +278,11 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr
211278

212279
virtual inline void set_vpr_constraints_tool_name(const char* /*tool_name*/, void*& /*ctx*/) final {}
213280

281+
virtual inline void set_vpr_constraints_constraints_comment(const char* /*constraints_comment*/, void*& /*ctx*/) final {}
282+
283+
virtual inline const char* get_vpr_constraints_constraints_comment(void*& /*ctx*/) final {
284+
return temp_.c_str();
285+
}
214286
virtual inline void* init_vpr_constraints_partition_list(void*& /*ctx*/) final {
215287
return nullptr;
216288
}
@@ -227,13 +299,22 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase<VprConstr
227299

228300
//temp data for loads
229301
const std::function<void(const char*)>* report_error_;
302+
303+
//temp data structures to be loaded during file reading
230304
Region loaded_region;
231305
Partition loaded_partition;
232306
PartitionRegion loaded_part_region;
233307
VprConstraints constraints_;
308+
309+
//temp string used when a method must return a const char*
234310
std::string temp_;
311+
312+
//used to count the number of partitions read in from the file
235313
int num_partitions_ = 0;
314+
315+
//used when reading in atom names and regular expressions for atoms
236316
AtomBlockId atom_id_;
317+
std::vector<AtomBlockId> atoms_;
237318
};
238319

239320
#endif /* VPR_CONSTRAINTS_SERIALIZER_H_ */

0 commit comments

Comments
 (0)