Code cleanup

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
Maciej Kurc 2022-08-31 14:31:24 +02:00
parent 60a6e8b070
commit 1f1bae3e23
2 changed files with 37 additions and 66 deletions

View File

@ -254,7 +254,6 @@ void TimingAnalyser::setup_port_domains()
copy_domains(port, CellPortKey(pi.net->driver), true); copy_domains(port, CellPortKey(pi.net->driver), true);
} }
} }
// Iterate over ports and find domain paris // Iterate over ports and find domain paris
for (auto port : topological_order) { for (auto port : topological_order) {
auto &pd = ports.at(port); auto &pd = ports.at(port);
@ -296,8 +295,8 @@ void TimingAnalyser::identify_related_domains() {
// For each clock net identify all nets that can possibly drive it. Compute // For each clock net identify all nets that can possibly drive it. Compute
// cumulative delays to each of them. // cumulative delays to each of them.
std::function<void(const NetInfo*, dict<IdString, delay_t>&, delay_t, int32_t)> find_net_drivers = std::function<void(const NetInfo*, dict<IdString, delay_t>&, delay_t)> find_net_drivers =
[&] (const NetInfo* ni, dict<IdString, delay_t>& drivers, delay_t delay_acc, int32_t level) [&] (const NetInfo* ni, dict<IdString, delay_t>& drivers, delay_t delay_acc)
{ {
// Get driving cell and port // Get driving cell and port
const CellInfo* cell = ni->driver.cell; const CellInfo* cell = ni->driver.cell;
@ -305,30 +304,14 @@ void TimingAnalyser::identify_related_domains() {
bool didGoUpstream = false; bool didGoUpstream = false;
std::string indent (level, ' ');
log("%sout %s.%s\n", indent.c_str(), cell->name.str(ctx).c_str(), port.str(ctx).c_str());
// The cell has only one port // The cell has only one port
if (cell->ports.size() == 1) { if (cell->ports.size() == 1) {
drivers[ni->name] = delay_acc; drivers[ni->name] = delay_acc;
return; return;
} }
// Count cell port types
size_t num_inp = 0;
size_t num_out = 0;
for (const auto& it : cell->ports) {
const auto& pi = it.second;
if (pi.type != PORT_IN) {
num_inp++;
} else {
num_out++;
}
}
// Get the driver timing class // Get the driver timing class
int info_count = 0; int info_count = 0;
auto timing_class = ctx->getPortTimingClass(cell, port, info_count); auto timing_class = ctx->getPortTimingClass(cell, port, info_count);
// The driver must be a combinational output // The driver must be a combinational output
@ -361,16 +344,13 @@ void TimingAnalyser::identify_related_domains() {
continue; continue;
} }
log("%sinp %s.%s\n", indent.c_str(), cell->name.str(ctx).c_str(), pi.name.str(ctx).c_str());
// Recurse // Recurse
find_net_drivers(pi.net, drivers, delay_acc + delay.maxDelay(), level+1); find_net_drivers(pi.net, drivers, delay_acc + delay.maxDelay());
didGoUpstream = true; didGoUpstream = true;
} }
// Did not propagate upstream through the cell, mark the net as driver // Did not propagate upstream through the cell, mark the net as driver
if (!didGoUpstream) { if (!didGoUpstream) {
log("%send %s\n", indent.c_str(), ni->name.str(ctx).c_str());
drivers[ni->name] = delay_acc; drivers[ni->name] = delay_acc;
} }
}; };
@ -381,21 +361,28 @@ void TimingAnalyser::identify_related_domains() {
const NetInfo* ni = ctx->nets.at(domain.key.clock).get(); const NetInfo* ni = ctx->nets.at(domain.key.clock).get();
dict<IdString, delay_t> drivers; dict<IdString, delay_t> drivers;
find_net_drivers(ni, drivers, 0, 0); find_net_drivers(ni, drivers, 0);
clock_drivers[domain.key.clock] = drivers; clock_drivers[domain.key.clock] = drivers;
log("Clock '%s' can be driven by:\n", domain.key.clock.str(ctx).c_str()); if (ctx->debug) {
for (const auto& it : drivers) { log("Clock '%s' can be driven by:\n", domain.key.clock.str(ctx).c_str());
log(" net '%s' delay %.3fns\n", it.first.str(ctx).c_str(), ctx->getDelayNS(it.second)); for (const auto& it : drivers) {
const NetInfo* net = ctx->nets.at(it.first).get();
log(" %s.%s delay %.3fns\n",
net->driver.cell->name.str(ctx).c_str(),
net->driver.port.str(ctx).c_str(),
ctx->getDelayNS(it.second)
);
}
} }
} }
// Identify related clocks // Identify related clocks. For simplicity do it both for A->B and B->A
// cases.
for (const auto& c1 : clock_drivers) { for (const auto& c1 : clock_drivers) {
for (const auto& c2 : clock_drivers) { for (const auto& c2 : clock_drivers) {
// Evident?
if (c1 == c2) { if (c1 == c2) {
continue; continue;
} }
@ -417,28 +404,25 @@ void TimingAnalyser::identify_related_domains() {
} }
} }
// DEBUG // if (ctx->debug) {
log("Clocks '%s' and '%s'\n", c1.first.str(ctx).c_str(), c2.first.str(ctx).c_str());
for (const auto& it : common_drivers) {
// TEST // log("Possible common driver(s) for clocks '%s' and '%s'\n",
const NetInfo* ni = ctx->nets.at(it).get(); c1.first.str(ctx).c_str(), c2.first.str(ctx).c_str());
const CellInfo* cell = ni->driver.cell;
const IdString port = ni->driver.port;
int info_count; for (const auto& it : common_drivers) {
auto timing_class = ctx->getPortTimingClass(cell, port, info_count);
// TEST //
log(" net '%s', cell %s (%s), port %s, class%d\n", const NetInfo* ni = ctx->nets.at(it).get();
it.str(ctx).c_str(), const CellInfo* cell = ni->driver.cell;
cell->name.str(ctx).c_str(), const IdString port = ni->driver.port;
cell->type.str(ctx).c_str(),
port.str(ctx).c_str(), log(" net '%s', cell %s (%s), port %s\n",
int(timing_class) it.str(ctx).c_str(),
); cell->name.str(ctx).c_str(),
cell->type.str(ctx).c_str(),
port.str(ctx).c_str()
);
}
} }
// DEBUG //
// If there is no single driver then consider the two clocks // If there is no single driver then consider the two clocks
// unrelated. // unrelated.
@ -1417,7 +1401,6 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
dict<IdString, CriticalPath> clock_reports; dict<IdString, CriticalPath> clock_reports;
std::vector<CriticalPath> xclock_reports; std::vector<CriticalPath> xclock_reports;
dict<IdString, ClockFmax> clock_fmax; dict<IdString, ClockFmax> clock_fmax;
dict<std::pair<IdString, IdString>, ClockFmax> xclock_fmax;
std::set<IdString> empty_clocks; // set of clocks with no interior paths std::set<IdString> empty_clocks; // set of clocks with no interior paths
if (report_critical_paths) { if (report_critical_paths) {
@ -1453,18 +1436,6 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
if (a.clock == b.clock && a.clock != ctx->id("$async$")) if (a.clock == b.clock && a.clock != ctx->id("$async$"))
continue; continue;
double Fmax;
if (a.edge == b.edge)
Fmax = 1000 / ctx->getDelayNS(path.second.path_delay);
else
Fmax = 500 / ctx->getDelayNS(path.second.path_delay);
auto key = std::make_pair(a.clock, b.clock);
if (!xclock_fmax.count(key) || Fmax < xclock_fmax.at(key).achieved) {
xclock_fmax[key].achieved = Fmax;
xclock_fmax[key].constraint = 0.0f; // Will be filled later
}
auto &crit_path = crit_paths.at(path.first).ports; auto &crit_path = crit_paths.at(path.first).ports;
xclock_reports.push_back(build_critical_path_report(ctx, path.first, crit_path)); xclock_reports.push_back(build_critical_path_report(ctx, path.first, crit_path));
xclock_reports.back().period = path.second.path_period; xclock_reports.back().period = path.second.path_period;

View File

@ -495,10 +495,10 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
} else if (cell->type == id_DCC) { } else if (cell->type == id_DCC) {
if (fromPort == id_CLKI && toPort == id_CLKO) { if (fromPort == id_CLKI && toPort == id_CLKO) {
// TODO: Use actual DCC delays // TODO: Use actual DCC delays
delay.rise.min_delay = 1000; delay.rise.min_delay = 1;
delay.rise.max_delay = 1000; delay.rise.max_delay = 1;
delay.fall.min_delay = 1000; delay.fall.min_delay = 1;
delay.fall.max_delay = 1000; delay.fall.max_delay = 1;
return true; return true;
} }
} }