aboutsummaryrefslogtreecommitdiffstats
path: root/cyclonev
diff options
context:
space:
mode:
Diffstat (limited to 'cyclonev')
-rw-r--r--cyclonev/arch.cc19
-rw-r--r--cyclonev/arch.h15
-rw-r--r--cyclonev/constids.inc8
-rw-r--r--cyclonev/io.cc53
-rw-r--r--cyclonev/lab.cc6
5 files changed, 92 insertions, 9 deletions
diff --git a/cyclonev/arch.cc b/cyclonev/arch.cc
index 8dd21499..9aee5a59 100644
--- a/cyclonev/arch.cc
+++ b/cyclonev/arch.cc
@@ -67,8 +67,7 @@ Arch::Arch(ArchArgs args)
create_lab(x, y);
break;
case CycloneV::block_type_t::GPIO:
- // GPIO tiles contain 4 pins
- // TODO
+ create_gpio(x, y);
break;
default:
continue;
@@ -137,6 +136,18 @@ IdStringList Arch::getBelName(BelId bel) const
return IdStringList(ids);
}
+bool Arch::isBelLocationValid(BelId bel) const
+{
+ auto &data = bel_data(bel);
+ // Incremental validity update
+ if (data.type == id_MISTRAL_COMB) {
+ return is_alm_legal(data.lab_data.lab, data.lab_data.alm);
+ } else if (data.type == id_MISTRAL_FF) {
+ return is_alm_legal(data.lab_data.lab, data.lab_data.alm) && is_lab_ctrlset_legal(data.lab_data.lab);
+ }
+ return true;
+}
+
WireId Arch::getWireByName(IdStringList name) const
{
// non-mistral wires
@@ -217,6 +228,8 @@ bool Arch::isValidBelForCellType(IdString cell_type, BelId bel) const
IdString bel_type = getBelType(bel);
if (bel_type == id_MISTRAL_COMB)
return is_comb_cell(cell_type);
+ else if (bel_type == id_MISTRAL_IO)
+ return is_io_cell(cell_type);
else
return bel_type == cell_type;
}
@@ -225,6 +238,8 @@ BelBucketId Arch::getBelBucketForCellType(IdString cell_type) const
{
if (is_comb_cell(cell_type))
return id_MISTRAL_COMB;
+ else if (is_io_cell(cell_type))
+ return id_MISTRAL_IO;
else
return cell_type;
}
diff --git a/cyclonev/arch.h b/cyclonev/arch.h
index 34d90a04..301f19d8 100644
--- a/cyclonev/arch.h
+++ b/cyclonev/arch.h
@@ -44,8 +44,6 @@ struct ALMInfo
std::array<BelId, 2> lut_bels;
std::array<BelId, 4> ff_bels;
// TODO: ALM configuration (L5/L6 mode, LUT input permutation, etc)
- // So we only validity-check changed parts
- bool valid = false, dirty = false;
};
struct LABInfo
@@ -56,9 +54,6 @@ struct LABInfo
std::array<WireId, 2> aclr_wires;
WireId sclr_wire, sload_wire;
// TODO: LAB configuration (control set etc)
-
- // These apply to the validity-checking status of the shared FF control sets
- bool ctrl_valid = false, ctrl_dirty = false;
};
struct PinInfo
@@ -278,6 +273,8 @@ struct Arch : BaseArch<ArchRanges>
PortType getBelPinType(BelId bel, IdString pin) const override { return bel_data(bel).pins.at(pin).dir; }
std::vector<IdString> getBelPins(BelId bel) const override;
+ bool isBelLocationValid(BelId bel) const override;
+
// -------------------------------------------------
WireId getWireByName(IdStringList name) const override;
@@ -341,8 +338,8 @@ struct Arch : BaseArch<ArchRanges>
return WireId(cyclonev->pnode_to_rnode(CycloneV::pnode(bt, x, y, port, bi, pi)));
}
- void create_lab(int x, int y); // lab.cc
- void create_gpio(int x, int y);
+ void create_lab(int x, int y); // lab.cc
+ void create_gpio(int x, int y); // io.cc
// -------------------------------------------------
@@ -355,6 +352,10 @@ struct Arch : BaseArch<ArchRanges>
// -------------------------------------------------
+ bool is_io_cell(IdString cell_type) const; // io.cc
+
+ // -------------------------------------------------
+
static const std::string defaultPlacer;
static const std::vector<std::string> availablePlacers;
static const std::string defaultRouter;
diff --git a/cyclonev/constids.inc b/cyclonev/constids.inc
index 90d5e753..fcc723f8 100644
--- a/cyclonev/constids.inc
+++ b/cyclonev/constids.inc
@@ -3,6 +3,14 @@ X(MISTRAL_FF)
X(LAB)
X(MLAB)
+X(MISTRAL_IO)
+X(I)
+X(O)
+X(OE)
+X(PAD)
+X(MISTRAL_IB)
+X(MISTRAL_OB)
+
X(A)
X(B)
X(C)
diff --git a/cyclonev/io.cc b/cyclonev/io.cc
new file mode 100644
index 00000000..f2517e5d
--- /dev/null
+++ b/cyclonev/io.cc
@@ -0,0 +1,53 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2021 gatecat <gatecat@ds0.me>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "log.h"
+#include "nextpnr.h"
+#include "util.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+void Arch::create_gpio(int x, int y)
+{
+ for (int z = 0; z < 4; z++) {
+ // Notional pad wire
+ WireId pad = add_wire(x, y, id(stringf("PAD[%d]", z)));
+ BelId bel = add_bel(x, y, id(stringf("IO[%d]", z)), id_MISTRAL_IO);
+ add_bel_pin(bel, id_PAD, PORT_INOUT, pad);
+ // FIXME: is the port index of zero always correct?
+ add_bel_pin(bel, id_I, PORT_IN, get_port(CycloneV::GPIO, x, y, z, CycloneV::DATAIN, 0));
+ add_bel_pin(bel, id_OE, PORT_IN, get_port(CycloneV::GPIO, x, y, z, CycloneV::OEIN, 0));
+ add_bel_pin(bel, id_O, PORT_OUT, get_port(CycloneV::GPIO, x, y, z, CycloneV::DATAOUT, 0));
+ }
+}
+
+bool Arch::is_io_cell(IdString cell_type) const
+{
+ // Return true if a cell is an IO buffer cell type
+ switch (cell_type.index) {
+ case ID_MISTRAL_IB:
+ case ID_MISTRAL_OB:
+ case ID_MISTRAL_IO:
+ return true;
+ default:
+ return false;
+ }
+}
+
+NEXTPNR_NAMESPACE_END \ No newline at end of file
diff --git a/cyclonev/lab.cc b/cyclonev/lab.cc
index 4e10fe59..6f7c5e6d 100644
--- a/cyclonev/lab.cc
+++ b/cyclonev/lab.cc
@@ -377,4 +377,10 @@ bool Arch::is_alm_legal(uint32_t lab, uint8_t alm) const
return true;
}
+bool Arch::is_lab_ctrlset_legal(uint32_t lab) const
+{
+ // TODO
+ return true;
+}
+
NEXTPNR_NAMESPACE_END \ No newline at end of file