ecp5: Update arch to new timing API

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2018-11-04 14:51:48 +00:00
parent bd2b3e5e02
commit 8af86ff37d
3 changed files with 73 additions and 17 deletions

View File

@ -530,8 +530,7 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
Fmax = 1000 / ctx->getDelayNS(path.second.path_delay);
else
Fmax = 500 / ctx->getDelayNS(path.second.path_delay);
if (!clock_fmax.count(a.clock) ||
Fmax < clock_fmax.at(a.clock)) {
if (!clock_fmax.count(a.clock) || Fmax < clock_fmax.at(a.clock)) {
clock_reports[a.clock] = path;
clock_fmax[a.clock] = Fmax;
}

View File

@ -539,10 +539,10 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
return true;
}
#if 0 // FIXME
if (fromPort == id_WCK && (toPort == id_F0 || toPort == id_F1)) {
delay.delay = 717;
return true;
}
if (fromPort == id_WCK && (toPort == id_F0 || toPort == id_F1)) {
delay.delay = 717;
return true;
}
#endif
if ((fromPort == id_A0 && toPort == id_WADO3) || (fromPort == id_A1 && toPort == id_WDO1) ||
(fromPort == id_B0 && toPort == id_WADO1) || (fromPort == id_B1 && toPort == id_WDO3) ||
@ -576,10 +576,10 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
}
}
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const
{
auto disconnected = [cell](IdString p) { return !cell->ports.count(p) || cell->ports.at(p).net == nullptr; };
clockInfoCount = 0;
if (cell->type == id_TRELLIS_SLICE) {
int sd0 = int_or_default(cell->params, id("REG0_SD"), 0), sd1 = int_or_default(cell->params, id("REG1_SD"), 0);
if (port == id_CLK || port == id_WCK)
@ -598,13 +598,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
return TMG_COMB_OUTPUT;
if (port == id_DI0 || port == id_DI1 || port == id_CE || port == id_LSR || (sd0 == 1 && port == id_M0) ||
(sd1 == 1 && port == id_M1)) {
clockPort = id_CLK;
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
}
if (port == id_M0 || port == id_M1)
return TMG_COMB_INPUT;
if (port == id_Q0 || port == id_Q1) {
clockPort = id_CLK;
clockInfoCount = 1;
return TMG_REGISTER_OUTPUT;
}
@ -614,7 +614,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
if (port == id_WD0 || port == id_WD1 || port == id_WAD0 || port == id_WAD1 || port == id_WAD2 ||
port == id_WAD3 || port == id_WRE) {
clockPort = id_WCK;
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
}
@ -638,10 +638,8 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
for (auto c : boost::adaptors::reverse(port_name)) {
if (std::isdigit(c))
continue;
if (c == 'A')
clockPort = id_CLKA;
else if (c == 'B')
clockPort = id_CLKB;
if (c == 'A' || c == 'B')
clockInfoCount = 1;
else
NPNR_ASSERT_FALSE_STR("bad ram port");
return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
@ -658,6 +656,57 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
}
}
TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port, int index) const
{
TimingClockingInfo info;
info.setup.delay = 0;
info.hold.delay = 0;
info.clockToQ.delay = 0;
if (cell->type == id_TRELLIS_SLICE) {
int sd0 = int_or_default(cell->params, id("REG0_SD"), 0), sd1 = int_or_default(cell->params, id("REG1_SD"), 0);
if (port == id_WD0 || port == id_WD1 || port == id_WAD0 || port == id_WAD1 || port == id_WAD2 ||
port == id_WAD3 || port == id_WRE) {
info.edge = RISING_EDGE;
info.clock_port = id_WCK;
info.setup.delay = 100;
info.hold.delay = 0;
} else if (port == id_DI0 || port == id_DI1 || port == id_CE || port == id_LSR || (sd0 == 1 && port == id_M0) ||
(sd1 == 1 && port == id_M1)) {
info.edge = cell->sliceInfo.clkmux == id("INV") ? FALLING_EDGE : RISING_EDGE;
info.clock_port = id_CLK;
info.setup.delay = 100;
info.hold.delay = 0;
} else {
info.edge = cell->sliceInfo.clkmux == id("INV") ? FALLING_EDGE : RISING_EDGE;
info.clock_port = id_CLK;
info.clockToQ.delay = 395;
}
} else if (cell->type == id_DP16KD) {
for (auto c : boost::adaptors::reverse(port.str(this))) {
if (std::isdigit(c))
continue;
if (c == 'A')
info.clock_port = id_CLKA;
else if (c == 'B')
info.clock_port = id_CLKB;
else
NPNR_ASSERT_FALSE_STR("bad ram port");
}
info.edge = (str_or_default(cell->params, info.clock_port == id_CLKB ? id("CLKBMUX") : id("CLKAMUX"), "CLK") ==
"INV")
? FALLING_EDGE
: RISING_EDGE;
if (cell->ports.at(port).type == PORT_OUT) {
info.clockToQ.delay = 4280;
} else {
info.setup.delay = 100;
info.hold.delay = 0;
}
}
return info;
}
std::vector<std::pair<std::string, std::string>> Arch::getTilesAtLocation(int row, int col)
{
std::vector<std::pair<std::string, std::string>> ret;

View File

@ -855,6 +855,12 @@ struct Arch : BaseCtx
delay_t getDelayEpsilon() const { return 20; }
delay_t getRipupDelayPenalty() const { return 200; }
float getDelayNS(delay_t v) const { return v * 0.001; }
DelayInfo getDelayFromNS(float ns) const
{
DelayInfo del;
del.delay = delay_t(ns * 1000);
return del;
}
uint32_t getDelayChecksum(delay_t v) const { return v; }
bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const;
@ -878,8 +884,10 @@ struct Arch : BaseCtx
// Get the delay through a cell from one port to another, returning false
// if no path exists
bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const;
// Get the port class, also setting clockPort if applicable
TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) 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
TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const;
// Return true if a port is a net
bool isGlobalNet(const NetInfo *net) const;