Merge pull request #217 from YosysHQ/timingfixes
[timing] Path related fixes
This commit is contained in:
commit
6cc1bfcb37
@ -267,8 +267,7 @@ struct Timing
|
||||
auto net_delay = net_delays ? ctx->getNetinfoRouteDelay(net, usr) : delay_t();
|
||||
auto usr_arrival = net_arrival + net_delay;
|
||||
|
||||
if (portClass == TMG_REGISTER_INPUT || portClass == TMG_ENDPOINT || portClass == TMG_IGNORE ||
|
||||
portClass == TMG_CLOCK_INPUT) {
|
||||
if (portClass == TMG_ENDPOINT || portClass == TMG_IGNORE || portClass == TMG_CLOCK_INPUT) {
|
||||
// Skip
|
||||
} else {
|
||||
auto budget_override = ctx->getBudgetOverride(net, usr, net_delay);
|
||||
|
@ -866,6 +866,17 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||
{
|
||||
if (cell->type == id_ICESTORM_LC && cell->lcInfo.dffEnable) {
|
||||
if (toPort == id_O)
|
||||
return false;
|
||||
} else if (cell->type == id_ICESTORM_RAM || cell->type == id_ICESTORM_SPRAM) {
|
||||
return false;
|
||||
}
|
||||
return getCellDelayInternal(cell, fromPort, toPort, delay);
|
||||
}
|
||||
|
||||
bool Arch::getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||
{
|
||||
for (int i = 0; i < chip_info->num_timing_cells; i++) {
|
||||
const auto &tc = chip_info->cell_timing[i];
|
||||
@ -965,7 +976,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
|
||||
|
||||
return TMG_IGNORE;
|
||||
} 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 || port == id_PLLOUT_A_GLOBAL || port == id_PLLOUT_B_GLOBAL)
|
||||
return TMG_GEN_CLOCK;
|
||||
return TMG_IGNORE;
|
||||
} else if (cell->type == id_ICESTORM_LFOSC) {
|
||||
@ -1001,10 +1012,23 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
||||
info.clock_port = id_CLK;
|
||||
info.edge = cell->lcInfo.negClk ? FALLING_EDGE : RISING_EDGE;
|
||||
if (port == id_O) {
|
||||
bool has_clktoq = getCellDelay(cell, id_CLK, id_O, info.clockToQ);
|
||||
bool has_clktoq = getCellDelayInternal(cell, id_CLK, id_O, info.clockToQ);
|
||||
NPNR_ASSERT(has_clktoq);
|
||||
} else {
|
||||
if (port == id_I0 || port == id_I1 || port == id_I2 || port == id_I3) {
|
||||
DelayInfo dlut;
|
||||
bool has_ld = getCellDelayInternal(cell, port, id_O, dlut);
|
||||
NPNR_ASSERT(has_ld);
|
||||
if (args.type == ArchArgs::LP1K || args.type == ArchArgs::LP8K || args.type == ArchArgs::LP384) {
|
||||
info.setup.delay = 30 + dlut.delay;
|
||||
} else if (args.type == ArchArgs::UP5K) {
|
||||
info.setup.delay = dlut.delay - 50;
|
||||
} else {
|
||||
info.setup.delay = 20 + dlut.delay;
|
||||
}
|
||||
} else {
|
||||
info.setup.delay = 100;
|
||||
}
|
||||
info.hold.delay = 0;
|
||||
}
|
||||
} else if (cell->type == id_ICESTORM_RAM) {
|
||||
@ -1016,7 +1040,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
||||
info.edge = bool_or_default(cell->params, id("NEG_CLK_W")) ? FALLING_EDGE : RISING_EDGE;
|
||||
}
|
||||
if (cell->ports.at(port).type == PORT_OUT) {
|
||||
bool has_clktoq = getCellDelay(cell, info.clock_port, port, info.clockToQ);
|
||||
bool has_clktoq = getCellDelayInternal(cell, info.clock_port, port, info.clockToQ);
|
||||
NPNR_ASSERT(has_clktoq);
|
||||
} else {
|
||||
info.setup.delay = 100;
|
||||
@ -1061,7 +1085,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
||||
info.clock_port = cell->type == id_ICESTORM_SPRAM ? id_CLOCK : id_CLK;
|
||||
info.edge = RISING_EDGE;
|
||||
if (cell->ports.at(port).type == PORT_OUT) {
|
||||
bool has_clktoq = getCellDelay(cell, info.clock_port, port, info.clockToQ);
|
||||
bool has_clktoq = getCellDelayInternal(cell, info.clock_port, port, info.clockToQ);
|
||||
if (!has_clktoq)
|
||||
info.clockToQ.delay = 100;
|
||||
} else {
|
||||
|
@ -841,8 +841,11 @@ struct Arch : BaseCtx
|
||||
// -------------------------------------------------
|
||||
|
||||
// Get the delay through a cell from one port to another, returning false
|
||||
// if no path exists
|
||||
// if no path exists. This only considers combinational delays, as required by the Arch API
|
||||
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const;
|
||||
// getCellDelayInternal is similar to the above, but without false path checks and including clock to out delays
|
||||
// for internal arch use only
|
||||
bool getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const;
|
||||
// Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port
|
||||
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const;
|
||||
// Get the TimingClockingInfo of a port
|
||||
|
Loading…
Reference in New Issue
Block a user