aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiodrag Milanovic <mmicko@gmail.com>2023-03-17 19:00:05 +0100
committermyrtle <gatecat@ds0.me>2023-03-20 09:53:35 +0100
commit0ce72e1a3103d52d036f822b98e511d9c4f1e71b (patch)
treedf69b12dc5ec296cdce6e7e7279234c476f2d811
parentad5f6fccaa4484eb02d3fa6d420ff39517b524e6 (diff)
downloadnextpnr-0ce72e1a3103d52d036f822b98e511d9c4f1e71b.tar.gz
nextpnr-0ce72e1a3103d52d036f822b98e511d9c4f1e71b.tar.bz2
nextpnr-0ce72e1a3103d52d036f822b98e511d9c4f1e71b.zip
Use TRELLIS primitives
-rw-r--r--machxo2/arch.cc2
-rw-r--r--machxo2/bitstream.cc4
-rw-r--r--machxo2/cells.cc6
-rw-r--r--machxo2/cells.h6
-rw-r--r--machxo2/constids.inc7
-rw-r--r--machxo2/facade_import.py6
-rw-r--r--machxo2/gfx.cc6
-rw-r--r--machxo2/pack.cc42
8 files changed, 39 insertions, 40 deletions
diff --git a/machxo2/arch.cc b/machxo2/arch.cc
index 639f6c6b..f2c87888 100644
--- a/machxo2/arch.cc
+++ b/machxo2/arch.cc
@@ -368,7 +368,7 @@ bool Arch::place()
return retVal;
} else if (placer == "heap") {
PlacerHeapCfg cfg(getCtx());
- cfg.ioBufTypes.insert(id_FACADE_IO);
+ cfg.ioBufTypes.insert(id_TRELLIS_IO);
bool retVal = placer_heap(getCtx(), cfg);
getCtx()->settings[id_place] = 1;
archInfoToAttributes();
diff --git a/machxo2/bitstream.cc b/machxo2/bitstream.cc
index 8cfc408d..6ae4ffac 100644
--- a/machxo2/bitstream.cc
+++ b/machxo2/bitstream.cc
@@ -225,7 +225,7 @@ void write_bitstream(Context *ctx, std::string text_config_file)
continue;
}
BelId bel = ci->bel;
- if (ci->type == id_FACADE_SLICE) {
+ if (ci->type == id_TRELLIS_SLICE) {
std::string tname = ctx->get_tile_by_type_loc(bel.location.y, bel.location.x, "PLC");
std::string slice = ctx->tile_info(bel)->bel_data[bel.index].name.get();
@@ -253,7 +253,7 @@ void write_bitstream(Context *ctx, std::string text_config_file)
cc.tiles[tname].add_enum(slice + ".REG1.SD", intstr_or_default(ci->params, id_REG1_SD, "0"));
cc.tiles[tname].add_enum(slice + ".REG0.REGSET", str_or_default(ci->params, id_REG0_REGSET, "RESET"));
cc.tiles[tname].add_enum(slice + ".REG1.REGSET", str_or_default(ci->params, id_REG1_REGSET, "RESET"));
- } else if (ci->type == id_FACADE_IO) {
+ } else if (ci->type == id_TRELLIS_IO) {
std::string pio = ctx->tile_info(bel)->bel_data[bel.index].name.get();
std::string iotype = str_or_default(ci->attrs, id_IO_TYPE, "LVCMOS33");
std::string dir = str_or_default(ci->params, id_DIR, "INPUT");
diff --git a/machxo2/cells.cc b/machxo2/cells.cc
index c5464892..5f277d17 100644
--- a/machxo2/cells.cc
+++ b/machxo2/cells.cc
@@ -32,7 +32,7 @@ std::unique_ptr<CellInfo> create_machxo2_cell(Context *ctx, IdString type, std::
name.empty() ? ctx->id("$nextpnr_" + type.str(ctx) + "_" + std::to_string(auto_idx++)) : ctx->id(name);
auto new_cell = std::make_unique<CellInfo>(ctx, name_id, type);
- if (type == id_FACADE_SLICE) {
+ if (type == id_TRELLIS_SLICE) {
new_cell->params[id_MODE] = std::string("LOGIC");
new_cell->params[id_GSR] = std::string("ENABLED");
new_cell->params[id_SRMODE] = std::string("LSR_OVER_CE");
@@ -101,11 +101,11 @@ std::unique_ptr<CellInfo> create_machxo2_cell(Context *ctx, IdString type, std::
new_cell->addOutput(id_WADO1);
new_cell->addOutput(id_WADO2);
new_cell->addOutput(id_WADO3);
- } else if (type == id_FACADE_IO) {
+ } else if (type == id_TRELLIS_IO) {
new_cell->params[id_DIR] = std::string("INPUT");
new_cell->attrs[id_IO_TYPE] = std::string("LVCMOS33");
- new_cell->addInout(id_PAD);
+ new_cell->addInout(id_B);
new_cell->addInput(id_I);
new_cell->addInput(id_EN);
new_cell->addOutput(id_O);
diff --git a/machxo2/cells.h b/machxo2/cells.h
index 7a9bab92..753d7f11 100644
--- a/machxo2/cells.h
+++ b/machxo2/cells.h
@@ -26,7 +26,7 @@
NEXTPNR_NAMESPACE_BEGIN
// When packing DFFs, we need context of how it's connected to a LUT to
-// properly map DFF ports to FACADE_SLICEs; DI0 input muxes F0 and OFX0,
+// properly map DFF ports to TRELLIS_SLICEs; DI0 input muxes F0 and OFX0,
// and a DFF inside a slice can use either DI0 or M0 as an input.
enum class LutType
{
@@ -43,9 +43,9 @@ std::unique_ptr<CellInfo> create_machxo2_cell(Context *ctx, IdString type, std::
inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_LUT4; }
// Return true if a cell is a flipflop
-inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_FACADE_FF; }
+inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_TRELLIS_FF; }
-inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_FACADE_SLICE; }
+inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_TRELLIS_SLICE; }
// Convert a LUT primitive to (part of) an GENERIC_SLICE, swapping ports
// as needed. Set no_dff if a DFF is not being used, so that the output
diff --git a/machxo2/constids.inc b/machxo2/constids.inc
index 40d96fb8..d527c28f 100644
--- a/machxo2/constids.inc
+++ b/machxo2/constids.inc
@@ -1,4 +1,4 @@
-X(FACADE_SLICE)
+X(TRELLIS_SLICE)
X(A0)
X(B0)
X(C0)
@@ -60,15 +60,14 @@ X(CCU2_INJECT1_1)
X(WREMUX)
-X(FACADE_FF)
+X(TRELLIS_FF)
X(DI)
X(Q)
X(REGSET)
-X(FACADE_IO)
-X(PAD)
+X(TRELLIS_IO)
X(I)
X(EN)
X(O)
diff --git a/machxo2/facade_import.py b/machxo2/facade_import.py
index 327d3418..93e07775 100644
--- a/machxo2/facade_import.py
+++ b/machxo2/facade_import.py
@@ -469,11 +469,11 @@ def main():
constids[line[1]] = idx
const_id_count += 1
- constids["SLICE"] = constids["FACADE_SLICE"]
- constids["PIO"] = constids["FACADE_IO"]
+ constids["SLICE"] = constids["TRELLIS_SLICE"]
+ constids["PIO"] = constids["TRELLIS_IO"]
chip = pytrellis.Chip(dev_names[args.device])
- rg = pytrellis.make_optimized_chipdb(chip)
+ rg = pytrellis.make_optimized_chipdb(chip, split_slice_mode=False)
max_row = chip.get_max_row()
max_col = chip.get_max_col()
process_pio_db(rg, args.device)
diff --git a/machxo2/gfx.cc b/machxo2/gfx.cc
index 08b2e01d..19da68e1 100644
--- a/machxo2/gfx.cc
+++ b/machxo2/gfx.cc
@@ -43,19 +43,19 @@ void gfxTileBel(std::vector<GraphicElement> &g, int x, int y, int z, int w, int
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = style;
- if (bel_type == id_FACADE_SLICE) {
+ if (bel_type == id_TRELLIS_SLICE) {
el.x1 = x + slice_x1;
el.x2 = x + slice_x2_comb;
el.y1 = y + slice_y1 + z * slice_pitch;
el.y2 = y + slice_y2 + z * slice_pitch;
g.push_back(el);
- /* } else if (bel_type == id_FACADE_FF) {
+ /* } else if (bel_type == id_TRELLIS_FF) {
el.x1 = x + slice_x1_ff;
el.x2 = x + slice_x2;
el.y1 = y + slice_y1 + z * slice_pitch;
el.y2 = y + slice_y2 + z * slice_pitch;
g.push_back(el);*/
- } else if (bel_type.in(id_FACADE_IO)) {
+ } else if (bel_type.in(id_TRELLIS_IO)) {
bool top_bottom = (y == 0 || y == (h - 1));
if (top_bottom) {
el.x1 = x + io_cell_h_x1 + (z + 2) * io_cell_gap;
diff --git a/machxo2/pack.cc b/machxo2/pack.cc
index a9ca00f2..5f895cf9 100644
--- a/machxo2/pack.cc
+++ b/machxo2/pack.cc
@@ -39,7 +39,7 @@ static void pack_lut_lutffs(Context *ctx)
if (ctx->verbose)
log_info("cell '%s' is of type '%s'\n", ci->name.c_str(ctx), ci->type.c_str(ctx));
if (is_lut(ctx, ci)) {
- std::unique_ptr<CellInfo> packed = create_machxo2_cell(ctx, id_FACADE_SLICE, ci->name.str(ctx) + "_LC");
+ std::unique_ptr<CellInfo> packed = create_machxo2_cell(ctx, id_TRELLIS_SLICE, ci->name.str(ctx) + "_LC");
for (auto &attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
@@ -100,7 +100,7 @@ static void pack_remaining_ffs(Context *ctx)
if (ctx->verbose)
log_info("cell '%s' of type '%s remains unpacked'\n", ci->name.c_str(ctx), ci->type.c_str(ctx));
- std::unique_ptr<CellInfo> packed = create_machxo2_cell(ctx, id_FACADE_SLICE, ci->name.str(ctx) + "_LC");
+ std::unique_ptr<CellInfo> packed = create_machxo2_cell(ctx, id_TRELLIS_SLICE, ci->name.str(ctx) + "_LC");
for (auto &attr : ci->attrs)
packed->attrs[attr.first] = attr.second;
@@ -141,10 +141,10 @@ static void set_net_constant(Context *ctx, NetInfo *orig, NetInfo *constnet, boo
if (ctx->verbose)
log_info("%s user %s\n", orig->name.c_str(ctx), uc->name.c_str(ctx));
- if (uc->type == id_FACADE_FF && user.port == id_DI) {
- log_info("FACADE_FF %s is driven by a constant\n", uc->name.c_str(ctx));
+ if (uc->type == id_TRELLIS_FF && user.port == id_DI) {
+ log_info("TRELLIS_FF %s is driven by a constant\n", uc->name.c_str(ctx));
- std::unique_ptr<CellInfo> lc = create_machxo2_cell(ctx, id_FACADE_SLICE, uc->name.str(ctx) + "_CONST");
+ std::unique_ptr<CellInfo> lc = create_machxo2_cell(ctx, id_TRELLIS_SLICE, uc->name.str(ctx) + "_CONST");
for (auto &attr : uc->attrs)
lc->attrs[attr.first] = attr.second;
@@ -179,7 +179,7 @@ static void pack_constants(Context *ctx)
{
log_info("Packing constants..\n");
- std::unique_ptr<CellInfo> const_cell = create_machxo2_cell(ctx, id_FACADE_SLICE, "$PACKER_CONST");
+ std::unique_ptr<CellInfo> const_cell = create_machxo2_cell(ctx, id_TRELLIS_SLICE, "$PACKER_CONST");
const_cell->params[id_LUT0_INITVAL] = Property(0, 16);
const_cell->params[id_LUT1_INITVAL] = Property(0xFFFF, 16);
@@ -224,9 +224,9 @@ static bool is_nextpnr_iob(Context *ctx, CellInfo *cell)
cell->type == ctx->id("$nextpnr_iobuf");
}
-static bool is_facade_iob(const Context *ctx, const CellInfo *cell) { return cell->type == id_FACADE_IO; }
+static bool is_trellis_iob(const Context *ctx, const CellInfo *cell) { return cell->type == id_TRELLIS_IO; }
-static bool nextpnr_iob_connects_only_facade_iob(Context *ctx, CellInfo *iob, NetInfo *&top)
+static bool nextpnr_iob_connects_only_trellis_iob(Context *ctx, CellInfo *iob, NetInfo *&top)
{
NPNR_ASSERT(is_nextpnr_iob(ctx, iob));
@@ -234,18 +234,18 @@ static bool nextpnr_iob_connects_only_facade_iob(Context *ctx, CellInfo *iob, Ne
NetInfo *o = iob->ports.at(id_O).net;
top = o;
- CellInfo *fio = net_only_drives(ctx, o, is_facade_iob, id_PAD, true);
+ CellInfo *fio = net_only_drives(ctx, o, is_trellis_iob, id_B, true);
return fio != nullptr;
} else if (iob->type == ctx->id("$nextpnr_obuf")) {
NetInfo *i = iob->ports.at(id_I).net;
top = i;
- // If connected to a FACADE_IO PAD, the net attached to an I port of an
+ // If connected to a TRELLIS_IO PAD, the net attached to an I port of an
// $nextpnr_obuf will not have a driver, only users; an inout port
// like PAD cannot be a driver in nextpnr. So net_driven_by won't
// return anything. We exclude the IOB as one of the two users because
// we already know that the net drives the $nextpnr_obuf.
- CellInfo *fio = net_only_drives(ctx, i, is_facade_iob, id_PAD, true, iob);
+ CellInfo *fio = net_only_drives(ctx, i, is_trellis_iob, id_B, true, iob);
return fio != nullptr;
} else if (iob->type == ctx->id("$nextpnr_iobuf")) {
NetInfo *o = iob->ports.at(id_O).net;
@@ -254,10 +254,10 @@ static bool nextpnr_iob_connects_only_facade_iob(Context *ctx, CellInfo *iob, Ne
// When split_io is enabled in a frontend (it is for JSON), the I and O
// ports of a $nextpnr_iobuf are split; the I port connects to the
// driver of the original net before IOB insertion, and the O port
- // connects everything else. Because FACADE_IO PADs cannot be a driver
+ // connects everything else. Because TRELLIS_IO PADs cannot be a driver
// in nextpnr, the we can safely ignore the I port of an $nextpnr_iobuf
// for any JSON input we're interested in accepting.
- CellInfo *fio_o = net_only_drives(ctx, o, is_facade_iob, id_PAD, true);
+ CellInfo *fio_o = net_only_drives(ctx, o, is_trellis_iob, id_B, true);
return fio_o != nullptr;
}
@@ -266,7 +266,7 @@ static bool nextpnr_iob_connects_only_facade_iob(Context *ctx, CellInfo *iob, Ne
}
// Pack IO buffers- Right now, all this does is remove $nextpnr_[io]buf cells.
-// User is expected to manually instantiate FACADE_IO with BEL/IO_TYPE
+// User is expected to manually instantiate TRELLIS_IO with BEL/IO_TYPE
// attributes.
static void pack_io(Context *ctx)
{
@@ -279,8 +279,8 @@ static void pack_io(Context *ctx)
if (is_nextpnr_iob(ctx, ci)) {
NetInfo *top;
- if (!nextpnr_iob_connects_only_facade_iob(ctx, ci, top))
- log_error("Top level net '%s' is not connected to a FACADE_IO PAD port.\n", top->name.c_str(ctx));
+ if (!nextpnr_iob_connects_only_trellis_iob(ctx, ci, top))
+ log_error("Top level net '%s' is not connected to a TRELLIS_IO PAD port.\n", top->name.c_str(ctx));
if (ctx->verbose)
log_info("Removing top-level IOBUF '%s' of type '%s'\n", ci->name.c_str(ctx), ci->type.c_str(ctx));
@@ -288,11 +288,11 @@ static void pack_io(Context *ctx)
for (auto &p : ci->ports)
ci->disconnectPort(p.first);
packed_cells.insert(ci->name);
- } else if (is_facade_iob(ctx, ci)) {
- // If FACADE_IO has LOC attribute, convert the LOC (pin) to a BEL
- // attribute and place FACADE_IO at resulting BEL location. A BEL
- // attribute already on a FACADE_IO is an error. Attributes on
- // the pin attached to the PAD of FACADE_IO are ignored by this
+ } else if (is_trellis_iob(ctx, ci)) {
+ // If TRELLIS_IO has LOC attribute, convert the LOC (pin) to a BEL
+ // attribute and place TRELLIS_IO at resulting BEL location. A BEL
+ // attribute already on a TRELLIS_IO is an error. Attributes on
+ // the pin attached to the PAD of TRELLIS_IO are ignored by this
// packing phase.
auto loc_attr_cell = ci->attrs.find(id_LOC);
auto bel_attr_cell = ci->attrs.find(id_BEL);