Skip to content

Commit d5b6534

Browse files
mtdudekacomodi
authored andcommitted
RR_graph building for fpga interchange
Signed-off-by: Maciej Dudek <[email protected]>
1 parent 5d48549 commit d5b6534

File tree

8 files changed

+1311
-96
lines changed

8 files changed

+1311
-96
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include "fpga_interchange_arch_utils.h"
2+
3+
/****************** Utility functions ******************/
4+
5+
/**
6+
* @brief The FPGA interchange timing model includes three different corners (min, typ and max) for each of the two
7+
* speed_models (slow and fast).
8+
*
9+
* Timing data can be found on PIPs, nodes, site pins and bel pins.
10+
* This function retrieves the timing value based on the wanted speed model and the wanted corner.
11+
*
12+
* Corner model is considered valid if at least one configuration is set.
13+
* In that case this value shall be returned.
14+
*
15+
* More information on the FPGA Interchange timing model can be found here:
16+
* - https://github.com/chipsalliance/fpga-interchange-schema/blob/main/interchange/DeviceResources.capnp
17+
*/
18+
19+
float get_corner_value(DeviceResources::Device::CornerModel::Reader model, const char* speed_model, const char* value) {
20+
bool slow_model = std::string(speed_model) == std::string("slow");
21+
bool fast_model = std::string(speed_model) == std::string("fast");
22+
23+
bool min_corner = std::string(value) == std::string("min");
24+
bool typ_corner = std::string(value) == std::string("typ");
25+
bool max_corner = std::string(value) == std::string("max");
26+
27+
if (!slow_model && !fast_model) {
28+
archfpga_throw("", __LINE__, "Wrong speed model `%s`. Expected `slow` or `fast`\n", speed_model);
29+
}
30+
31+
if (!min_corner && !typ_corner && !max_corner) {
32+
archfpga_throw("", __LINE__, "Wrong corner model `%s`. Expected `min`, `typ` or `max`\n", value);
33+
}
34+
35+
bool has_fast = model.getFast().hasFast();
36+
bool has_slow = model.getSlow().hasSlow();
37+
38+
if ((slow_model || (fast_model && !has_fast)) && has_slow) {
39+
auto half = model.getSlow().getSlow();
40+
if (min_corner && half.getMin().isMin()) {
41+
return half.getMin().getMin();
42+
} else if (typ_corner && half.getTyp().isTyp()) {
43+
return half.getTyp().getTyp();
44+
} else if (max_corner && half.getMax().isMax()) {
45+
return half.getMax().getMax();
46+
} else {
47+
if (half.getMin().isMin()) {
48+
return half.getMin().getMin();
49+
} else if (half.getTyp().isTyp()) {
50+
return half.getTyp().getTyp();
51+
} else if (half.getMax().isMax()) {
52+
return half.getMax().getMax();
53+
} else {
54+
archfpga_throw("", __LINE__, "Invalid speed model %s. No value found!\n", speed_model);
55+
}
56+
}
57+
} else if ((fast_model || slow_model) && has_fast) {
58+
auto half = model.getFast().getFast();
59+
if (min_corner && half.getMin().isMin()) {
60+
return half.getMin().getMin();
61+
} else if (typ_corner && half.getTyp().isTyp()) {
62+
return half.getTyp().getTyp();
63+
} else if (max_corner && half.getMax().isMax()) {
64+
return half.getMax().getMax();
65+
} else {
66+
if (half.getMin().isMin()) {
67+
return half.getMin().getMin();
68+
} else if (half.getTyp().isTyp()) {
69+
return half.getTyp().getTyp();
70+
} else if (half.getMax().isMax()) {
71+
return half.getMax().getMax();
72+
} else {
73+
archfpga_throw("", __LINE__, "Invalid speed model %s. No value found!\n", speed_model);
74+
}
75+
}
76+
}
77+
return 0.;
78+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifndef FPGAINTERCHANGE_ARCH_UTILS_FILE_H
2+
#define FPGAINTERCHANGE_ARCH_UTILS_FILE_H
3+
4+
#include "arch_types.h"
5+
#include "arch_error.h"
6+
#include "vtr_error.h"
7+
8+
#include "DeviceResources.capnp.h"
9+
#include "LogicalNetlist.capnp.h"
10+
#include "capnp/serialize.h"
11+
#include "capnp/serialize-packed.h"
12+
#include <fcntl.h>
13+
#include <unistd.h>
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
19+
/****************** Utility functions ******************/
20+
21+
/**
22+
* @brief The FPGA interchange timing model includes three different corners (min, typ and max) for each of the two
23+
* speed_models (slow and fast).
24+
*
25+
* Timing data can be found on PIPs, nodes, site pins and bel pins.
26+
* This function retrieves the timing value based on the wanted speed model and the wanted corner.
27+
*
28+
* Corner model is considered valid if at least one configuration is set.
29+
* In that case this value shall be returned.
30+
*
31+
* More information on the FPGA Interchange timing model can be found here:
32+
* - https://github.com/chipsalliance/fpga-interchange-schema/blob/main/interchange/DeviceResources.capnp
33+
*/
34+
35+
float get_corner_value(DeviceResources::Device::CornerModel::Reader model, const char* speed_model, const char* value);
36+
37+
#ifdef __cplusplus
38+
}
39+
#endif
40+
41+
#endif

