Skip to content

Commit 0f14bd9

Browse files
authored
Merge branch 'master' into openfpga
2 parents cab1db1 + d5dc5f7 commit 0f14bd9

File tree

3 files changed

+85
-45
lines changed

3 files changed

+85
-45
lines changed

vpr/src/base/SetupGrid.h

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ DeviceGrid create_device_grid(const std::string& layout_name,
2525

2626
DeviceGrid create_device_grid(const std::string& layout_name, const std::vector<t_grid_def>& grid_layouts, size_t min_width, size_t min_height);
2727

28+
2829
/**
2930
* @brief Returns the effective size of the device
3031
* (size of the bounding box of non-empty grid tiles)

vpr/src/pack/prepack.cpp

+71-45
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,11 @@ static void init_molecule_chain_info(const AtomBlockId blk_id,
107107
const AtomNetlist& atom_nlist);
108108

109109
static AtomBlockId get_sink_block(const AtomBlockId block_id,
110-
const t_model_ports* model_port,
111-
const BitIndex pin_number,
110+
const t_pack_pattern_connections& connections,
112111
const AtomNetlist& atom_nlist);
113112

114113
static AtomBlockId get_driving_block(const AtomBlockId block_id,
115-
const t_model_ports* model_port,
116-
const BitIndex pin_number,
114+
const t_pack_pattern_connections& connections,
117115
const AtomNetlist& atom_nlist);
118116

119117
static void print_chain_starting_points(t_pack_patterns* chain_pattern);
@@ -1047,17 +1045,13 @@ static bool try_expand_molecule(t_pack_molecule& molecule,
10471045
// this block is the driver of this connection
10481046
if (block_connection->from_block == pattern_block) {
10491047
// find the block this connection is driving and add it to the queue
1050-
auto port_model = block_connection->from_pin->port->model_port;
1051-
auto ipin = block_connection->from_pin->pin_number;
1052-
auto sink_blk_id = get_sink_block(block_id, port_model, ipin, atom_nlist);
1048+
auto sink_blk_id = get_sink_block(block_id, *block_connection, atom_nlist);
10531049
// add this sink block id with its corresponding pattern block to the queue
10541050
pattern_block_queue.push(std::make_pair(block_connection->to_block, sink_blk_id));
10551051
// this block is being driven by this connection
10561052
} else if (block_connection->to_block == pattern_block) {
10571053
// find the block that is driving this connection and it to the queue
1058-
auto port_model = block_connection->to_pin->port->model_port;
1059-
auto ipin = block_connection->to_pin->pin_number;
1060-
auto driver_blk_id = get_driving_block(block_id, port_model, ipin, atom_nlist);
1054+
auto driver_blk_id = get_driving_block(block_id, *block_connection, atom_nlist);
10611055
// add this driver block id with its corresponding pattern block to the queue
10621056
pattern_block_queue.push(std::make_pair(block_connection->from_block, driver_blk_id));
10631057
}
@@ -1076,62 +1070,94 @@ static bool try_expand_molecule(t_pack_molecule& molecule,
10761070
/**
10771071
* Find the atom block in the netlist driven by this pin of the input atom block
10781072
* If doesn't exist return AtomBlockId::INVALID()
1079-
* Limitation: The block should be driving only one sink block
1073+
* TODO: Limitation — For pack patterns other than chains,
1074+
* the block should be driven by only one block
10801075
* block_id : id of the atom block that is driving the net connected to the sink block
1081-
* model_port : the model of the port driving the net
1082-
* pin_number : the pin_number of the pin driving the net (pin index within the port)
1076+
* connections : pack pattern connections from the given block
10831077
*/
10841078
static AtomBlockId get_sink_block(const AtomBlockId block_id,
1085-
const t_model_ports* model_port,
1086-
const BitIndex pin_number,
1079+
const t_pack_pattern_connections& connections,
10871080
const AtomNetlist& atom_nlist) {
1088-
auto port_id = atom_nlist.find_atom_port(block_id, model_port);
1089-
1090-
if (port_id) {
1091-
auto net_id = atom_nlist.port_net(port_id, pin_number);
1092-
if (net_id && atom_nlist.net_sinks(net_id).size() == 1) { /* Single fanout assumption */
1093-
auto net_sinks = atom_nlist.net_sinks(net_id);
1094-
auto sink_pin_id = *(net_sinks.begin());
1095-
return atom_nlist.pin_block(sink_pin_id);
1096-
}
1081+
const t_model_ports* from_port_model = connections.from_pin->port->model_port;
1082+
const int from_pin_number = connections.from_pin->pin_number;
1083+
auto from_port_id = atom_nlist.find_atom_port(block_id, from_port_model);
1084+
1085+
const t_model_ports* to_port_model = connections.to_pin->port->model_port;
1086+
const int to_pin_number = connections.to_pin->pin_number;
1087+
const auto& to_pb_type = connections.to_block->pb_type;
1088+
1089+
if (!from_port_id.is_valid()) {
1090+
return AtomBlockId::INVALID();
10971091
}
10981092

1099-
return AtomBlockId::INVALID();
1093+
auto net_id = atom_nlist.port_net(from_port_id, from_pin_number);
1094+
if (!net_id.is_valid()) {
1095+
return AtomBlockId::INVALID();
1096+
}
1097+
1098+
const auto& net_sinks = atom_nlist.net_sinks(net_id);
1099+
// Iterate through all sink blocks and check whether any of them
1100+
// is compatible with the block specified in the pack pattern.
1101+
bool connected_to_latch = false;
1102+
AtomBlockId pattern_sink_block_id = AtomBlockId::INVALID();
1103+
for (const auto& sink_pin_id : net_sinks) {
1104+
auto sink_block_id = atom_nlist.pin_block(sink_pin_id);
1105+
if (atom_nlist.block_model(sink_block_id)->name == std::string(MODEL_LATCH)) {
1106+
connected_to_latch = true;
1107+
}
1108+
if (primitive_type_feasible(sink_block_id, to_pb_type)) {
1109+
auto to_port_id = atom_nlist.find_atom_port(sink_block_id, to_port_model);
1110+
auto to_pin_id = atom_nlist.find_pin(to_port_id, BitIndex(to_pin_number));
1111+
if (to_pin_id == sink_pin_id) {
1112+
pattern_sink_block_id = sink_block_id;
1113+
}
1114+
}
1115+
}
1116+
// If the number of sinks is greater than 1, and one of the connected blocks is a latch,
1117+
// then we drop the block to avoid a situation where only registers or unregistered output
1118+
// of the block can use the output pin.
1119+
// TODO: This is a conservative assumption, and ideally we need to do analysis of the architecture
1120+
// before to determine which pattern is supported by the architecture.
1121+
if (connected_to_latch && net_sinks.size() > 1) {
1122+
pattern_sink_block_id = AtomBlockId::INVALID();
1123+
}
1124+
return pattern_sink_block_id;
11001125
}
11011126

11021127
/**
11031128
* Find the atom block in the netlist driving this pin of the input atom block
11041129
* If doesn't exist return AtomBlockId::INVALID()
11051130
* Limitation: This driving block should be driving only the input block
11061131
* block_id : id of the atom block that is connected to a net driven by the driving block
1107-
* model_port : the model of the port driven by the net
1108-
* pin_number : the pin_number of the pin driven by the net (pin index within the port)
1132+
* connections : pack pattern connections from the given block
11091133
*/
11101134
static AtomBlockId get_driving_block(const AtomBlockId block_id,
1111-
const t_model_ports* model_port,
1112-
const BitIndex pin_number,
1135+
const t_pack_pattern_connections& connections,
11131136
const AtomNetlist& atom_nlist) {
1114-
auto port_id = atom_nlist.find_atom_port(block_id, model_port);
1115-
1116-
if (port_id) {
1117-
auto net_id = atom_nlist.port_net(port_id, pin_number);
1118-
if (net_id && atom_nlist.net_sinks(net_id).size() == 1) { /* Single fanout assumption */
1137+
auto to_port_model = connections.to_pin->port->model_port;
1138+
auto to_pin_number = connections.to_pin->pin_number;
1139+
auto to_port_id = atom_nlist.find_atom_port(block_id, to_port_model);
11191140

1120-
auto driver_blk_id = atom_nlist.net_driver_block(net_id);
1141+
if (!to_port_id.is_valid()) {
1142+
return AtomBlockId::INVALID();
1143+
}
11211144

1122-
if (model_port->is_clock) {
1123-
auto driver_blk_type = atom_nlist.block_type(driver_blk_id);
1145+
auto net_id = atom_nlist.port_net(to_port_id, to_pin_number);
1146+
if (net_id && atom_nlist.net_sinks(net_id).size() == 1) { /* Single fanout assumption */
1147+
auto driver_blk_id = atom_nlist.net_driver_block(net_id);
11241148

1125-
// TODO: support multi-clock primitives.
1126-
// If the driver block is a .input block, this assertion should not
1127-
// be triggered as the sink block might have only one input pin, which
1128-
// would be a clock pin in case the sink block primitive is a clock generator,
1129-
// resulting in a pin_number == 0.
1130-
VTR_ASSERT(pin_number == 1 || (pin_number == 0 && driver_blk_type == AtomBlockType::INPAD));
1131-
}
1149+
if (to_port_model->is_clock) {
1150+
auto driver_blk_type = atom_nlist.block_type(driver_blk_id);
11321151

1133-
return atom_nlist.net_driver_block(net_id);
1152+
// TODO: support multi-clock primitives.
1153+
// If the driver block is a .input block, this assertion should not
1154+
// be triggered as the sink block might have only one input pin, which
1155+
// would be a clock pin in case the sink block primitive is a clock generator,
1156+
// resulting in a pin_number == 0.
1157+
VTR_ASSERT(to_pin_number == 1 || (to_pin_number == 0 && driver_blk_type == AtomBlockType::INPAD));
11341158
}
1159+
1160+
return driver_blk_id;
11351161
}
11361162

11371163
return AtomBlockId::INVALID();

vpr/src/route/rr_graph.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ static void alloc_rr_switch_inf(RRGraphBuilder& rr_graph_builder,
568568
t_arch_switch_fanin& arch_switch_fanins,
569569
const std::map<int, t_arch_switch_inf>& arch_sw_map);
570570

571+
571572
static std::vector<t_seg_details> alloc_and_load_global_route_seg_details(const int global_route_switch);
572573

573574
static RRNodeId pick_best_direct_connect_target_rr_node(const RRGraphView& rr_graph,
@@ -827,6 +828,18 @@ void create_rr_graph(e_graph_type graph_type,
827828
// Remember the loaded filename to avoid reloading it before the RR graph is cleared.
828829
mutable_device_ctx.loaded_rr_edge_override_filename = det_routing_arch->read_rr_edge_override_filename;
829830
}
831+
832+
// Check if there is an edge override file to read and that it is not already loaded.
833+
if (!det_routing_arch->read_rr_edge_override_filename.empty()
834+
&& det_routing_arch->read_rr_edge_override_filename != device_ctx.loaded_rr_edge_override_filename) {
835+
836+
load_rr_edge_delay_overrides(det_routing_arch->read_rr_edge_override_filename,
837+
mutable_device_ctx.rr_graph_builder,
838+
device_ctx.rr_graph);
839+
840+
// Remember the loaded filename to avoid reloading it before the RR graph is cleared.
841+
mutable_device_ctx.loaded_rr_edge_override_filename = det_routing_arch->read_rr_edge_override_filename;
842+
}
830843
}
831844

832845
if (is_flat) {

0 commit comments

Comments
 (0)