@@ -1355,7 +1355,7 @@ std::set<AtomNetId> find_netlist_physical_clock_nets(const AtomNetlist& netlist)
1355
1355
return clock_nets;
1356
1356
}
1357
1357
1358
- // Finds all logical clock drivers in the netlist (by back-tracing through logic)
1358
+ // Finds all logical clock drivers in the netlist
1359
1359
std::set<AtomPinId> find_netlist_logical_clock_drivers (const AtomNetlist& netlist) {
1360
1360
auto clock_nets = find_netlist_physical_clock_nets (netlist);
1361
1361
@@ -1364,53 +1364,28 @@ std::set<AtomPinId> find_netlist_logical_clock_drivers(const AtomNetlist& netlis
1364
1364
// However, some of them may be the same logical clock (e.g. if there are
1365
1365
// buffers between them). Here we trace-back through any clock buffers
1366
1366
// to find the true source
1367
- size_t assumed_buffer_count = 0 ;
1368
1367
std::set<AtomNetId> prev_clock_nets;
1369
1368
while (prev_clock_nets != clock_nets) { // Still tracing back
1370
1369
prev_clock_nets = clock_nets;
1371
1370
clock_nets.clear ();
1372
1371
1373
1372
for (auto clk_net : prev_clock_nets) {
1374
- AtomPinId driver_pin = netlist.net_driver (clk_net);
1375
- AtomPortId driver_port = netlist.pin_port (driver_pin);
1373
+ auto driver_block = netlist.net_driver_block (clk_net);
1376
1374
1377
- std::vector<AtomPortId> upstream_ports = find_combinationally_connected_input_ports (netlist, driver_port);
1375
+ if (is_buffer (netlist, driver_block)) {
1376
+ // Driver is a buffer lut, use it's input net
1377
+ auto input_pins = netlist.block_input_pins (driver_block);
1378
+ VTR_ASSERT (input_pins.size () == 1 );
1379
+ auto input_pin = *input_pins.begin ();
1378
1380
1379
- if (upstream_ports.empty ()) {
1380
- // This net is a root net of a clock, keep it
1381
- clock_nets.insert (clk_net);
1381
+ auto input_net = netlist.pin_net (input_pin);
1382
+ clock_nets.insert (input_net);
1382
1383
} else {
1383
- // Trace the clock back through any combinational logic
1384
- //
1385
- // We are assuming that the combinational connections are independent and non-inverting.
1386
- // If this is not the case, it is up to the end-user to specify the clocks explicitly
1387
- // at the intermediate pins in the netlist.
1388
- for (AtomPortId upstream_port : upstream_ports) {
1389
- for (AtomPinId upstream_pin : netlist.port_pins (upstream_port)) {
1390
- AtomNetId upstream_net = netlist.pin_net (upstream_pin);
1391
-
1392
- VTR_ASSERT (upstream_net);
1393
-
1394
- AtomBlockId driver_blk = netlist.port_block (driver_port);
1395
- VTR_LOG_WARN (" Assuming clocks may propagate through %s (%s) from pin %s to %s (assuming a non-inverting buffer).\n " ,
1396
- netlist.block_name (driver_blk).c_str (), netlist.block_model (driver_blk)->name ,
1397
- netlist.pin_name (upstream_pin).c_str (), netlist.pin_name (driver_pin).c_str ());
1398
-
1399
- clock_nets.insert (upstream_net);
1400
- ++assumed_buffer_count;
1401
- }
1402
- }
1384
+ clock_nets.insert (clk_net);
1403
1385
}
1404
1386
}
1405
1387
}
1406
1388
1407
- if (assumed_buffer_count > 0 ) {
1408
- VTR_LOG_WARN (
1409
- " Assumed %zu netlist logic connections may be clock buffers. "
1410
- " To override this behaviour explicitly create clocks at the appropriate netlist pins.\n " ,
1411
- assumed_buffer_count);
1412
- }
1413
-
1414
1389
// Extract the net drivers
1415
1390
std::set<AtomPinId> clock_drivers;
1416
1391
for (auto net : clock_nets) {
0 commit comments