aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/arch.h
diff options
context:
space:
mode:
Diffstat (limited to 'ice40/arch.h')
-rw-r--r--ice40/arch.h71
1 files changed, 50 insertions, 21 deletions
diff --git a/ice40/arch.h b/ice40/arch.h
index 27d5db9f..836dc46e 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -404,7 +404,7 @@ struct Arch : BaseCtx
std::vector<CellInfo *> bel_to_cell;
std::vector<NetInfo *> wire_to_net;
std::vector<NetInfo *> pip_to_net;
- std::vector<NetInfo *> switches_locked;
+ std::vector<WireId> switches_locked;
ArchArgs args;
Arch(ArchArgs args);
@@ -417,8 +417,8 @@ struct Arch : BaseCtx
// -------------------------------------------------
- int getGridDimX() const { return 34; }
- int getGridDimY() const { return 34; }
+ int getGridDimX() const { return chip_info->width; }
+ int getGridDimY() const { return chip_info->height; }
int getTileBelDimZ(int, int) const { return 8; }
int getTilePipDimZ(int, int) const { return 1; }
@@ -485,6 +485,7 @@ struct Arch : BaseCtx
Loc getBelLocation(BelId bel) const
{
+ NPNR_ASSERT(bel != BelId());
Loc loc;
loc.x = chip_info->bel_data[bel.index].x;
loc.y = chip_info->bel_data[bel.index].y;
@@ -546,7 +547,7 @@ struct Arch : BaseCtx
auto pip = it->second.pip;
if (pip != PipId()) {
pip_to_net[pip.index] = nullptr;
- switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr;
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = WireId();
}
net_wires.erase(it);
@@ -566,6 +567,8 @@ struct Arch : BaseCtx
return wire_to_net[wire.index];
}
+ WireId getConflictingWireWire(WireId wire) const { return wire; }
+
NetInfo *getConflictingWireNet(WireId wire) const
{
NPNR_ASSERT(wire != WireId());
@@ -608,14 +611,15 @@ struct Arch : BaseCtx
{
NPNR_ASSERT(pip != PipId());
NPNR_ASSERT(pip_to_net[pip.index] == nullptr);
- NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == nullptr);
-
- pip_to_net[pip.index] = net;
- switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
+ NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == WireId());
WireId dst;
dst.index = chip_info->pip_data[pip.index].dst;
NPNR_ASSERT(wire_to_net[dst.index] == nullptr);
+
+ pip_to_net[pip.index] = net;
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = dst;
+
wire_to_net[dst.index] = net;
net->wires[dst].pip = pip;
net->wires[dst].strength = strength;
@@ -627,7 +631,7 @@ struct Arch : BaseCtx
{
NPNR_ASSERT(pip != PipId());
NPNR_ASSERT(pip_to_net[pip.index] != nullptr);
- NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != nullptr);
+ NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != WireId());
WireId dst;
dst.index = chip_info->pip_data[pip.index].dst;
@@ -636,33 +640,39 @@ struct Arch : BaseCtx
pip_to_net[pip.index]->wires.erase(dst);
pip_to_net[pip.index] = nullptr;
- switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr;
+ switches_locked[chip_info->pip_data[pip.index].switch_index] = WireId();
refreshUiPip(pip);
refreshUiWire(dst);
}
- bool checkPipAvail(PipId pip) const
+ bool ice40_pip_hard_unavail(PipId pip) const
{
NPNR_ASSERT(pip != PipId());
auto &pi = chip_info->pip_data[pip.index];
auto &si = chip_info->bits_info->switches[pi.switch_index];
- if (switches_locked[pi.switch_index] != nullptr)
- return false;
-
if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) {
NPNR_ASSERT(si.bel >= 0);
if (bel_to_cell[si.bel] != nullptr)
- return false;
+ return true;
}
if (pi.flags & PipInfoPOD::FLAG_NOCARRY) {
NPNR_ASSERT(si.bel >= 0);
if (bel_carry[si.bel])
- return false;
+ return true;
}
- return true;
+ return false;
+ }
+
+ bool checkPipAvail(PipId pip) const
+ {
+ if (ice40_pip_hard_unavail(pip))
+ return false;
+
+ auto &pi = chip_info->pip_data[pip.index];
+ return switches_locked[pi.switch_index] == WireId();
}
NetInfo *getBoundPipNet(PipId pip) const
@@ -671,12 +681,23 @@ struct Arch : BaseCtx
return pip_to_net[pip.index];
}
- NetInfo *getConflictingPipNet(PipId pip) const
+ WireId getConflictingPipWire(PipId pip) const
{
- NPNR_ASSERT(pip != PipId());
+ if (ice40_pip_hard_unavail(pip))
+ return WireId();
+
return switches_locked[chip_info->pip_data[pip.index].switch_index];
}
+ NetInfo *getConflictingPipNet(PipId pip) const
+ {
+ if (ice40_pip_hard_unavail(pip))
+ return nullptr;
+
+ WireId wire = switches_locked[chip_info->pip_data[pip.index].switch_index];
+ return wire == WireId() ? nullptr : wire_to_net[wire.index];
+ }
+
AllPipRange getPips() const
{
AllPipRange range;
@@ -775,6 +796,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;
@@ -798,8 +825,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 clockDomain if applicable
- TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockDomain) 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;