diff options
author | gatecat <gatecat@ds0.me> | 2021-02-19 10:39:57 +0000 |
---|---|---|
committer | gatecat <gatecat@ds0.me> | 2021-02-19 11:31:33 +0000 |
commit | 7922b3bfc4ef93b8f67194c05e1a236b4c83c3da (patch) | |
tree | b2b21259e030edd0adc7cc944322e3e9186d3a71 /gowin | |
parent | 8376db94a7519406444988be3628a4dadfb8d742 (diff) | |
download | nextpnr-7922b3bfc4ef93b8f67194c05e1a236b4c83c3da.tar.gz nextpnr-7922b3bfc4ef93b8f67194c05e1a236b4c83c3da.tar.bz2 nextpnr-7922b3bfc4ef93b8f67194c05e1a236b4c83c3da.zip |
Replace DelayInfo with DelayPair/DelayQuad
This replaces the arch-specific DelayInfo structure with new DelayPair
(min/max only) and DelayQuad (min/max for both rise and fall) structures
that form part of common code.
This further reduces the amount of arch-specific code; and also provides
useful data structures for timing analysis which will need to delay
with pairs/quads of delays as it is improved.
While there may be a small performance cost to arches that didn't
separate the rise/fall cases (arches that aren't currently separating
the min/max cases just need to be fixed...) in DelayInfo, my expectation
is that inlining will mean this doesn't make much difference.
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'gowin')
-rw-r--r-- | gowin/arch.cc | 56 | ||||
-rw-r--r-- | gowin/arch.h | 30 | ||||
-rw-r--r-- | gowin/arch_pybindings.cc | 6 | ||||
-rw-r--r-- | gowin/archdefs.h | 27 |
4 files changed, 36 insertions, 83 deletions
diff --git a/gowin/arch.cc b/gowin/arch.cc index b817dae0..d1fbd0ed 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -68,7 +68,7 @@ void Arch::addWire(IdString name, IdString type, int x, int y) wire_ids.push_back(name); } -void Arch::addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayInfo delay, Loc loc) +void Arch::addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayQuad delay, Loc loc) { NPNR_ASSERT(pips.count(name) == 0); PipInfo &pi = pips[name]; @@ -226,7 +226,7 @@ void Arch::setDelayScaling(double scale, double offset) void Arch::addCellTimingClock(IdString cell, IdString port) { cellTiming[cell].portClasses[port] = TMG_CLOCK_INPUT; } -void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayInfo delay) +void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayQuad delay) { if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE) cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT; @@ -235,7 +235,7 @@ void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay; } -void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold) +void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayPair setup, DelayPair hold) { TimingClockingInfo ci; ci.clock_port = clock; @@ -246,7 +246,7 @@ void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, cellTiming[cell].portClasses[port] = TMG_REGISTER_INPUT; } -void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq) +void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayQuad clktoq) { TimingClockingInfo ci; ci.clock_port = clock; @@ -340,27 +340,24 @@ template <class T, class C> const T *genericLookup(const T *first, int len, cons } } -DelayInfo delayLookup(const TimingPOD *first, int len, IdString name) +DelayQuad delayLookup(const TimingPOD *first, int len, IdString name) { TimingPOD needle; needle.name_id = name.index; const TimingPOD *timing = genericLookup(first, len, needle, timingCompare); - DelayInfo info; + DelayQuad delay; if (timing != nullptr) { - info.maxFall = std::max(timing->ff, timing->rf) / 1000; - info.minFall = std::min(timing->ff, timing->rf) / 1000; - info.maxRaise = std::max(timing->rr, timing->fr) / 1000; - info.minRaise = std::min(timing->rr, timing->fr) / 1000; + delay.fall.max_delay = std::max(timing->ff, timing->rf) / 1000; + delay.fall.min_delay = std::min(timing->ff, timing->rf) / 1000; + delay.rise.max_delay = std::max(timing->rr, timing->fr) / 1000; + delay.rise.min_delay = std::min(timing->rr, timing->fr) / 1000; } else { - info.maxFall = 0; - info.minFall = 0; - info.maxRaise = 0; - info.minRaise = 0; + delay = DelayQuad(0); } - return info; + return delay; } -DelayInfo Arch::getWireTypeDelay(IdString wire) +DelayQuad Arch::getWireTypeDelay(IdString wire) { IdString len; IdString glbsrc; @@ -480,12 +477,7 @@ DelayInfo Arch::getWireTypeDelay(IdString wire) } else if (glbsrc != IdString()) { return delayLookup(speed->glbsrc.timings.get(), speed->glbsrc.num_timings, glbsrc); } else { - DelayInfo info; - info.maxFall = 0; - info.minFall = 0; - info.maxRaise = 0; - info.minRaise = 0; - return info; + return DelayQuad(0); } } @@ -720,7 +712,7 @@ Arch::Arch(ArchArgs args) : args(args) snprintf(buf, 32, "R%dC%d_%s_%s", row + 1, col + 1, srcid.c_str(this), destid.c_str(this)); IdString pipname = id(buf); - DelayInfo delay = getWireTypeDelay(destid); + DelayQuad delay = getWireTypeDelay(destid); // local alias auto local_alias = pairLookup(tile->aliases.get(), tile->num_aliases, srcid.index); // std::cout << "srcid " << srcid.str(this) << std::endl; @@ -934,7 +926,7 @@ WireId Arch::getPipSrcWire(PipId pip) const { return pips.at(pip).srcWire; } WireId Arch::getPipDstWire(PipId pip) const { return pips.at(pip).dstWire; } -DelayInfo Arch::getPipDelay(PipId pip) const { return pips.at(pip).delay; } +DelayQuad Arch::getPipDelay(PipId pip) const { return pips.at(pip).delay; } const std::vector<PipId> &Arch::getPipsDownhill(WireId wire) const { return wires.at(wire).downhill; } @@ -1067,7 +1059,7 @@ bool Arch::route() // --------------------------------------------------------------- -bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const +bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const { if (!cellTiming.count(cell->name)) return false; @@ -1145,19 +1137,17 @@ void Arch::assignArchInfo() addCellTimingClock(cname, id_CLK); IdString ports[4] = {id_A, id_B, id_C, id_D}; for (int i = 0; i < 4; i++) { - DelayInfo setup = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clksetpos); - DelayInfo hold = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clkholdpos); - // DelayInfo setup = getDelayFromNS(0.1); - // DelayInfo hold = getDelayFromNS(0.1); + DelayPair setup = + delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clksetpos).delayPair(); + DelayPair hold = + delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clkholdpos).delayPair(); addCellTimingSetupHold(cname, ports[i], id_CLK, setup, hold); } - DelayInfo clkout = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clk_qpos); - // DelayInfo clkout = getDelayFromNS(0.1); + DelayQuad clkout = delayLookup(speed->dff.timings.get(), speed->dff.num_timings, id_clk_qpos); addCellTimingClockToOut(cname, id_Q, id_CLK, clkout); IdString port_delay[4] = {id_a_f, id_b_f, id_c_f, id_d_f}; for (int i = 0; i < 4; i++) { - DelayInfo delay = delayLookup(speed->lut.timings.get(), speed->lut.num_timings, port_delay[i]); - // DelayInfo delay = getDelayFromNS(0.1); + DelayQuad delay = delayLookup(speed->lut.timings.get(), speed->lut.num_timings, port_delay[i]); addCellTimingDelay(cname, ports[i], id_F, delay); } diff --git a/gowin/arch.h b/gowin/arch.h index cdc011aa..0b0d7b9c 100644 --- a/gowin/arch.h +++ b/gowin/arch.h @@ -170,7 +170,7 @@ struct PipInfo std::map<IdString, std::string> attrs; NetInfo *bound_net; WireId srcWire, dstWire; - DelayInfo delay; + DelayQuad delay; DecalXY decalxy; Loc loc; }; @@ -239,7 +239,7 @@ NEXTPNR_NAMESPACE_BEGIN struct CellTiming { std::unordered_map<IdString, TimingPortClass> portClasses; - std::unordered_map<CellDelayKey, DelayInfo> combDelays; + std::unordered_map<CellDelayKey, DelayQuad> combDelays; std::unordered_map<IdString, std::vector<TimingClockingInfo>> clockingInfo; }; @@ -302,7 +302,7 @@ struct Arch : BaseArch<ArchRanges> std::unordered_map<IdString, CellTiming> cellTiming; void addWire(IdString name, IdString type, int x, int y); - void addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayInfo delay, Loc loc); + void addPip(IdString name, IdString type, IdString srcWire, IdString dstWire, DelayQuad delay, Loc loc); void addBel(IdString name, IdString type, Loc loc, bool gb); void addBelInput(IdString bel, IdString name, IdString wire); @@ -327,12 +327,12 @@ struct Arch : BaseArch<ArchRanges> void setDelayScaling(double scale, double offset); void addCellTimingClock(IdString cell, IdString port); - void addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayInfo delay); - void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold); - void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq); + void addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayQuad delay); + void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayPair setup, DelayPair hold); + void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayQuad clktoq); IdString wireToGlobal(int &row, int &col, const DatabasePOD *db, IdString &wire); - DelayInfo getWireTypeDelay(IdString wire); + DelayQuad getWireTypeDelay(IdString wire); void read_cst(std::istream &in); // --------------------------------------------------------------- @@ -384,7 +384,7 @@ struct Arch : BaseArch<ArchRanges> NetInfo *getBoundWireNet(WireId wire) const override; WireId getConflictingWireWire(WireId wire) const override { return wire; } NetInfo *getConflictingWireNet(WireId wire) const override; - DelayInfo getWireDelay(WireId wire) const override { return DelayInfo(); } + DelayQuad getWireDelay(WireId wire) const override { return DelayQuad(0); } const std::vector<WireId> &getWires() const override; const std::vector<BelPin> &getWireBelPins(WireId wire) const override; @@ -402,7 +402,7 @@ struct Arch : BaseArch<ArchRanges> Loc getPipLocation(PipId pip) const override; WireId getPipSrcWire(PipId pip) const override; WireId getPipDstWire(PipId pip) const override; - DelayInfo getPipDelay(PipId pip) const override; + DelayQuad getPipDelay(PipId pip) const override; const std::vector<PipId> &getPipsDownhill(WireId wire) const override; const std::vector<PipId> &getPipsUphill(WireId wire) const override; @@ -420,15 +420,7 @@ struct Arch : BaseArch<ArchRanges> delay_t getRipupDelayPenalty() const override { return 0.4; } float getDelayNS(delay_t v) const override { return v; } - DelayInfo getDelayFromNS(float ns) const override - { - DelayInfo del; - del.maxRaise = ns; - del.maxFall = ns; - del.minRaise = ns; - del.minFall = ns; - return del; - } + delay_t getDelayFromNS(float ns) const override { return ns; } uint32_t getDelayChecksum(delay_t v) const override { return 0; } bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override; @@ -439,7 +431,7 @@ struct Arch : BaseArch<ArchRanges> bool place() override; bool route() override; - bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; + bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &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 diff --git a/gowin/arch_pybindings.cc b/gowin/arch_pybindings.cc index f0a0ed64..24a55ac7 100644 --- a/gowin/arch_pybindings.cc +++ b/gowin/arch_pybindings.cc @@ -59,8 +59,6 @@ void arch_wrap_python(py::module &m) py::class_<BelPin>(m, "BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin); - py::class_<DelayInfo>(m, "DelayInfo").def("maxDelay", &DelayInfo::maxDelay).def("minDelay", &DelayInfo::minDelay); - fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<IdString>, conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType"); fn_wrapper_1a<Context, decltype(&Context::checkBelAvail), &Context::checkBelAvail, pass_through<bool>, @@ -125,10 +123,10 @@ void arch_wrap_python(py::module &m) conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipSrcWire"); fn_wrapper_1a<Context, decltype(&Context::getPipDstWire), &Context::getPipDstWire, conv_to_str<WireId>, conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipDstWire"); - fn_wrapper_1a<Context, decltype(&Context::getPipDelay), &Context::getPipDelay, pass_through<DelayInfo>, + fn_wrapper_1a<Context, decltype(&Context::getPipDelay), &Context::getPipDelay, pass_through<DelayQuad>, conv_from_str<PipId>>::def_wrap(ctx_cls, "getPipDelay"); - fn_wrapper_1a<Context, decltype(&Context::getDelayFromNS), &Context::getDelayFromNS, pass_through<DelayInfo>, + fn_wrapper_1a<Context, decltype(&Context::getDelayFromNS), &Context::getDelayFromNS, pass_through<delay_t>, pass_through<double>>::def_wrap(ctx_cls, "getDelayFromNS"); fn_wrapper_0a<Context, decltype(&Context::getChipName), &Context::getChipName, pass_through<std::string>>::def_wrap( diff --git a/gowin/archdefs.h b/gowin/archdefs.h index 2efe1437..67ac6521 100644 --- a/gowin/archdefs.h +++ b/gowin/archdefs.h @@ -26,33 +26,6 @@ NEXTPNR_NAMESPACE_BEGIN typedef float delay_t; -struct DelayInfo -{ - delay_t minRaise = 0; - delay_t minFall = 0; - delay_t maxRaise = 0; - delay_t maxFall = 0; - - delay_t minRaiseDelay() const { return minRaise; } - delay_t maxRaiseDelay() const { return maxRaise; } - - delay_t minFallDelay() const { return minFall; } - delay_t maxFallDelay() const { return maxFall; } - - delay_t minDelay() const { return std::min(minFall, minRaise); } - delay_t maxDelay() const { return std::max(maxFall, maxRaise); } - - DelayInfo operator+(const DelayInfo &other) const - { - DelayInfo ret; - ret.minRaise = this->minRaise + other.minRaise; - ret.maxRaise = this->maxRaise + other.maxRaise; - ret.minFall = this->minFall + other.minFall; - ret.maxFall = this->maxFall + other.maxFall; - return ret; - } -}; - #ifndef Q_MOC_RUN enum ConstIds { |