aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-11-05 15:16:43 +0000
committergatecat <gatecat@ds0.me>2021-11-05 15:16:43 +0000
commitce030a474ca28dcc309892439b0dab331c4f73b0 (patch)
tree9e20c7b7c68f1b1d9679afb3db3c1c13620b0fe9 /ecp5
parent06d58e6eed90aa9c2d16d0fe6286ec59a2f880a2 (diff)
downloadnextpnr-ce030a474ca28dcc309892439b0dab331c4f73b0.tar.gz
nextpnr-ce030a474ca28dcc309892439b0dab331c4f73b0.tar.bz2
nextpnr-ce030a474ca28dcc309892439b0dab331c4f73b0.zip
ecp5: Fix packing of IOFF with IODELAYs
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/cells.h10
-rw-r--r--ecp5/pack.cc4
2 files changed, 11 insertions, 3 deletions
diff --git a/ecp5/cells.h b/ecp5/cells.h
index 4289a84a..c1165ddc 100644
--- a/ecp5/cells.h
+++ b/ecp5/cells.h
@@ -21,6 +21,7 @@
#define ECP5_CELLS_H
#include "nextpnr.h"
+#include "util.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -49,12 +50,17 @@ inline bool is_l6mux(const BaseCtx *ctx, const CellInfo *cell) { return cell->ty
inline bool is_iologic_input_cell(const BaseCtx *ctx, const CellInfo *cell)
{
return cell->type == ctx->id("IDDRX1F") || cell->type == ctx->id("IDDRX2F") || cell->type == ctx->id("IDDR71B") ||
- cell->type == ctx->id("IDDRX2DQA");
+ cell->type == ctx->id("IDDRX2DQA") ||
+ (cell->type == ctx->id("TRELLIS_FF") && bool_or_default(cell->attrs, ctx->id("syn_useioff")) &&
+ (str_or_default(cell->attrs, ctx->id("ioff_dir"), "") != "output"));
}
inline bool is_iologic_output_cell(const BaseCtx *ctx, const CellInfo *cell)
{
return cell->type == ctx->id("ODDRX1F") || cell->type == ctx->id("ODDRX2F") || cell->type == ctx->id("ODDR71B") ||
- cell->type == ctx->id("ODDRX2DQA") || cell->type == ctx->id("ODDRX2DQSB") || cell->type == ctx->id("OSHX2A");
+ cell->type == ctx->id("ODDRX2DQA") || cell->type == ctx->id("ODDRX2DQSB") ||
+ cell->type == ctx->id("OSHX2A") ||
+ (cell->type == ctx->id("TRELLIS_FF") && bool_or_default(cell->attrs, ctx->id("syn_useioff")) &&
+ (str_or_default(cell->attrs, ctx->id("ioff_dir"), "") != "input"));
}
void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool driven_by_lut);
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 66cb81b2..cbf882a8 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -2316,7 +2316,9 @@ class Ecp5Packer
set_iologic_mode(iol, "IREG_OREG");
bool drives_iologic = false;
for (auto user : ci->ports.at(ctx->id("Z")).net->users)
- if (is_iologic_input_cell(ctx, user.cell) && user.port == ctx->id("D"))
+ if (is_iologic_input_cell(ctx, user.cell) &&
+ (user.port == ctx->id("D") ||
+ (user.cell->type == ctx->id("TRELLIS_FF") && user.port == ctx->id("DI"))))
drives_iologic = true;
if (drives_iologic) {
// Reconnect to PIO which the packer expects later on