aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nexus/arch.h20
-rw-r--r--nexus/arch_place.cc70
-rw-r--r--nexus/archdefs.h21
3 files changed, 108 insertions, 3 deletions
diff --git a/nexus/arch.h b/nexus/arch.h
index 48dc137b..ffa7ef78 100644
--- a/nexus/arch.h
+++ b/nexus/arch.h
@@ -576,10 +576,26 @@ struct Arch : BaseCtx
const ChipInfoPOD *chip_info;
// Binding states
+ struct LogicTileStatus
+ {
+ struct SliceStatus
+ {
+ bool valid = true, dirty = true;
+ } slices[4];
+ struct HalfTileStatus
+ {
+ bool valid = true, dirty = true;
+ } halfs[2];
+ CellInfo *cells[32];
+ };
+
struct TileStatus
{
std::vector<CellInfo *> boundcells;
+ LogicTileStatus *lts = nullptr;
+ ~TileStatus() { delete lts; }
};
+
std::vector<TileStatus> tileStatus;
std::unordered_map<WireId, NetInfo *> wire_to_net;
std::unordered_map<PipId, NetInfo *> pip_to_net;
@@ -1088,6 +1104,10 @@ struct Arch : BaseCtx
range.e.cursor = nh_data(wire).wire_neighbours[wire.index].num_nwires;
return range;
}
+
+ // -------------------------------------------------
+
+ bool nexus_logic_tile_valid(LogicTileStatus &lts) const;
};
NEXTPNR_NAMESPACE_END
diff --git a/nexus/arch_place.cc b/nexus/arch_place.cc
index ae1b5c79..6444d1e9 100644
--- a/nexus/arch_place.cc
+++ b/nexus/arch_place.cc
@@ -23,6 +23,76 @@
NEXTPNR_NAMESPACE_BEGIN
+enum LogicBelZ
+{
+ BEL_LUT0 = 0,
+ BEL_LUT1 = 1,
+ BEL_FF0 = 2,
+ BEL_FF1 = 3,
+ BEL_RAMW = 4,
+};
+
+bool Arch::nexus_logic_tile_valid(LogicTileStatus &lts) const
+{
+ for (int s = 0; s < 4; s++) {
+ if (lts.slices[s].dirty) {
+ lts.slices[s].valid = false;
+ lts.slices[s].dirty = false;
+ CellInfo *lut0 = lts.cells[(s << 3) | BEL_LUT0];
+ CellInfo *lut1 = lts.cells[(s << 3) | BEL_LUT1];
+ CellInfo *ff0 = lts.cells[(s << 3) | BEL_FF0];
+ CellInfo *ff1 = lts.cells[(s << 3) | BEL_FF1];
+ if (lut0 != nullptr) {
+ // Check for overuse of M signal
+ if (lut0->lutInfo.mux2_used && ff0 != nullptr && ff0->ffInfo.m != nullptr)
+ return false;
+ }
+ // Check for correct use of FF0 DI
+ if (ff0 != nullptr && ff0->ffInfo.di != nullptr &&
+ (lut0 == nullptr || (ff0->ffInfo.di != lut0->lutInfo.f && ff0->ffInfo.di != lut0->lutInfo.ofx)))
+ return false;
+ if (lut1 != nullptr) {
+ // LUT1 cannot contain a MUX2
+ if (lut1->lutInfo.mux2_used)
+ return false;
+ // If LUT1 is carry then LUT0 must be carry too
+ if (lut1->lutInfo.is_carry && (lut0 == nullptr || !lut0->lutInfo.is_carry))
+ return false;
+ }
+ // Check for correct use of FF1 DI
+ if (ff1 != nullptr && ff1->ffInfo.di != nullptr && (lut1 == nullptr || ff1->ffInfo.di != lut1->lutInfo.f))
+ return false;
+ lts.slices[s].valid = true;
+ } else if (!lts.slices[s].valid) {
+ return false;
+ }
+ }
+ for (int h = 0; h < 2; h++) {
+ if (lts.halfs[h].dirty) {
+ bool found_ff = false;
+ FFControlSet ctrlset;
+ for (int i = 0; i < 1; i++) {
+ for (auto bel : {BEL_FF0, BEL_FF1, BEL_RAMW}) {
+ if (bel == BEL_RAMW && (h != 1 || i != 0))
+ continue;
+ CellInfo *ci = lts.cells[(h * 2 + i) << 3 | bel];
+ if (ci == nullptr)
+ continue;
+ if (!found_ff) {
+ ctrlset = ci->ffInfo.ctrlset;
+ found_ff = true;
+ } else if (ci->ffInfo.ctrlset != ctrlset) {
+ return false;
+ }
+ }
+ }
+ } else if (!lts.halfs[h].valid) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { return true; }
bool Arch::isBelLocationValid(BelId bel) const { return true; }
diff --git a/nexus/archdefs.h b/nexus/archdefs.h
index ef5c4c3c..098333b9 100644
--- a/nexus/archdefs.h
+++ b/nexus/archdefs.h
@@ -148,19 +148,34 @@ struct ArchNetInfo
struct NetInfo;
+struct FFControlSet
+{
+ int clkmux, cemux, lsrmux;
+ bool async, regddr_en, gsr_en;
+ NetInfo *clk, *lsr, *ce;
+};
+
+inline bool operator!=(const FFControlSet &a, const FFControlSet &b)
+{
+ return (a.clkmux != b.clkmux) || (a.cemux != b.cemux) || (a.lsrmux != b.lsrmux) || (a.async != b.async) ||
+ (a.regddr_en != b.regddr_en) || (a.gsr_en != b.gsr_en) || (a.clk != b.clk) || (a.lsr != b.lsr) ||
+ (a.ce != b.ce);
+}
+
struct ArchCellInfo
{
union
{
struct
{
- bool is_memory, is_carry;
+ bool is_memory, is_carry, mux2_used;
int input_count;
+ NetInfo *f, *ofx;
} lutInfo;
struct
{
- bool is_clkinv, is_lsrinv, is_ceinv, is_async, gsr;
- NetInfo *clk, *lsr, *ce, *d;
+ FFControlSet ctrlset;
+ NetInfo *di, *m;
} ffInfo;
};
};