diff --git a/ecp5/cells.cc b/ecp5/cells.cc index fee1d982..58d4797c 100644 --- a/ecp5/cells.cc +++ b/ecp5/cells.cc @@ -127,11 +127,17 @@ std::unique_ptr create_ecp5_cell(Context *ctx, IdString type, std::str } else if (type == ctx->id("TRELLIS_IO")) { new_cell->params[ctx->id("DIR")] = "INPUT"; new_cell->attrs[ctx->id("IO_TYPE")] = "LVCMOS33"; + new_cell->params[ctx->id("DATAMUX_ODDR")] = "PADDO"; + new_cell->params[ctx->id("DATAMUX_MDDR")] = "PADDO"; add_port(ctx, new_cell.get(), "B", PORT_INOUT); add_port(ctx, new_cell.get(), "I", PORT_IN); add_port(ctx, new_cell.get(), "T", PORT_IN); add_port(ctx, new_cell.get(), "O", PORT_OUT); + + add_port(ctx, new_cell.get(), "IOLDO", PORT_IN); + add_port(ctx, new_cell.get(), "IOLTO", PORT_IN); + } else if (type == ctx->id("LUT4")) { new_cell->params[ctx->id("INIT")] = "0"; @@ -179,7 +185,6 @@ std::unique_ptr create_ecp5_cell(Context *ctx, IdString type, std::str new_cell->params[ctx->id("DELAY.DEL_VALUE")] = "0"; new_cell->params[ctx->id("DELAY.WAIT_FOR_EDGE")] = "DISABLED"; - new_cell->params[ctx->id("DATAMUX_ODDR")] = "PADDO"; if (type == id_IOLOGIC) { new_cell->params[ctx->id("IDDRXN.MODE")] = "NONE"; new_cell->params[ctx->id("ODDRXN.MODE")] = "NONE"; diff --git a/ecp5/pack.cc b/ecp5/pack.cc index 504ee784..a09480c2 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -1469,6 +1469,25 @@ class Ecp5Packer replace_port(ci, ctx->id("Q1"), iol, id_RXDATA1); iol->params[ctx->id("GSR")] = str_or_default(ci->params, ctx->id("GSR"), "DISABLED"); packed_cells.insert(cell.first); + } else if (ci->type == ctx->id("ODDRX1F")) { + CellInfo *pio = net_only_drives(ctx, ci->ports.at(ctx->id("Q")).net, is_trellis_io, id_I, true); + if (pio == nullptr) + log_error("ODDRX1F '%s' Q output must be connected only to a top level output\n", ci->name.c_str(ctx)); + CellInfo *iol; + if (pio_iologic.count(pio->name)) + iol = pio_iologic.at(pio->name); + else + iol = create_pio_iologic(pio, ci); + set_iologic_mode(iol, "IDDRX1_ODDRX1"); + replace_port(ci, ctx->id("Q"), iol, id_IOLDO); + replace_port(pio, id_PADDO, pio, id_IOLDO); + pio->params[ctx->id("DATAMUX_ODDR")] = "IOLDO"; + set_iologic_sclk(iol, ci, ctx->id("SCLK"), true); + set_iologic_lsr(iol, ci, ctx->id("RST"), true); + replace_port(ci, ctx->id("D0"), iol, id_TXDATA0); + replace_port(ci, ctx->id("D1"), iol, id_TXDATA1); + iol->params[ctx->id("GSR")] = str_or_default(ci->params, ctx->id("GSR"), "DISABLED"); + packed_cells.insert(cell.first); } } flush_cells();