aboutsummaryrefslogtreecommitdiffstats
path: root/generic
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 /generic
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 'generic')
-rw-r--r--generic/arch.cc21
-rw-r--r--generic/arch.h25
-rw-r--r--generic/arch_pybindings.cc24
-rw-r--r--generic/archdefs.h21
4 files changed, 31 insertions, 60 deletions
diff --git a/generic/arch.cc b/generic/arch.cc
index a87c4392..03d8c801 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -64,8 +64,7 @@ void Arch::addWire(IdStringList name, IdString type, int x, int y)
wire_ids.push_back(name);
}
-void Arch::addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, DelayInfo delay,
- Loc loc)
+void Arch::addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, delay_t delay, Loc loc)
{
NPNR_ASSERT(pips.count(name) == 0);
PipInfo &pi = pips[name];
@@ -219,32 +218,32 @@ 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, delay_t delay)
{
if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE)
cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT;
if (get_or_default(cellTiming[cell].portClasses, toPort, TMG_IGNORE) == TMG_IGNORE)
cellTiming[cell].portClasses[toPort] = TMG_COMB_OUTPUT;
- cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay;
+ cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = DelayQuad(delay);
}
-void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold)
+void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, delay_t setup, delay_t hold)
{
TimingClockingInfo ci;
ci.clock_port = clock;
ci.edge = RISING_EDGE;
- ci.setup = setup;
- ci.hold = hold;
+ ci.setup = DelayPair(setup);
+ ci.hold = DelayPair(hold);
cellTiming[cell].clockingInfo[port].push_back(ci);
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, delay_t clktoq)
{
TimingClockingInfo ci;
ci.clock_port = clock;
ci.edge = RISING_EDGE;
- ci.clockToQ = clktoq;
+ ci.clockToQ = DelayQuad(clktoq);
cellTiming[cell].clockingInfo[port].push_back(ci);
cellTiming[cell].portClasses[port] = TMG_REGISTER_OUTPUT;
}
@@ -465,7 +464,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 DelayQuad(pips.at(pip).delay); }
const std::vector<PipId> &Arch::getPipsDownhill(WireId wire) const { return wires.at(wire).downhill; }
@@ -615,7 +614,7 @@ DecalXY Arch::getGroupDecal(GroupId group) const { return groups.at(group).decal
// ---------------------------------------------------------------
-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;
diff --git a/generic/arch.h b/generic/arch.h
index f3a6dccd..8a5b27e0 100644
--- a/generic/arch.h
+++ b/generic/arch.h
@@ -41,7 +41,7 @@ struct PipInfo
std::map<IdString, std::string> attrs;
NetInfo *bound_net;
WireId srcWire, dstWire;
- DelayInfo delay;
+ delay_t delay;
DecalXY decalxy;
Loc loc;
};
@@ -113,7 +113,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;
};
@@ -177,7 +177,7 @@ struct Arch : ArchAPI<ArchRanges>
std::unordered_map<IdString, CellTiming> cellTiming;
void addWire(IdStringList name, IdString type, int x, int y);
- void addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, DelayInfo delay, Loc loc);
+ void addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, delay_t delay, Loc loc);
void addBel(IdStringList name, IdString type, Loc loc, bool gb, bool hidden);
void addBelInput(IdStringList bel, IdString name, IdStringList wire);
@@ -203,9 +203,9 @@ struct Arch : ArchAPI<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, delay_t delay);
+ void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, delay_t setup, delay_t hold);
+ void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, delay_t clktoq);
void clearCellBelPinMap(IdString cell, IdString cell_pin);
void addCellBelPinMapping(IdString cell, IdString cell_pin, IdString bel_pin);
@@ -260,7 +260,7 @@ struct Arch : ArchAPI<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;
@@ -279,7 +279,7 @@ struct Arch : ArchAPI<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;
@@ -297,12 +297,7 @@ struct Arch : ArchAPI<ArchRanges>
delay_t getRipupDelayPenalty() const override { return 0.015; }
float getDelayNS(delay_t v) const override { return v; }
- DelayInfo getDelayFromNS(float ns) const override
- {
- DelayInfo del;
- del.delay = 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;
@@ -350,7 +345,7 @@ struct Arch : ArchAPI<ArchRanges>
DecalXY getPipDecal(PipId pip) const override;
DecalXY getGroupDecal(GroupId group) const override;
- bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const override;
+ bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override;
// 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 override;
// Get the TimingClockingInfo of a port
diff --git a/generic/arch_pybindings.cc b/generic/arch_pybindings.cc
index 35ec3b33..50544dc1 100644
--- a/generic/arch_pybindings.cc
+++ b/generic/arch_pybindings.cc
@@ -60,8 +60,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>,
@@ -126,10 +124,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(
@@ -159,8 +157,8 @@ void arch_wrap_python(py::module &m)
"y"_a);
fn_wrapper_6a_v<Context, decltype(&Context::addPip), &Context::addPip, conv_from_str<IdStringList>,
conv_from_str<IdString>, conv_from_str<IdStringList>, conv_from_str<IdStringList>,
- pass_through<DelayInfo>, pass_through<Loc>>::def_wrap(ctx_cls, "addPip", "name"_a, "type"_a,
- "srcWire"_a, "dstWire"_a, "delay"_a, "loc"_a);
+ pass_through<delay_t>, pass_through<Loc>>::def_wrap(ctx_cls, "addPip", "name"_a, "type"_a,
+ "srcWire"_a, "dstWire"_a, "delay"_a, "loc"_a);
fn_wrapper_5a_v<Context, decltype(&Context::addBel), &Context::addBel, conv_from_str<IdStringList>,
conv_from_str<IdString>, pass_through<Loc>, pass_through<bool>,
@@ -215,16 +213,16 @@ void arch_wrap_python(py::module &m)
"port"_a);
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingDelay), &Context::addCellTimingDelay,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
- pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingDelay", "cell"_a, "fromPort"_a,
- "toPort"_a, "delay"_a);
+ pass_through<delay_t>>::def_wrap(ctx_cls, "addCellTimingDelay", "cell"_a, "fromPort"_a, "toPort"_a,
+ "delay"_a);
fn_wrapper_5a_v<Context, decltype(&Context::addCellTimingSetupHold), &Context::addCellTimingSetupHold,
- conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>, pass_through<DelayInfo>,
- pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingSetupHold", "cell"_a, "port"_a, "clock"_a,
- "setup"_a, "hold"_a);
+ conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>, pass_through<delay_t>,
+ pass_through<delay_t>>::def_wrap(ctx_cls, "addCellTimingSetupHold", "cell"_a, "port"_a, "clock"_a,
+ "setup"_a, "hold"_a);
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingClockToOut), &Context::addCellTimingClockToOut,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
- pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingClockToOut", "cell"_a, "port"_a,
- "clock"_a, "clktoq"_a);
+ pass_through<delay_t>>::def_wrap(ctx_cls, "addCellTimingClockToOut", "cell"_a, "port"_a, "clock"_a,
+ "clktoq"_a);
fn_wrapper_2a_v<Context, decltype(&Context::clearCellBelPinMap), &Context::clearCellBelPinMap,
conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "clearCellBelPinMap", "cell"_a,
diff --git a/generic/archdefs.h b/generic/archdefs.h
index 30503414..a5108e9e 100644
--- a/generic/archdefs.h
+++ b/generic/archdefs.h
@@ -25,27 +25,6 @@ NEXTPNR_NAMESPACE_BEGIN
typedef float delay_t;
-struct DelayInfo
-{
- delay_t delay = 0;
-
- delay_t minRaiseDelay() const { return delay; }
- delay_t maxRaiseDelay() const { return delay; }
-
- delay_t minFallDelay() const { return delay; }
- delay_t maxFallDelay() const { return delay; }
-
- delay_t minDelay() const { return delay; }
- delay_t maxDelay() const { return delay; }
-
- DelayInfo operator+(const DelayInfo &other) const
- {
- DelayInfo ret;
- ret.delay = this->delay + other.delay;
- return ret;
- }
-};
-
typedef IdStringList BelId;
typedef IdStringList WireId;
typedef IdStringList PipId;