diff options
author | YRabbit <rabbit@yrabbit.cyou> | 2023-04-14 16:54:08 +1000 |
---|---|---|
committer | myrtle <gatecat@ds0.me> | 2023-04-14 09:23:00 +0200 |
commit | 71192dc7a3b8dfae1f76f48412dd906bfb0783e7 (patch) | |
tree | 9ba977ffaa87b5fef166b68f1d97f37cb9dc07f3 /gowin/pack.cc | |
parent | b0a78de78f213d6cb169a22e38179c48f3dc02fc (diff) | |
download | nextpnr-71192dc7a3b8dfae1f76f48412dd906bfb0783e7.tar.gz nextpnr-71192dc7a3b8dfae1f76f48412dd906bfb0783e7.tar.bz2 nextpnr-71192dc7a3b8dfae1f76f48412dd906bfb0783e7.zip |
gowin: Remove inherited code for ODDR(c)
Implement ODDR(c) as part of IOLOGIC and remove all old code associated
with those primitives.
Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
Diffstat (limited to 'gowin/pack.cc')
-rw-r--r-- | gowin/pack.cc | 109 |
1 files changed, 29 insertions, 80 deletions
diff --git a/gowin/pack.cc b/gowin/pack.cc index 2ff42e55..c9ca635b 100644 --- a/gowin/pack.cc +++ b/gowin/pack.cc @@ -903,79 +903,15 @@ static void pack_iologic(Context *ctx) CellInfo *q0_dst = nullptr; CellInfo *q1_dst = nullptr; switch (ci->type.hash()) { - case ID_ODDRC: /* fall-through*/ - case ID_ODDR: { - q0_dst = net_only_drives(ctx, ci->ports.at(id_Q0).net, is_iob, id_I); - NPNR_ASSERT(q0_dst != nullptr); - - auto iob_bel = q0_dst->attrs.find(id_BEL); - if (q0_dst->attrs.count(id_DIFF_TYPE)) { - ci->attrs[id_OBUF_TYPE] = std::string("DBUF"); - } else { - ci->attrs[id_OBUF_TYPE] = std::string("SBUF"); - } - if (iob_bel != q0_dst->attrs.end()) { - // already know there to place, no need of any cluster stuff - Loc loc = ctx->getBelLocation(ctx->getBelByNameStr(iob_bel->second.as_string())); - loc.z += BelZ::oddr_0_z; - ci->attrs[id_BEL] = ctx->getBelName(ctx->getBelByLocation(loc)).str(ctx); - } else { - // make cluster from ODDR and OBUF - ci->cluster = ci->name; - ci->constr_x = 0; - ci->constr_y = 0; - ci->constr_z = 0; - ci->constr_abs_z = false; - ci->constr_children.push_back(q0_dst); - q0_dst->cluster = ci->name; - q0_dst->constr_x = 0; - q0_dst->constr_y = 0; - q0_dst->constr_z = -BelZ::oddr_0_z; - q0_dst->constr_abs_z = false; - } - - // disconnect Q0 output: it is wired internally - delete_nets.insert(ci->ports.at(id_Q0).net->name); - q0_dst->disconnectPort(id_I); - ci->disconnectPort(id_Q0); - - ci->attrs[id_IOBUF] = 0; - // if Q1 is conected then disconnet it too - if (port_used(ci, id_Q1)) { - q1_dst = net_only_drives(ctx, ci->ports.at(id_Q1).net, is_iob, id_OEN); - if (q1_dst != nullptr) { - delete_nets.insert(ci->ports.at(id_Q1).net->name); - q0_dst->disconnectPort(id_OEN); - ci->disconnectPort(id_Q1); - ci->attrs[id_IOBUF] = 1; - } - } - // if have XXX_ inputs connect them - if (ctx->ddr_has_extra_inputs) { - ci->addInput(id_ODDR_ALWAYS_LOW); - ci->connectPort(id_ODDR_ALWAYS_LOW, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); - ci->addInput(id_ODDR_ALWAYS_HIGH); - ci->connectPort(id_ODDR_ALWAYS_HIGH, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - if (iob_bel != q0_dst->attrs.end()) { - IdString io_bel_name = ctx->getBelByNameStr(iob_bel->second.as_string()); - if (ctx->gw1n9_quirk && ctx->bels.at(io_bel_name).pins.count(id_GW9_ALWAYS_LOW0)) { - q0_dst->disconnectPort(id_GW9_ALWAYS_LOW0); - q0_dst->connectPort(id_GW9_ALWAYS_LOW0, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - if (ctx->bels.at(io_bel_name).pins.count(id_GW9C_ALWAYS_LOW1)) { - q0_dst->disconnectPort(id_GW9C_ALWAYS_LOW1); - q0_dst->connectPort(id_GW9C_ALWAYS_LOW1, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); - } - } - } break; + case ID_ODDR: /* fall-through */ + case ID_ODDRC: /* fall-through */ case ID_OSER4: /* fall-through */ case ID_OSER8: /* fall-through */ case ID_OSER10: /* fall-through */ case ID_OVIDEO: { IdString output = id_Q; IdString output_1 = IdString(); - if (ci->type == id_OSER4 || ci->type == id_OSER8) { + if (ci->type == id_ODDR || ci->type == id_ODDRC || ci->type == id_OSER4 || ci->type == id_OSER8) { output = id_Q0; output_1 = id_Q1; } @@ -999,6 +935,10 @@ static void pack_iologic(Context *ctx) std::string out_mode; switch (ci->type.hash()) { + case ID_ODDR: + case ID_ODDRC: + out_mode = "ODDRX1"; + break; case ID_OSER4: out_mode = "ODDRX2"; break; @@ -1025,12 +965,18 @@ static void pack_iologic(Context *ctx) delete_nets.insert(ci->ports.at(output).net->name); q0_dst->disconnectPort(id_I); ci->disconnectPort(output); - bool have_XXX = - ctx->bels.at(ctx->getBelByNameStr(iob_bel->second.as_string())).pins.count(id_GW9C_ALWAYS_LOW1); - if (have_XXX) { + if (ctx->bels.at(ctx->getBelByNameStr(iob_bel->second.as_string())).pins.count(id_GW9C_ALWAYS_LOW1)) { q0_dst->disconnectPort(id_GW9C_ALWAYS_LOW1); q0_dst->connectPort(id_GW9C_ALWAYS_LOW1, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); } + if (ctx->bels.at(ctx->getBelByLocation(loc)).pins.count(id_DAADJ0)) { + ci->addInput(id_DAADJ0); + ci->connectPort(id_DAADJ0, ctx->nets[ctx->id("$PACKER_GND_NET")].get()); + } + if (ctx->bels.at(ctx->getBelByLocation(loc)).pins.count(id_DAADJ1)) { + ci->addInput(id_DAADJ1); + ci->connectPort(id_DAADJ1, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); + } // if Q1 is connected then disconnet it too if (output_1 != IdString() && port_used(ci, output_1)) { @@ -1057,16 +1003,19 @@ static void pack_iologic(Context *ctx) ci->setAttr(id_IOBUF, 0); ci->setAttr(id_IOLOGIC_TYPE, ci->type.str(ctx)); - if (ci->type == id_OSER4) { - // two OSER4 share FCLK, check it - Loc other_loc = loc; - other_loc.z = 1 - loc.z + 2 * BelZ::iologic_z; - BelId other_bel = ctx->getBelByLocation(other_loc); - CellInfo *other_cell = ctx->getBoundBelCell(other_bel); - if (other_cell != nullptr) { - NPNR_ASSERT(other_cell->type == id_OSER4); - if (ci->ports.at(id_FCLK).net != other_cell->ports.at(id_FCLK).net) { - log_error("%s and %s have differnet FCLK nets\n", ctx->nameOf(ci), ctx->nameOf(other_cell)); + if (ci->type == id_OSER4 || ci->type == id_ODDR || ci->type == id_ODDRC) { + if (ci->type == id_OSER4) { + // two OSER4 share FCLK, check it + Loc other_loc = loc; + other_loc.z = 1 - loc.z + 2 * BelZ::iologic_z; + BelId other_bel = ctx->getBelByLocation(other_loc); + CellInfo *other_cell = ctx->getBoundBelCell(other_bel); + if (other_cell != nullptr) { + NPNR_ASSERT(other_cell->type == id_OSER4); + if (ci->ports.at(id_FCLK).net != other_cell->ports.at(id_FCLK).net) { + log_error("%s and %s have differnet FCLK nets\n", ctx->nameOf(ci), + ctx->nameOf(other_cell)); + } } } } else { |