ecp5: Fix packing of IOFF with IODELAYs
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
06d58e6eed
commit
ce030a474c
10
ecp5/cells.h
10
ecp5/cells.h
@ -21,6 +21,7 @@
|
|||||||
#define ECP5_CELLS_H
|
#define ECP5_CELLS_H
|
||||||
|
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
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)
|
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") ||
|
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)
|
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") ||
|
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);
|
void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool driven_by_lut);
|
||||||
|
@ -2316,7 +2316,9 @@ class Ecp5Packer
|
|||||||
set_iologic_mode(iol, "IREG_OREG");
|
set_iologic_mode(iol, "IREG_OREG");
|
||||||
bool drives_iologic = false;
|
bool drives_iologic = false;
|
||||||
for (auto user : ci->ports.at(ctx->id("Z")).net->users)
|
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;
|
drives_iologic = true;
|
||||||
if (drives_iologic) {
|
if (drives_iologic) {
|
||||||
// Reconnect to PIO which the packer expects later on
|
// Reconnect to PIO which the packer expects later on
|
||||||
|
Loading…
Reference in New Issue
Block a user