libs/libarchfpga/src/read_fpga_interchange_arch.cpp

Lines changed: 2 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "arch_types.h"
2222

2323
#include "read_fpga_interchange_arch.h"
24+
#include "fpga_interchange_arch_utils.h"
2425

2526
/*
2627
* FPGA Interchange Device frontend
@@ -78,82 +79,6 @@ struct t_ic_data {
7879

7980
/****************** Utility functions ******************/
8081

81-
/**
82-
* @brief The FPGA interchange timing model includes three different corners (min, typ and max) for each of the two
83-
* speed_models (slow and fast).
84-
*
85-
* Timing data can be found on PIPs, nodes, site pins and bel pins.
86-
* This function retrieves the timing value based on the wanted speed model and the wanted corner.
87-
*
88-
* More information on the FPGA Interchange timing model can be found here:
89-
* - https://github.com/chipsalliance/fpga-interchange-schema/blob/main/interchange/DeviceResources.capnp
90-
*/
91-
static float get_corner_value(Device::CornerModel::Reader model, const char* speed_model, const char* value) {
92-
bool slow_model = std::string(speed_model) == std::string("slow");
93-
bool fast_model = std::string(speed_model) == std::string("fast");
94-
95-
bool min_corner = std::string(value) == std::string("min");
96-
bool typ_corner = std::string(value) == std::string("typ");
97-
bool max_corner = std::string(value) == std::string("max");
98-
99-
if (!slow_model && !fast_model) {
100-
archfpga_throw("", __LINE__,
101-
"Wrong speed model `%s`. Expected `slow` or `fast`\n", speed_model);
102-
}
103-
104-
if (!min_corner && !typ_corner && !max_corner) {
105-
archfpga_throw("", __LINE__,
106-
"Wrong corner model `%s`. Expected `min`, `typ` or `max`\n", value);
107-
}
108-
109-
bool has_fast = model.getFast().hasFast();
110-
bool has_slow = model.getSlow().hasSlow();
111-
112-
if (slow_model && has_slow) {
113-
auto half = model.getSlow().getSlow();
114-
if (min_corner && half.getMin().isMin()) {
115-
return half.getMin().getMin();
116-
} else if (typ_corner && half.getTyp().isTyp()) {
117-
return half.getTyp().getTyp();
118-
} else if (max_corner && half.getMax().isMax()) {
119-
return half.getMax().getMax();
120-
} else {
121-
if (half.getMin().isMin()) {
122-
return half.getMin().getMin();
123-
} else if (half.getTyp().isTyp()) {
124-
return half.getTyp().getTyp();
125-
} else if (half.getMax().isMax()) {
126-
return half.getMax().getMax();
127-
} else {
128-
archfpga_throw("", __LINE__,
129-
"Invalid speed model %s. No value found!\n", speed_model);
130-
}
131-
}
132-
} else if (fast_model && has_fast) {
133-
auto half = model.getFast().getFast();
134-
if (min_corner && half.getMin().isMin()) {
135-
return half.getMin().getMin();
136-
} else if (typ_corner && half.getTyp().isTyp()) {
137-
return half.getTyp().getTyp();
138-
} else if (max_corner && half.getMax().isMax()) {
139-
return half.getMax().getMax();
140-
} else {
141-
if (half.getMin().isMin()) {
142-
return half.getMin().getMin();
143-
} else if (half.getTyp().isTyp()) {
144-
return half.getTyp().getTyp();
145-
} else if (half.getMax().isMax()) {
146-
return half.getMax().getMax();
147-
} else {
148-
archfpga_throw("", __LINE__,
149-
"Invalid speed model %s. No value found!\n", speed_model);
150-
}
151-
}
152-
}
153-
154-
return 0.;
155-
}
156-
15782
/** @brief Returns the port corresponding to the given model in the architecture */
15883
static t_model_ports* get_model_port(t_arch* arch, std::string model, std::string port, bool fail = true) {
15984
for (t_model* m : {arch->models, arch->model_library}) {
@@ -2457,17 +2382,11 @@ struct ArchReader {
24572382
}
24582383
}
24592384

2460-
// FIXME: have only one segment type for the time being, so that
2461-
// the RR graph generation is correct.
2462-
// This can be removed once the RR graph reader from the interchange
2463-
// device is ready and functional.
2464-
size_t num_seg = 1; //wire_names.size();
2385+
int num_seg = wire_names.size();
24652386

24662387
arch_->Segments.resize(num_seg);
24672388
size_t index = 0;
24682389
for (auto i : wire_names) {
2469-
if (index >= num_seg) break;
2470-
24712390
// Use default values as we will populate rr_graph with correct values
24722391
// This segments are just declaration of future use
24732392
arch_->Segments[index].name = str(i);

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)
422422

423423
RouterOpts->max_logged_overused_rr_nodes = Options.max_logged_overused_rr_nodes;
424424
RouterOpts->generate_rr_node_overuse_report = Options.generate_rr_node_overuse_report;
425-
RouterOpts->FPGAInterchange = Options.FPGAInterchangeDevice;
425+
RouterOpts->FPGAInterchange = (Options.arch_format == e_arch_format::FPGAInterchange);
426426
}
427427

