Merge pull request #970 from yrabbit/nr9-wip
gowin: handle the GW1N-9 feature.
This commit is contained in:
commit
fcf2bf6a95
@ -1119,7 +1119,7 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
z++; /* fall-through*/
|
z++; /* fall-through*/
|
||||||
case ID_IOBB:
|
case ID_IOBB:
|
||||||
z++; /* fall-through*/
|
z++; /* fall-through*/
|
||||||
case ID_IOBA:
|
case ID_IOBA: {
|
||||||
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
||||||
belname = id(buf);
|
belname = id(buf);
|
||||||
addBel(belname, id_IOB, Loc(col, row, z), false);
|
addBel(belname, id_IOB, Loc(col, row, z), false);
|
||||||
@ -1132,7 +1132,22 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_OE)->src_id);
|
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_OE)->src_id);
|
||||||
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
addBelInput(belname, id_OEN, id(buf));
|
addBelInput(belname, id_OEN, id(buf));
|
||||||
break;
|
// GW1NR-9 quirk
|
||||||
|
const PairPOD *xxx_port = pairLookup(bel->ports.get(), bel->num_ports, ID_XXX_VSS0);
|
||||||
|
if (xxx_port != nullptr) {
|
||||||
|
gw1n9_quirk = true;
|
||||||
|
portname = IdString(xxx_port->src_id);
|
||||||
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
|
addBelInput(belname, id_XXX_VSS0, id(buf));
|
||||||
|
}
|
||||||
|
xxx_port = pairLookup(bel->ports.get(), bel->num_ports, ID_XXX_VSS1);
|
||||||
|
if (xxx_port != nullptr) {
|
||||||
|
gw1n9_quirk = true;
|
||||||
|
portname = IdString(xxx_port->src_id);
|
||||||
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
|
addBelInput(belname, id_XXX_VSS1, id(buf));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
// Simplified IO
|
// Simplified IO
|
||||||
case ID_IOBJS:
|
case ID_IOBJS:
|
||||||
z++; /* fall-through*/
|
z++; /* fall-through*/
|
||||||
|
@ -472,6 +472,8 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
|
|
||||||
// XXX GW1N-9C DDR quirk
|
// XXX GW1N-9C DDR quirk
|
||||||
bool ddr_has_extra_inputs = false;
|
bool ddr_has_extra_inputs = false;
|
||||||
|
// XXX GW1NR-9 iobuf quirk
|
||||||
|
bool gw1n9_quirk = false;
|
||||||
|
|
||||||
// Permissible combinations of modes in a single slice
|
// Permissible combinations of modes in a single slice
|
||||||
std::map<const IdString, IdString> dff_comp_mode;
|
std::map<const IdString, IdString> dff_comp_mode;
|
||||||
|
@ -683,6 +683,8 @@ X(IOBJS)
|
|||||||
X(TX)
|
X(TX)
|
||||||
X(XXX_VSS)
|
X(XXX_VSS)
|
||||||
X(XXX_VCC)
|
X(XXX_VCC)
|
||||||
|
X(XXX_VSS0)
|
||||||
|
X(XXX_VSS1)
|
||||||
X(OBUF_TYPE)
|
X(OBUF_TYPE)
|
||||||
X(SBUF)
|
X(SBUF)
|
||||||
X(DBUF)
|
X(DBUF)
|
||||||
|
@ -805,6 +805,14 @@ static void pack_iologic(Context *ctx)
|
|||||||
ci->addInput(id_XXX_VCC);
|
ci->addInput(id_XXX_VCC);
|
||||||
ci->connectPort(id_XXX_VCC, ctx->nets[ctx->id("$PACKER_VCC_NET")].get());
|
ci->connectPort(id_XXX_VCC, ctx->nets[ctx->id("$PACKER_VCC_NET")].get());
|
||||||
}
|
}
|
||||||
|
if (ctx->gw1n9_quirk && iob_bel != q0_dst->attrs.end()) {
|
||||||
|
bool have_XXX_VSS0 =
|
||||||
|
ctx->bels[ctx->getBelByNameStr(iob_bel->second.as_string())].pins.count(id_XXX_VSS0);
|
||||||
|
if (have_XXX_VSS0) {
|
||||||
|
q0_dst->disconnectPort(id_XXX_VSS0);
|
||||||
|
q0_dst->connectPort(id_XXX_VSS0, ctx->nets[ctx->id("$PACKER_VCC_NET")].get());
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -933,6 +941,7 @@ static void pack_io(Context *ctx)
|
|||||||
// what type to create
|
// what type to create
|
||||||
IdString new_cell_type = id_IOB;
|
IdString new_cell_type = id_IOB;
|
||||||
std::string constr_bel_name = std::string("");
|
std::string constr_bel_name = std::string("");
|
||||||
|
bool have_xxx_port = false;
|
||||||
// check whether the given IO is limited to simplified IO cells
|
// check whether the given IO is limited to simplified IO cells
|
||||||
auto constr_bel = ci->attrs.find(id_BEL);
|
auto constr_bel = ci->attrs.find(id_BEL);
|
||||||
if (constr_bel != ci->attrs.end()) {
|
if (constr_bel != ci->attrs.end()) {
|
||||||
@ -946,6 +955,9 @@ static void pack_io(Context *ctx)
|
|||||||
BelId constr_bel = ctx->getBelByNameStr(constr_bel_name);
|
BelId constr_bel = ctx->getBelByNameStr(constr_bel_name);
|
||||||
if (constr_bel != BelId()) {
|
if (constr_bel != BelId()) {
|
||||||
new_cell_type = ctx->bels[constr_bel].type;
|
new_cell_type = ctx->bels[constr_bel].type;
|
||||||
|
if (ctx->gw1n9_quirk) {
|
||||||
|
have_xxx_port = ctx->bels[constr_bel].pins.count(id_XXX_VSS0) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,6 +966,13 @@ static void pack_io(Context *ctx)
|
|||||||
gwio_to_iob(ctx, ci, ice_cell.get(), packed_cells);
|
gwio_to_iob(ctx, ci, ice_cell.get(), packed_cells);
|
||||||
new_cells.push_back(std::move(ice_cell));
|
new_cells.push_back(std::move(ice_cell));
|
||||||
auto gwiob = new_cells.back().get();
|
auto gwiob = new_cells.back().get();
|
||||||
|
// XXX GW1NR-9 quirks
|
||||||
|
if (have_xxx_port && ci->type != id_IBUF) {
|
||||||
|
gwiob->addInput(id_XXX_VSS0);
|
||||||
|
gwiob->connectPort(id_XXX_VSS0, ctx->nets[ctx->id("$PACKER_GND_NET")].get());
|
||||||
|
gwiob->addInput(id_XXX_VSS1);
|
||||||
|
gwiob->connectPort(id_XXX_VSS1, ctx->nets[ctx->id("$PACKER_GND_NET")].get());
|
||||||
|
}
|
||||||
|
|
||||||
packed_cells.insert(ci->name);
|
packed_cells.insert(ci->name);
|
||||||
if (iob != nullptr) {
|
if (iob != nullptr) {
|
||||||
|
Loading…
Reference in New Issue
Block a user