timing: Update to new use API (currently broken)
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
bf42e525cb
commit
d8b3830031
@ -84,20 +84,20 @@ struct Timing
|
|||||||
input_ports.push_back(port.first);
|
input_ports.push_back(port.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_io = ctx->isIOCell(cell.second.get());
|
|
||||||
for (auto o : output_ports) {
|
for (auto o : output_ports) {
|
||||||
IdString clock_domain = ctx->getPortClock(cell.second.get(), o->name);
|
IdString clockPort;
|
||||||
|
TimingPortClass portClass = ctx->getPortTimingClass(cell.second.get(), o->name, clockPort);
|
||||||
// If output port is influenced by a clock (e.g. FF output)
|
// If output port is influenced by a clock (e.g. FF output)
|
||||||
// then add it to the ordering as a timing start-point
|
// then add it to the ordering as a timing start-point
|
||||||
if (clock_domain != IdString()) {
|
if (portClass == TMG_REGISTER_OUTPUT) {
|
||||||
DelayInfo clkToQ;
|
DelayInfo clkToQ;
|
||||||
ctx->getCellDelay(cell.second.get(), clock_domain, o->name, clkToQ);
|
ctx->getCellDelay(cell.second.get(), clockPort, o->name, clkToQ);
|
||||||
topographical_order.emplace_back(o->net);
|
topographical_order.emplace_back(o->net);
|
||||||
net_data.emplace(o->net, TimingData{clkToQ.maxDelay()});
|
net_data.emplace(o->net, TimingData{clkToQ.maxDelay()});
|
||||||
} else {
|
} else {
|
||||||
// Also add I/O cells too
|
// Also add I/O cells too
|
||||||
// TODO(eddieh): More generic way of detecting PLLs
|
// TODO(eddieh): More generic way of detecting PLLs
|
||||||
if (is_io || cell.second->type == ctx->id("ICESTORM_PLL")) {
|
if (portClass == TMG_STARTPOINT || portClass == TMG_IGNORE) { // IGNORE: ????
|
||||||
topographical_order.emplace_back(o->net);
|
topographical_order.emplace_back(o->net);
|
||||||
net_data.emplace(o->net, TimingData{});
|
net_data.emplace(o->net, TimingData{});
|
||||||
}
|
}
|
||||||
@ -137,12 +137,13 @@ struct Timing
|
|||||||
|
|
||||||
DelayInfo clkToQ;
|
DelayInfo clkToQ;
|
||||||
for (auto &usr : net->users) {
|
for (auto &usr : net->users) {
|
||||||
auto clock_domain = ctx->getPortClock(usr.cell, usr.port);
|
IdString clockPort;
|
||||||
|
TimingPortClass portClass = ctx->getPortTimingClass(usr.cell, usr.port, clockPort);
|
||||||
for (auto &port : usr.cell->ports) {
|
for (auto &port : usr.cell->ports) {
|
||||||
if (port.second.type != PORT_OUT || !port.second.net)
|
if (port.second.type != PORT_OUT || !port.second.net)
|
||||||
continue;
|
continue;
|
||||||
// Skip if this is a clocked output (but allow non-clocked ones)
|
// Skip if this is a clocked output (but allow non-clocked ones)
|
||||||
if (clock_domain != IdString() && ctx->getCellDelay(usr.cell, clock_domain, port.first, clkToQ))
|
if (portClass == TMG_REGISTER_OUTPUT || portClass == TMG_ENDPOINT || portClass == TMG_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
DelayInfo comb_delay;
|
DelayInfo comb_delay;
|
||||||
bool is_path = ctx->getCellDelay(usr.cell, usr.port, port.first, comb_delay);
|
bool is_path = ctx->getCellDelay(usr.cell, usr.port, port.first, comb_delay);
|
||||||
@ -173,7 +174,9 @@ struct Timing
|
|||||||
const auto net_length_plus_one = nd.max_path_length + 1;
|
const auto net_length_plus_one = nd.max_path_length + 1;
|
||||||
nd.min_remaining_budget = clk_period;
|
nd.min_remaining_budget = clk_period;
|
||||||
for (auto &usr : net->users) {
|
for (auto &usr : net->users) {
|
||||||
if (ctx->getPortClock(usr.cell, usr.port) != IdString()) {
|
IdString clockPort;
|
||||||
|
TimingPortClass portClass = ctx->getPortTimingClass(usr.cell, usr.port, clockPort);
|
||||||
|
if (portClass == TMG_REGISTER_INPUT || portClass == TMG_ENDPOINT || portClass == TMG_IGNORE) {
|
||||||
} else {
|
} else {
|
||||||
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
|
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
|
||||||
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
|
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
|
||||||
@ -212,7 +215,9 @@ struct Timing
|
|||||||
for (auto &usr : net->users) {
|
for (auto &usr : net->users) {
|
||||||
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
|
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
|
||||||
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
|
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
|
||||||
if (ctx->getPortClock(usr.cell, usr.port) != IdString()) {
|
IdString associatedClock;
|
||||||
|
TimingPortClass portClass = ctx->getPortTimingClass(usr.cell, usr.port, associatedClock);
|
||||||
|
if (portClass == TMG_REGISTER_INPUT || portClass == TMG_ENDPOINT) {
|
||||||
const auto net_arrival = nd.max_arrival;
|
const auto net_arrival = nd.max_arrival;
|
||||||
auto path_budget = clk_period - (net_arrival + net_delay);
|
auto path_budget = clk_period - (net_arrival + net_delay);
|
||||||
if (update) {
|
if (update) {
|
||||||
@ -267,7 +272,10 @@ struct Timing
|
|||||||
if (!is_path)
|
if (!is_path)
|
||||||
continue;
|
continue;
|
||||||
// If input port is influenced by a clock, skip
|
// If input port is influenced by a clock, skip
|
||||||
if (ctx->getPortClock(crit_net->driver.cell, port.first) != IdString())
|
IdString portClock;
|
||||||
|
TimingPortClass portClass = ctx->getPortTimingClass(crit_net->driver.cell, port.first, portClock);
|
||||||
|
if (portClass == TMG_REGISTER_INPUT || portClass == TMG_CLOCK_INPUT || portClass == TMG_ENDPOINT ||
|
||||||
|
portClass == TMG_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// And find the fanin net with the latest arrival time
|
// And find the fanin net with the latest arrival time
|
||||||
@ -373,7 +381,9 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_path)
|
|||||||
auto &front = crit_path.front();
|
auto &front = crit_path.front();
|
||||||
auto &front_port = front->cell->ports.at(front->port);
|
auto &front_port = front->cell->ports.at(front->port);
|
||||||
auto &front_driver = front_port.net->driver;
|
auto &front_driver = front_port.net->driver;
|
||||||
auto last_port = ctx->getPortClock(front_driver.cell, front_driver.port);
|
|
||||||
|
IdString last_port;
|
||||||
|
ctx->getPortTimingClass(front_driver.cell, front_driver.port, last_port);
|
||||||
for (auto sink : crit_path) {
|
for (auto sink : crit_path) {
|
||||||
auto sink_cell = sink->cell;
|
auto sink_cell = sink->cell;
|
||||||
auto &port = sink_cell->ports.at(sink->port);
|
auto &port = sink_cell->ports.at(sink->port);
|
||||||
|
@ -29,7 +29,8 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent) : BaseMainWindow(std::move(context), args, parent)
|
MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent)
|
||||||
|
: BaseMainWindow(std::move(context), args, parent)
|
||||||
{
|
{
|
||||||
initMainResource();
|
initMainResource();
|
||||||
|
|
||||||
@ -50,7 +51,8 @@ void MainWindow::newContext(Context *ctx)
|
|||||||
setWindowTitle(title.c_str());
|
setWindowTitle(title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createMenu() {
|
void MainWindow::createMenu()
|
||||||
|
{
|
||||||
// Add arch specific actions
|
// Add arch specific actions
|
||||||
actionLoadBase = new QAction("Open Base Config", this);
|
actionLoadBase = new QAction("Open Base Config", this);
|
||||||
actionLoadBase->setIcon(QIcon(":/icons/resources/open_base.png"));
|
actionLoadBase->setIcon(QIcon(":/icons/resources/open_base.png"));
|
||||||
@ -96,8 +98,8 @@ static QStringList getSupportedPackages(ArchArgs::ArchArgsTypes chip)
|
|||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::new_proj()
|
||||||
void MainWindow::new_proj() {
|
{
|
||||||
QMap<QString, int> arch;
|
QMap<QString, int> arch;
|
||||||
arch.insert("Lattice ECP5 25K", ArchArgs::LFE5U_25F);
|
arch.insert("Lattice ECP5 25K", ArchArgs::LFE5U_25F);
|
||||||
arch.insert("Lattice ECP5 45K", ArchArgs::LFE5U_45F);
|
arch.insert("Lattice ECP5 45K", ArchArgs::LFE5U_45F);
|
||||||
|
@ -47,6 +47,7 @@ class MainWindow : public BaseMainWindow
|
|||||||
void newContext(Context *ctx);
|
void newContext(Context *ctx);
|
||||||
void open_base();
|
void open_base();
|
||||||
void save_config();
|
void save_config();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAction *actionLoadBase;
|
QAction *actionLoadBase;
|
||||||
QAction *actionSaveConfig;
|
QAction *actionSaveConfig;
|
||||||
|
@ -23,7 +23,8 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent) : BaseMainWindow(std::move(context), args, parent)
|
MainWindow::MainWindow(std::unique_ptr<Context> context, ArchArgs args, QWidget *parent)
|
||||||
|
: BaseMainWindow(std::move(context), args, parent)
|
||||||
{
|
{
|
||||||
initMainResource();
|
initMainResource();
|
||||||
|
|
||||||
|
@ -915,7 +915,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
|
|||||||
}
|
}
|
||||||
} else if (cell->type == id_icestorm_ram || cell->type == id("ICESTORM_DSP") ||
|
} else if (cell->type == id_icestorm_ram || cell->type == id("ICESTORM_DSP") ||
|
||||||
cell->type == id("ICESTORM_SPRAM")) {
|
cell->type == id("ICESTORM_SPRAM")) {
|
||||||
if (port == id_clk)
|
if (port == id_clk || port == id_rclk || port == id_wclk)
|
||||||
return TMG_CLOCK_INPUT;
|
return TMG_CLOCK_INPUT;
|
||||||
else if (cell->ports.at(port).type == PORT_OUT)
|
else if (cell->ports.at(port).type == PORT_OUT)
|
||||||
return TMG_REGISTER_OUTPUT;
|
return TMG_REGISTER_OUTPUT;
|
||||||
@ -925,7 +925,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
|
|||||||
if (port == id("D_IN_0") || port == id("D_IN_1"))
|
if (port == id("D_IN_0") || port == id("D_IN_1"))
|
||||||
return TMG_STARTPOINT;
|
return TMG_STARTPOINT;
|
||||||
if (port == id("D_OUT_0") || port == id("D_OUT_1"))
|
if (port == id("D_OUT_0") || port == id("D_OUT_1"))
|
||||||
return TMG_STARTPOINT;
|
return TMG_ENDPOINT;
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
} else if (cell->type == id("ICESTORM_PLL")) {
|
} else if (cell->type == id("ICESTORM_PLL")) {
|
||||||
if (port == id("PLLOUT_A") || port == id("PLLOUT_B"))
|
if (port == id("PLLOUT_A") || port == id("PLLOUT_B"))
|
||||||
|
Loading…
Reference in New Issue
Block a user