-
Notifications
You must be signed in to change notification settings - Fork 404
/
Copy pathclb_delay_calc.inl
116 lines (82 loc) · 4.28 KB
/
clb_delay_calc.inl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "clb_delay_calc.h"
#include "globals.h"
/*
* ClbDelayCalc
*/
inline ClbDelayCalc::ClbDelayCalc()
: intra_lb_pb_pin_lookup_(g_vpr_ctx.device().logical_block_types) {}
inline float ClbDelayCalc::clb_input_to_internal_sink_delay(const ClusterBlockId block_id, const int pin_index, int internal_sink_pin, DelayType delay_type) const {
return trace_delay(block_id, pin_index, internal_sink_pin, delay_type);
}
inline float ClbDelayCalc::internal_src_to_clb_output_delay(const ClusterBlockId block_id, const int pin_index, int internal_src_pin, DelayType delay_type) const {
return trace_delay(block_id, internal_src_pin, pin_index, delay_type);
}
inline float ClbDelayCalc::internal_src_to_internal_sink_delay(const ClusterBlockId clb, int internal_src_pin, int internal_sink_pin, DelayType delay_type) const {
return trace_delay(clb, internal_src_pin, internal_sink_pin, delay_type);
}
inline float ClbDelayCalc::trace_delay(ClusterBlockId clb, int src_pb_route_id, int sink_pb_route_id, DelayType delay_type) const {
const auto& cluster_ctx = g_vpr_ctx.clustering();
VTR_ASSERT(src_pb_route_id < cluster_ctx.clb_nlist.block_pb(clb)->pb_graph_node->total_pb_pins);
VTR_ASSERT(sink_pb_route_id < cluster_ctx.clb_nlist.block_pb(clb)->pb_graph_node->total_pb_pins);
const auto& pb_routes = cluster_ctx.clb_nlist.block_pb(clb)->pb_route;
VTR_ASSERT_SAFE(pb_routes.count(src_pb_route_id));
AtomNetId atom_net = pb_routes[src_pb_route_id].atom_net_id;
VTR_ASSERT_MSG(atom_net, "Source pin must be connected to a valid net");
VTR_ASSERT_MSG(atom_net == pb_routes[sink_pb_route_id].atom_net_id, "Source pin and sink pin must connect to the same net");
float delay = 0.;
//Trace back the internal routing from the sink to the source pin
int curr_pb_route_id = sink_pb_route_id;
while(pb_routes[curr_pb_route_id].driver_pb_pin_id >= 0) {
VTR_ASSERT_MSG(atom_net == pb_routes[curr_pb_route_id].atom_net_id, "Internal routing must connect the same net");
delay += pb_route_delay(clb, curr_pb_route_id, delay_type);
curr_pb_route_id = pb_routes[curr_pb_route_id].driver_pb_pin_id;
}
VTR_ASSERT_MSG(curr_pb_route_id == src_pb_route_id, "Sink pin should trace back to source pin");
return delay;
}
inline float ClbDelayCalc::pb_route_delay(ClusterBlockId clb, int pb_route_idx, DelayType delay_type) const {
const t_pb_graph_edge* pb_edge = find_pb_graph_edge(clb, pb_route_idx);
if(pb_edge) {
if (delay_type == DelayType::MAX) {
return pb_edge->delay_max;
} else {
VTR_ASSERT(delay_type == DelayType::MIN);
return pb_edge->delay_min;
}
} else {
return 0.;
}
}
inline const t_pb_graph_edge* ClbDelayCalc::find_pb_graph_edge(ClusterBlockId clb, int pb_route_idx) const {
auto& cluster_ctx = g_vpr_ctx.clustering();
int type_index = cluster_ctx.clb_nlist.block_type(clb)->index;
const t_pb* pb = cluster_ctx.clb_nlist.block_pb(clb);
if (pb->pb_route.count(pb_route_idx)) {
int upstream_pb_route_idx = pb->pb_route[pb_route_idx].driver_pb_pin_id;
if(upstream_pb_route_idx >= 0) {
const t_pb_graph_pin* pb_gpin = intra_lb_pb_pin_lookup_.pb_gpin(type_index, pb_route_idx);
const t_pb_graph_pin* upstream_pb_gpin = intra_lb_pb_pin_lookup_.pb_gpin(type_index, upstream_pb_route_idx);
return find_pb_graph_edge(upstream_pb_gpin, pb_gpin);
}
}
return nullptr;
}
inline const t_pb_graph_edge* ClbDelayCalc::find_pb_graph_edge(const t_pb_graph_pin* driver, const t_pb_graph_pin* sink) const {
VTR_ASSERT(driver);
VTR_ASSERT(sink);
const t_pb_graph_edge* pb_edge = nullptr;
for(int iedge = 0; iedge < driver->num_output_edges; ++iedge) {
const t_pb_graph_edge* check_edge = driver->output_edges[iedge];
VTR_ASSERT(check_edge);
VTR_ASSERT(check_edge->num_output_pins == 1);
if(check_edge->output_pins[0] == sink) {
pb_edge = check_edge;
}
}
if (!pb_edge) {
std::string conkt_debug_message = "Should find pb_graph_edge connecting PB pins from " + driver->to_string() + " to " + sink->to_string() + "!\n";
VTR_ASSERT_MSG(pb_edge,
conkt_debug_message.c_str());
}
return pb_edge;
}