428428
static void SetupAnnealSched(const t_options& Options,

vpr/src/base/vpr_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,9 @@ struct t_router_opts {
12501250
e_rr_node_reorder_algorithm reorder_rr_graph_nodes_algorithm = DONT_REORDER;
12511251
int reorder_rr_graph_nodes_threshold = 0;
12521252
int reorder_rr_graph_nodes_seed = 1;
1253+
1254+
// Options related to FPGA Interchange
1255+
bool FPGAInterchange;
12531256
};
12541257

12551258
struct t_analysis_opts {

vpr/src/route/rr_graph.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ void create_rr_graph(const t_graph_type graph_type,
318318
auto& mutable_device_ctx = g_vpr_ctx.mutable_device();
319319

320320
if (!det_routing_arch->read_rr_graph_filename.empty() || router_opts.FPGAInterchange) {
321-
if (device_ctx.read_rr_graph_filename != det_routing_arch->read_rr_graph_filename) {
321+
if (device_ctx.read_rr_graph_filename != det_routing_arch->read_rr_graph_filename && !router_opts.FPGAInterchange) {
322322
free_rr_graph();
323323

324324
load_rr_file(graph_type,
@@ -343,11 +343,7 @@ void create_rr_graph(const t_graph_type graph_type,
343343
segment_inf,
344344
router_opts.base_cost_type,
345345
&det_routing_arch->wire_to_rr_ipin_switch,
346-
det_routing_arch->read_rr_graph_filename.c_str(),
347-
router_opts.read_rr_edge_metadata,
348346
router_opts.do_check_rr_graph);
349-
350-
exit(0);
351347
if (router_opts.reorder_rr_graph_nodes_algorithm != DONT_REORDER) {
352348
mutable_device_ctx.rr_graph_builder.reorder_nodes(router_opts.reorder_rr_graph_nodes_algorithm,
353349
router_opts.reorder_rr_graph_nodes_threshold,

0 commit comments

Comments
 (0)