aboutsummaryrefslogtreecommitdiffstats
path: root/gowin
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-02-19 10:39:57 +0000
committergatecat <gatecat@ds0.me>2021-02-19 11:31:33 +0000
commit7922b3bfc4ef93b8f67194c05e1a236b4c83c3da (patch)
treeb2b21259e030edd0adc7cc944322e3e9186d3a71 /gowin
parent8376db94a7519406444988be3628a4dadfb8d742 (diff)
downloadnextpnr-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.cc56
-rw-r--r--gowin/arch.h30
-rw-r--r--gowin/arch_pybindings.cc6
-rw-r--r--gowin/archdefs.h27
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
{