Skip to content

Commit 90a87b9

Browse files
committed
Merge branch 'master+wip' into equivalent-tiles
Signed-off-by: Alessandro Comodi <[email protected]>
2 parents ea24a9e + eb6445b commit 90a87b9

20 files changed

+110
-33
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
name: Bug report
33
about: Create a report to help us improve
4+
title: ''
5+
labels: ''
6+
assignees: ''
47

58
---
69

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
name: Feature request
33
about: Suggest an idea for this project
4+
title: ''
5+
labels: ''
6+
assignees: ''
47

58
---
69

.github/ISSUE_TEMPLATE/vtr-change.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: VTR change
3+
about: Describe purpose and lifecycle of a local change we made to VTR
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
### Why did we need this? (what does this change enable us to do)
11+
<!--- i.e. what does this change enable us to do? -->
12+
13+
### What did it change?
14+
<!--- i.e. technical description what the change does -->
15+
16+
### Should it be merged upstream - if not, when can we delete it?
17+
18+
### What is needed to get this merged / deleted?
19+
20+
* [ ] is the implementation work to make suitable for merging / deletion completed?
21+
* [ ] Is there an associated test? <!--- i.e. how will we prevent it from regressing? -->
22+
* [ ] is this currently part of the Conda package?
23+
* [ ] is this properly cleaned up in our local repositories? <!--- add subtasks here if needed) -->
24+
25+
### Tracker / branch / PR & other useful links

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
2+
SymbiFlow WIP changes for Verilog to Routing (VTR)
3+
==================================================
4+
5+
This branch contains work in progress changes for using Verilog to Routing
6+
(VTR) as part of SymbiFlow.
7+
8+
---
9+
110
# Verilog to Routing (VTR)
2-
[![Build Status](https://travis-ci.org/verilog-to-routing/vtr-verilog-to-routing.svg?branch=master)](https://travis-ci.org/verilog-to-routing/vtr-verilog-to-routing) [![Documentation Status](https://readthedocs.org/projects/vtr/badge/?version=latest)](http://docs.verilogtorouting.org/en/latest/?badge=latest)
11+
[![Build Status](https://travis-ci.com/SymbiFlow/vtr-verilog-to-routing.svg?branch=master)](https://travis-ci.com/SymbiFlow/vtr-verilog-to-routing) [![Documentation Status](https://readthedocs.org/projects/vtr/badge/?version=latest)](http://docs.verilogtorouting.org/en/latest/?badge=latest)
312

413
## Introduction
514
The Verilog-to-Routing (VTR) project is a world-wide collaborative effort to provide a open-source framework for conducting FPGA architecture and CAD research and development.

libs/libarchfpga/src/physical_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,7 @@ enum class BufferSize {
12541254
* R: Equivalent resistance of the buffer/switch. *
12551255
* Cin: Input capacitance. *
12561256
* Cout: Output capacitance. *
1257+
* Cinternal: Internal capacitance in a buffer with fanout. *
12571258
* Tdel_map: A map where the key is the number of inputs and the entry *
12581259
* is the corresponding delay. If there is only one entry at key *
12591260
* UNDEFINED, then delay is a constant (doesn't vary with fan-in). *
@@ -1271,6 +1272,7 @@ struct t_arch_switch_inf {
12711272
float R = 0.;
12721273
float Cin = 0.;
12731274
float Cout = 0.;
1275+
float Cinternal = 0.; // defined the property Cinternal
12741276
float mux_trans_size = 1.;
12751277
BufferSize buf_size_type = BufferSize::AUTO;
12761278
float buf_size = 0.;
@@ -1322,6 +1324,7 @@ struct t_arch_switch_inf {
13221324
* R: Equivalent resistance of the buffer/switch. *
13231325
* Cin: Input capacitance. *
13241326
* Cout: Output capacitance. *
1327+
* Cinternal: Internal capacitance in a buffer. *
13251328
* Tdel: Intrinsic delay. The delay through an unloaded switch is *
13261329
* Tdel + R * Cout. *
13271330
* mux_trans_size: The area of each transistor in the segment's driving mux *
@@ -1332,6 +1335,7 @@ struct t_rr_switch_inf {
13321335
float R = 0.;
13331336
float Cin = 0.;
13341337
float Cout = 0.;
1338+
float Cinternal = 0.; //defined the property Cinternal
13351339
float Tdel = 0.;
13361340
float mux_trans_size = 0.;
13371341
float buf_size = 0.;

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3284,23 +3284,23 @@ static void ProcessSwitches(pugi::xml_node Parent,
32843284
SwitchType type = SwitchType::MUX;
32853285
if (0 == strcmp(type_name, "mux")) {
32863286
type = SwitchType::MUX;
3287-
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel", "buf_size", "power_buf_size", "mux_trans_size"}, " with type '"s + type_name + "'"s, loc_data);
3287+
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Cinternal", "Tdel", "buf_size", "power_buf_size", "mux_trans_size"}, " with type '"s + type_name + "'"s, loc_data); // buffered switch should have a Cinternal element
32883288

32893289
} else if (0 == strcmp(type_name, "tristate")) {
32903290
type = SwitchType::TRISTATE;
3291-
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel", "buf_size", "power_buf_size"}, " with type '"s + type_name + "'"s, loc_data);
3291+
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Cinternal", "Tdel", "buf_size", "power_buf_size"}, " with type '"s + type_name + "'"s, loc_data); // buffered switch should have a Cinternal element
32923292

32933293
} else if (0 == strcmp(type_name, "buffer")) {
32943294
type = SwitchType::BUFFER;
3295-
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel", "buf_size", "power_buf_size"}, " with type '"s + type_name + "'"s, loc_data);
3295+
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel", "buf_size", "power_buf_size"}, " with type '"s + type_name + "'"s, loc_data); // buffer should not have a Cinternal element
32963296

32973297
} else if (0 == strcmp(type_name, "pass_gate")) {
32983298
type = SwitchType::PASS_GATE;
3299-
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel"}, " with type '"s + type_name + "'"s, loc_data);
3299+
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel"}, " with type '"s + type_name + "'"s, loc_data); // unbuffered switch does not have Cinternal element
33003300

33013301
} else if (0 == strcmp(type_name, "short")) {
33023302
type = SwitchType::SHORT;
3303-
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel"}, " with type "s + type_name + "'"s, loc_data);
3303+
expect_only_attributes(Node, {"type", "name", "R", "Cin", "Cout", "Tdel"}, " with type "s + type_name + "'"s, loc_data); // unbuffered switch does not have Cinternal element
33043304

33053305
} else {
33063306
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
@@ -3312,13 +3312,16 @@ static void ProcessSwitches(pugi::xml_node Parent,
33123312

33133313
ReqOpt COUT_REQD = TIMING_ENABLE_REQD;
33143314
ReqOpt CIN_REQD = TIMING_ENABLE_REQD;
3315+
ReqOpt CINTERNAL_REQD = OPTIONAL; //defined the parameter
3316+
33153317
if (arch_switch.type() == SwitchType::SHORT) {
33163318
//Cin/Cout are optional on shorts, since they really only have one capacitance
33173319
CIN_REQD = OPTIONAL;
33183320
COUT_REQD = OPTIONAL;
33193321
}
33203322
arch_switch.Cin = get_attribute(Node, "Cin", loc_data, CIN_REQD).as_float(0);
33213323
arch_switch.Cout = get_attribute(Node, "Cout", loc_data, COUT_REQD).as_float(0);
3324+
arch_switch.Cinternal = get_attribute(Node, "Cinternal", loc_data, CINTERNAL_REQD).as_float(0); // retrieve the optional parameter
33223325

33233326
if (arch_switch.type() == SwitchType::MUX) {
33243327
//Only muxes have mux transistors

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)
347347
RouterOpts->max_convergence_count = Options.router_max_convergence_count;
348348
RouterOpts->reconvergence_cpd_threshold = Options.router_reconvergence_cpd_threshold;
349349
RouterOpts->first_iteration_timing_report_file = Options.router_first_iteration_timing_report_file;
350-
351350
RouterOpts->strict_checks = Options.strict_checks;
351+
RouterOpts->disable_check_route = Options.disable_check_route;
352352
}
353353

354354
static void SetupAnnealSched(const t_options& Options,

vpr/src/base/read_options.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,16 @@ static argparse::ArgumentParser create_arg_parser(std::string prog_name, t_optio
931931
.default_value("on")
932932
.show_in(argparse::ShowIn::HELP_ONLY);
933933

934+
gen_grp.add_argument<bool, ParseOnOff>(args.allow_dangling_combinational_nodes, "--allow_dangling_combinational_nodes")
935+
.help(
936+
"Option to allow dangling combinational nodes in the timing graph.\n"
937+
"This option should normally be off, as dangling combinational nodes are unusual\n"
938+
"in the timing graph and may indicate a problem in the circuit or architecture.\n"
939+
"Unless you understand why your architecture/circuit can have valid dangling combinational nodes, this option should be off.\n"
940+
"In general this is a dev-only option and should not be turned on by the end-user.")
941+
.default_value("off")
942+
.show_in(argparse::ShowIn::HELP_ONLY);
943+
934944
auto& file_grp = parser.add_argument_group("file options");
935945

936946
file_grp.add_argument(args.BlifFile, "--circuit_file")
@@ -1533,6 +1543,11 @@ static argparse::ArgumentParser create_arg_parser(std::string prog_name, t_optio
15331543
.default_value("")
15341544
.show_in(argparse::ShowIn::HELP_ONLY);
15351545

1546+
route_timing_grp.add_argument<bool, ParseOnOff>(args.disable_check_route, "--disable_check_route")
1547+
.help("Disables check_route once routing step has finished or when routing file is loaded")
1548+
.default_value("off")
1549+
.show_in(argparse::ShowIn::HELP_ONLY);
1550+
15361551
route_timing_grp.add_argument(args.router_debug_net, "--router_debug_net")
15371552
.help(
15381553
"Controls when router debugging is enabled.\n"

vpr/src/base/read_options.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct t_options {
5050
argparse::ArgValue<e_clock_modeling> clock_modeling;
5151
argparse::ArgValue<bool> exit_before_pack;
5252
argparse::ArgValue<bool> strict_checks;
53+
argparse::ArgValue<bool> allow_dangling_combinational_nodes;
5354

5455
/* Atom netlist options */
5556
argparse::ArgValue<bool> absorb_buffer_luts;
@@ -118,6 +119,7 @@ struct t_options {
118119
argparse::ArgValue<bool> verify_binary_search;
119120
argparse::ArgValue<e_router_algorithm> RouterAlgorithm;
120121
argparse::ArgValue<int> min_incremental_reroute_fanout;
122+
argparse::ArgValue<bool> disable_check_route;
121123

122124
/* Timing-driven router options only */
123125
argparse::ArgValue<float> astar_fac;

vpr/src/base/vpr_api.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ void vpr_init(const int argc, const char** argv, t_options* options, t_vpr_setup
274274
auto& timing_ctx = g_vpr_ctx.mutable_timing();
275275
{
276276
vtr::ScopedStartFinishTimer t("Build Timing Graph");
277-
timing_ctx.graph = TimingGraphBuilder(atom_ctx.nlist, atom_ctx.lookup).timing_graph();
277+
timing_ctx.graph = TimingGraphBuilder(atom_ctx.nlist, atom_ctx.lookup).timing_graph(options->allow_dangling_combinational_nodes);
278278
VTR_LOG(" Timing Graph Nodes: %zu\n", timing_ctx.graph->nodes().size());
279279
VTR_LOG(" Timing Graph Edges: %zu\n", timing_ctx.graph->edges().size());
280280
VTR_LOG(" Timing Graph Levels: %zu\n", timing_ctx.graph->levels().size());
@@ -636,7 +636,9 @@ RouteStatus vpr_route_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
636636
std::string graphics_msg;
637637
if (route_status.success()) {
638638
//Sanity check the routing
639-
check_route(router_opts.route_type);
639+
if (!router_opts.disable_check_route) {
640+
check_route(router_opts.route_type);
641+
}
640642
get_serial_num();
641643

642644
//Update status

vpr/src/base/vpr_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,7 @@ struct t_router_opts {
947947
float reconvergence_cpd_threshold;
948948
std::string first_iteration_timing_report_file;
949949
bool strict_checks;
950+
bool disable_check_route;
950951
};
951952

952953
struct t_analysis_opts {

vpr/src/place/place.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,13 +2118,12 @@ static bool find_to(t_type_ptr to_type, t_type_ptr from_type, float rlim, const
21182118
//The candidates are stored in a flat_map so we can efficiently find the set of valid
21192119
//candidates with upper/lower bound.
21202120
auto y_lower_iter = to_compressed_block_grid.grid[cx_to].lower_bound(min_cy);
2121-
auto y_upper_iter = to_compressed_block_grid.grid[cx_to].upper_bound(max_cy);
2122-
2123-
// If no block was found at this x location continue
21242121
if (y_lower_iter == to_compressed_block_grid.grid[cx_to].end()) {
21252122
continue;
21262123
}
21272124

2125+
auto y_upper_iter = to_compressed_block_grid.grid[cx_to].upper_bound(max_cy);
2126+
21282127
if (y_lower_iter->first > min_cy) {
21292128
//No valid blocks at this x location which are within rlim_y
21302129
//
@@ -3585,9 +3584,8 @@ static int check_placement_costs(const t_placer_costs& costs,
35853584
comp_td_costs(delay_model, &timing_cost_check);
35863585
//VTR_LOG("timing_cost recomputed from scratch: %g\n", timing_cost_check);
35873586
if (fabs(timing_cost_check - costs.timing_cost) > costs.timing_cost * ERROR_TOL) {
3588-
VTR_LOG_ERROR("timing_cost_check: %g and timing_cost: %g differ in check_place.\n",
3589-
timing_cost_check, costs.timing_cost);
3590-
error++;
3587+
VTR_LOG_WARN("timing_cost_check: %g and timing_cost: %g differ in check_place.\n",
3588+
timing_cost_check, costs.timing_cost);
35913589
}
35923590
}
35933591
return error;

vpr/src/route/check_route.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ void check_route(enum e_route_type route_type) {
118118
} else { //Continuing along existing branch
119119
connects = check_adjacent(prev_node, inode);
120120
if (!connects) {
121-
vpr_throw(VPR_ERROR_ROUTE, __FILE__, __LINE__,
122-
"in check_route: found non-adjacent segments in traceback while checking net %d:\n"
123-
" %s\n"
124-
" %s\n",
125-
size_t(net_id),
126-
describe_rr_node(prev_node).c_str(),
127-
describe_rr_node(inode).c_str());
121+
VTR_LOG_WARN(
122+
"in check_route: found non-adjacent segments in traceback while checking net %d:\n"
123+
" %s\n"
124+
" %s\n",
125+
size_t(net_id),
126+
describe_rr_node(prev_node).c_str(),
127+
describe_rr_node(inode).c_str());
128128
}
129129

130130
connected_to_route[inode] = true; /* Mark as in path. */

vpr/src/route/check_rr_graph.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -502,11 +502,11 @@ static void check_unbuffered_edges(int from_node) {
502502
}
503503

504504
if (trans_matched == false) {
505-
vpr_throw(VPR_ERROR_ROUTE, __FILE__, __LINE__,
506-
"in check_unbuffered_edges:\n"
507-
"connection from node %d to node %d uses an unbuffered switch (switch type %d '%s')\n"
508-
"but there is no corresponding unbuffered switch edge in the other direction.\n",
509-
from_node, to_node, from_switch_type, device_ctx.rr_switch_inf[from_switch_type].name);
505+
VTR_LOG_WARN(
506+
"in check_unbuffered_edges:\n"
507+
"connection from node %d to node %d uses an unbuffered switch (switch type %d '%s')\n"
508+
"but there is no corresponding unbuffered switch edge in the other direction.\n",
509+
from_node, to_node, from_switch_type, device_ctx.rr_switch_inf[from_switch_type].name);
510510
}
511511

512512
} /* End for all from_node edges */

vpr/src/route/rr_graph.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ void load_rr_switch_from_arch_switch(int arch_switch_idx,
893893
device_ctx.rr_switch_inf[rr_switch_idx].set_type(device_ctx.arch_switch_inf[arch_switch_idx].type());
894894
device_ctx.rr_switch_inf[rr_switch_idx].R = device_ctx.arch_switch_inf[arch_switch_idx].R;
895895
device_ctx.rr_switch_inf[rr_switch_idx].Cin = device_ctx.arch_switch_inf[arch_switch_idx].Cin;
896+
device_ctx.rr_switch_inf[rr_switch_idx].Cinternal = device_ctx.arch_switch_inf[arch_switch_idx].Cinternal; //now we can retrieve Cinternal from the arch and implement into the rr calculations.
896897
device_ctx.rr_switch_inf[rr_switch_idx].Cout = device_ctx.arch_switch_inf[arch_switch_idx].Cout;
897898
device_ctx.rr_switch_inf[rr_switch_idx].Tdel = rr_switch_Tdel;
898899
device_ctx.rr_switch_inf[rr_switch_idx].mux_trans_size = device_ctx.arch_switch_inf[arch_switch_idx].mux_trans_size;

vpr/src/route/rr_graph_reader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,13 @@ void process_switches(pugi::xml_node parent, const pugiutil::loc_data& loc_data)
234234
rr_switch.R = get_attribute(SwitchSubnode, "R", loc_data).as_float();
235235
rr_switch.Cin = get_attribute(SwitchSubnode, "Cin", loc_data).as_float();
236236
rr_switch.Cout = get_attribute(SwitchSubnode, "Cout", loc_data).as_float();
237+
rr_switch.Cinternal = get_attribute(SwitchSubnode, "Cinternal", loc_data).as_float();
237238
rr_switch.Tdel = get_attribute(SwitchSubnode, "Tdel", loc_data).as_float();
238239
} else {
239240
rr_switch.R = 0;
240241
rr_switch.Cin = 0;
241242
rr_switch.Cout = 0;
243+
rr_switch.Cinternal = 0;
242244
rr_switch.Tdel = 0;
243245
}
244246
SwitchSubnode = get_single_child(Switch, "sizing", loc_data);

vpr/src/route/rr_graph_writer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ void write_rr_switches(fstream& fp) {
189189
}
190190
fp << ">" << endl;
191191

192-
fp << "\t\t\t<timing R=\"" << setprecision(FLOAT_PRECISION) << rr_switch.R << "\" Cin=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Cin << "\" Cout=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Cout << "\" Tdel=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Tdel << "\"/>" << endl;
192+
fp << "\t\t\t<timing R=\"" << setprecision(FLOAT_PRECISION) << rr_switch.R << "\" Cin=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Cin << "\" Cout=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Cout << "\" Cinternal=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Cinternal << //will print display the value of Cinternal
193+
"\" Tdel=\"" << setprecision(FLOAT_PRECISION) << rr_switch.Tdel << "\"/>" << endl;
193194
fp << "\t\t\t<sizing mux_trans_size=\"" << setprecision(FLOAT_PRECISION) << rr_switch.mux_trans_size << "\" buf_size=\"" << setprecision(FLOAT_PRECISION) << rr_switch.buf_size << "\"/>" << endl;
194195
fp << "\t\t</switch>" << endl;
195196
}

vpr/src/timing/timing_graph_builder.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ TimingGraphBuilder::TimingGraphBuilder(const AtomNetlist& netlist,
4040
//pass
4141
}
4242

43-
std::unique_ptr<TimingGraph> TimingGraphBuilder::timing_graph() {
44-
build();
43+
std::unique_ptr<TimingGraph> TimingGraphBuilder::timing_graph(bool allow_dangling_combinational_nodes) {
44+
build(allow_dangling_combinational_nodes);
4545
opt_memory_layout();
4646

4747
VTR_ASSERT(tg_);
@@ -50,9 +50,13 @@ std::unique_ptr<TimingGraph> TimingGraphBuilder::timing_graph() {
5050
return std::move(tg_);
5151
}
5252

53-
void TimingGraphBuilder::build() {
53+
void TimingGraphBuilder::build(bool allow_dangling_combinational_nodes) {
5454
tg_ = std::make_unique<tatum::TimingGraph>();
5555

56+
// Optionally allow dangling combinational nodes.
57+
// Set by `--allow_dangling_combinational_nodes on`. Default value is false
58+
tg_->set_allow_dangling_combinational_nodes(allow_dangling_combinational_nodes);
59+
5660
for (AtomBlockId blk : netlist_.blocks()) {
5761
AtomBlockType blk_type = netlist_.block_type(blk);
5862

vpr/src/timing/timing_graph_builder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ class TimingGraphBuilder {
1010
TimingGraphBuilder(const AtomNetlist& netlist,
1111
AtomLookup& netlist_lookup);
1212

13-
std::unique_ptr<tatum::TimingGraph> timing_graph();
13+
std::unique_ptr<tatum::TimingGraph> timing_graph(bool allow_dangling_combinational_nodes);
1414

1515
private:
16-
void build();
16+
void build(bool allow_dangling_combinational_nodes);
1717
void opt_memory_layout();
1818

1919
void add_io_to_timing_graph(const AtomBlockId blk);

vpr/src/timing/timing_util.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,10 @@ float calc_relaxed_criticality(const std::map<DomainPair, float>& domains_max_re
571571
max_req += shift;
572572
}
573573

574+
if (!std::isfinite(slack)) {
575+
continue;
576+
}
577+
574578
float crit = std::numeric_limits<float>::quiet_NaN();
575579
if (max_req > 0.) {
576580
//Standard case

0 commit comments

Comments
 (0)