aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-01-21 19:03:12 +0000
committerDavid Shah <dave@ds0.me>2019-02-08 12:34:22 +0000
commite929d221f3395b8c28bf146d1673072077cd8eea (patch)
treec6e2d2c8ee2046ef3df5423ba3fc5cab4808be5c /ecp5
parent8e8c103b3490a4636b652fb6555c40cd39fc1649 (diff)
downloadnextpnr-e929d221f3395b8c28bf146d1673072077cd8eea.tar.gz
nextpnr-e929d221f3395b8c28bf146d1673072077cd8eea.tar.bz2
nextpnr-e929d221f3395b8c28bf146d1673072077cd8eea.zip
ecp5: Adding DTR, OSCG, CLKDIVF, USRMCLK, JTAGG
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/arch.cc17
-rw-r--r--ecp5/arch.h11
-rw-r--r--ecp5/bitstream.cc29
-rw-r--r--ecp5/constids.inc100
4 files changed, 156 insertions, 1 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 380c0d7d..a2036033 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -681,6 +681,23 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
clockInfoCount = 1;
return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
}
+ } else if (cell->type == id_DTR || cell->type == id_USRMCLK || cell->type == id_SEDGA || cell->type == id_GSR ||
+ cell->type == id_JTAGG) {
+ return (cell->ports.at(port).type == PORT_OUT) ? TMG_STARTPOINT : TMG_ENDPOINT;
+ } else if (cell->type == id_OSCG) {
+ if (port == id_OSC)
+ return TMG_GEN_CLOCK;
+ else
+ return TMG_IGNORE;
+ } else if (cell->type == id_CLKDIVF) {
+ if (port == id_CLKI)
+ return TMG_CLOCK_INPUT;
+ else if (port == id_RST || port == id_ALIGNWD)
+ return TMG_ENDPOINT;
+ else if (port == id_CDIVX)
+ return TMG_GEN_CLOCK;
+ else
+ NPNR_ASSERT_FALSE("bad clkdiv port");
} else {
log_error("cell type '%s' is unsupported (instantiated as '%s')\n", cell->type.c_str(this),
cell->name.c_str(this));
diff --git a/ecp5/arch.h b/ecp5/arch.h
index a68673f4..4f2aaaa9 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -993,6 +993,17 @@ struct Arch : BaseCtx
NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set");
}
+ std::string getTileByType(std::string type) const
+ {
+ for (int i = 0; i < chip_info->height * chip_info->width; i++) {
+ auto &tileloc = chip_info->tile_info[i];
+ for (int j = 0; j < tileloc.num_tiles; j++)
+ if (chip_info->tiletype_names[tileloc.tile_names[j].type_idx].get() == type)
+ return tileloc.tile_names[j].name.get();
+ }
+ NPNR_ASSERT_FALSE_STR("no with type " + type);
+ }
+
GlobalInfoPOD globalInfoAtLoc(Location loc);
// Apply LPF constraints to the context
diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc
index 69398010..bec33f67 100644
--- a/ecp5/bitstream.cc
+++ b/ecp5/bitstream.cc
@@ -1120,6 +1120,35 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
std::string tname = ctx->getTileByTypeAndLocation(loc.y + 1, loc.x, "BMID_0H");
cc.tiles[tname].add_enum("PCSCLKDIV" + std::to_string(loc.z),
str_or_default(ci->params, ctx->id("GSR"), "ENABLED"));
+ } else if (ci->type == id_DTR) {
+ cc.tiles[ctx->getTileByType("DTR")].add_enum("DTR.MODE", "DTR");
+ } else if (ci->type == id_OSCG) {
+ int div = int_or_default(ci->params, ctx->id("DIV"), 128);
+ if (div == 128)
+ div = 127;
+ cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum("OSC.DIV", std::to_string(div));
+ cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("OSC.DIV", std::to_string(div));
+ cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("OSC.MODE", "OSCG");
+ cc.tiles[ctx->getTileByType("EFB1_PICB1")].add_enum("CCLK.MODE", "_NONE_");
+ } else if (ci->type == id_USRMCLK) {
+ cc.tiles[ctx->getTileByType("EFB3_PICB1")].add_enum("CCLK.MODE", "USRMCLK");
+ } else if (ci->type == id_GSR) {
+ cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum(
+ "GSR.GSRMODE", str_or_default(ci->params, ctx->id("MODE"), "ACTIVE_HIGH"));
+ cc.tiles[ctx->getTileByType("VIQ_BUF")].add_enum("GSR.SYNCMODE",
+ str_or_default(ci->params, ctx->id("SYNCMODE"), "ASYNC"));
+ } else if (ci->type == id_JTAGG) {
+ cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum("JTAG.ER1",
+ str_or_default(ci->params, ctx->id("ER1"), "ENABLED"));
+ cc.tiles[ctx->getTileByType("EFB0_PICB0")].add_enum("JTAG.ER2",
+ str_or_default(ci->params, ctx->id("ER2"), "ENABLED"));
+ } else if (ci->type == id_CLKDIVF) {
+ Loc loc = ctx->getBelLocation(ci->bel);
+ bool r = loc.x > 5;
+ std::string clkdiv = std::string("CLKDIV_") + (r ? "R" : "L") + std::to_string(loc.z);
+ std::string tile = ctx->getTileByType(std::string("ECLK_") + (r ? "R" : "L"));
+ cc.tiles[tile].add_enum(clkdiv + ".DIV", str_or_default(ci->params, ctx->id("DIV"), "2.0"));
+ cc.tiles[tile].add_enum(clkdiv + ".GSR", str_or_default(ci->params, ctx->id("GSR"), "DISABLED"));
} else {
NPNR_ASSERT_FALSE("unsupported cell type");
}
diff --git a/ecp5/constids.inc b/ecp5/constids.inc
index 202a7eb2..6ba453c7 100644
--- a/ecp5/constids.inc
+++ b/ecp5/constids.inc
@@ -1115,7 +1115,6 @@ X(SEL2)
X(SEL1)
X(SEL0)
X(CDIV1)
-X(CDIVX)
X(DP16KD_REGMODE_A_NOREG_REGMODE_B_NOREG)
X(DP16KD_REGMODE_A_NOREG_REGMODE_B_OUTREG)
@@ -1182,3 +1181,102 @@ X(RDPNTR2)
X(WRPNTR0)
X(WRPNTR1)
X(WRPNTR2)
+
+X(GSR)
+
+X(JTAGG)
+X(TCK)
+X(TMS)
+X(TDI)
+X(JTDO2)
+X(JTDO1)
+X(TDO)
+X(JTDI)
+X(JTCK)
+X(JRTI2)
+X(JRTI1)
+X(JSHIFT)
+X(JUPDATE)
+X(JRSTN)
+X(JCE2)
+X(JCE1)
+
+X(OSCG)
+X(OSC)
+X(SEDSTDBY)
+
+X(SEDGA)
+X(SEDENABLE)
+X(SEDSTART)
+X(SEDFRCERR)
+X(SEDDONE)
+X(SEDINPROG)
+X(SEDERR)
+
+X(DTR)
+X(STARTPULSE)
+X(DTROUT0)
+X(DTROUT1)
+X(DTROUT2)
+X(DTROUT3)
+X(DTROUT4)
+X(DTROUT5)
+X(DTROUT6)
+X(DTROUT7)
+
+X(USRMCLK)
+
+X(CLKDIVF)
+X(ALIGNWD)
+X(CDIVX)
+
+X(ECLKSYNCB)
+X(ECLKI)
+X(STOP)
+X(ECLKO)
+
+X(DLLDELD)
+X(A)
+X(DDRDEL)
+X(Z)
+
+X(DDRDLL)
+X(UDDCNTLN)
+X(FREEZE)
+X(DIVOSC)
+X(DCNTL0)
+X(DCNTL1)
+X(DCNTL2)
+X(DCNTL3)
+X(DCNTL4)
+X(DCNTL5)
+X(DCNTL6)
+X(DCNTL7)
+
+X(DQSBUFM)
+X(DQSI)
+X(READ1)
+X(READ0)
+X(READCLKSEL2)
+X(READCLKSEL1)
+X(READCLKSEL0)
+X(DYNDELAY0)
+X(DYNDELAY1)
+X(DYNDELAY2)
+X(DYNDELAY3)
+X(DYNDELAY4)
+X(DYNDELAY5)
+X(DYNDELAY6)
+X(DYNDELAY7)
+X(PAUSE)
+X(RDLOADN)
+X(RDMOVE)
+X(RDDIRECTION)
+X(WRLOADN)
+X(WRMOVE)
+X(WRDIRECTION)
+X(DATAVALID)
+X(BURSTDET)
+X(RDCFLAG)
+X(WRCFLAG)
+X(SCLK)