Merge pull request #884 from yrabbit/simplified-io-pr
gowin: Add simplified IO cells processing
This commit is contained in:
commit
643b697178
@ -870,6 +870,39 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
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;
|
break;
|
||||||
|
// Simplified IO
|
||||||
|
case ID_IOBJS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBIS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBHS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBGS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBFS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBES:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBDS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBCS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBBS:
|
||||||
|
z++; /* fall-through*/
|
||||||
|
case ID_IOBAS:
|
||||||
|
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
||||||
|
belname = id(buf);
|
||||||
|
addBel(belname, id_IOBS, Loc(col, row, z), false);
|
||||||
|
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_O)->src_id);
|
||||||
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
|
addBelOutput(belname, id_O, id(buf));
|
||||||
|
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_I)->src_id);
|
||||||
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
|
addBelInput(belname, id_I, id(buf));
|
||||||
|
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));
|
||||||
|
addBelInput(belname, id_OEN, id(buf));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -64,14 +64,14 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
|
|||||||
add_port(ctx, new_cell.get(), id_I1, PORT_IN);
|
add_port(ctx, new_cell.get(), id_I1, PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), id_SEL, PORT_IN);
|
add_port(ctx, new_cell.get(), id_SEL, PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), id_OF, PORT_OUT);
|
add_port(ctx, new_cell.get(), id_OF, PORT_OUT);
|
||||||
} else if (type == id_IOB) {
|
} else if (type == id_IOB || type == id_IOBS) {
|
||||||
new_cell->params[id_INPUT_USED] = 0;
|
new_cell->params[id_INPUT_USED] = 0;
|
||||||
new_cell->params[id_OUTPUT_USED] = 0;
|
new_cell->params[id_OUTPUT_USED] = 0;
|
||||||
new_cell->params[id_ENABLE_USED] = 0;
|
new_cell->params[id_ENABLE_USED] = 0;
|
||||||
|
|
||||||
add_port(ctx, new_cell.get(), id_PAD, PORT_INOUT);
|
add_port(ctx, new_cell.get(), id_PAD, PORT_INOUT);
|
||||||
add_port(ctx, new_cell.get(), id_I, PORT_IN);
|
add_port(ctx, new_cell.get(), id_I, PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), id_EN, PORT_IN);
|
add_port(ctx, new_cell.get(), id_OEN, PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), id_O, PORT_OUT);
|
add_port(ctx, new_cell.get(), id_O, PORT_OUT);
|
||||||
} else {
|
} else {
|
||||||
log_error("unable to create generic cell of type %s\n", type.c_str(ctx));
|
log_error("unable to create generic cell of type %s\n", type.c_str(ctx));
|
||||||
@ -140,9 +140,17 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
|
|||||||
void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, pool<IdString> &todelete_cells)
|
void gwio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, pool<IdString> &todelete_cells)
|
||||||
{
|
{
|
||||||
if (nxio->type == id_IBUF) {
|
if (nxio->type == id_IBUF) {
|
||||||
|
if (iob->type == id_IOBS) {
|
||||||
|
// VCC -> OEN
|
||||||
|
connect_port(ctx, ctx->nets[ctx->id("$PACKER_VCC_NET")].get(), iob, id_OEN);
|
||||||
|
}
|
||||||
iob->params[id_INPUT_USED] = 1;
|
iob->params[id_INPUT_USED] = 1;
|
||||||
replace_port(nxio, id_O, iob, id_O);
|
replace_port(nxio, id_O, iob, id_O);
|
||||||
} else if (nxio->type == id_OBUF) {
|
} else if (nxio->type == id_OBUF) {
|
||||||
|
if (iob->type == id_IOBS) {
|
||||||
|
// VSS -> OEN
|
||||||
|
connect_port(ctx, ctx->nets[ctx->id("$PACKER_GND_NET")].get(), iob, id_OEN);
|
||||||
|
}
|
||||||
iob->params[id_OUTPUT_USED] = 1;
|
iob->params[id_OUTPUT_USED] = 1;
|
||||||
replace_port(nxio, id_I, iob, id_I);
|
replace_port(nxio, id_I, iob, id_I);
|
||||||
} else if (nxio->type == id_TBUF) {
|
} else if (nxio->type == id_TBUF) {
|
||||||
|
@ -358,6 +358,19 @@ X(IOBH)
|
|||||||
X(IOBI)
|
X(IOBI)
|
||||||
X(IOBJ)
|
X(IOBJ)
|
||||||
|
|
||||||
|
// simplified iobs
|
||||||
|
X(IOBS)
|
||||||
|
X(IOBAS)
|
||||||
|
X(IOBBS)
|
||||||
|
X(IOBCS)
|
||||||
|
X(IOBDS)
|
||||||
|
X(IOBES)
|
||||||
|
X(IOBFS)
|
||||||
|
X(IOBGS)
|
||||||
|
X(IOBHS)
|
||||||
|
X(IOBIS)
|
||||||
|
X(IOBJS)
|
||||||
|
|
||||||
// Wide LUTs
|
// Wide LUTs
|
||||||
X(MUX2_LUT5)
|
X(MUX2_LUT5)
|
||||||
X(MUX2_LUT6)
|
X(MUX2_LUT6)
|
||||||
|
@ -629,7 +629,7 @@ static void pack_constants(Context *ctx)
|
|||||||
|
|
||||||
std::vector<IdString> dead_nets;
|
std::vector<IdString> dead_nets;
|
||||||
|
|
||||||
bool gnd_used = false;
|
bool gnd_used = true; // XXX May be needed for simplified IO
|
||||||
|
|
||||||
for (auto &net : ctx->nets) {
|
for (auto &net : ctx->nets) {
|
||||||
NetInfo *ni = net.second.get();
|
NetInfo *ni = net.second.get();
|
||||||
@ -718,8 +718,27 @@ static void pack_io(Context *ctx)
|
|||||||
}
|
}
|
||||||
packed_cells.insert(iob->name);
|
packed_cells.insert(iob->name);
|
||||||
}
|
}
|
||||||
|
// what type to create
|
||||||
|
IdString new_cell_type = id_IOB;
|
||||||
|
std::string constr_bel_name = std::string("");
|
||||||
|
// check whether the given IO is limited to simplified IO cells
|
||||||
|
auto constr_bel = ci->attrs.find(id_BEL);
|
||||||
|
if (constr_bel != ci->attrs.end()) {
|
||||||
|
constr_bel_name = constr_bel->second.as_string();
|
||||||
|
}
|
||||||
|
constr_bel = iob->attrs.find(id_BEL);
|
||||||
|
if (constr_bel != iob->attrs.end()) {
|
||||||
|
constr_bel_name = constr_bel->second.as_string();
|
||||||
|
}
|
||||||
|
if (!constr_bel_name.empty()) {
|
||||||
|
BelId constr_bel = ctx->getBelByNameStr(constr_bel_name);
|
||||||
|
if (constr_bel != BelId()) {
|
||||||
|
new_cell_type = ctx->bels[constr_bel].type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create a IOB buffer
|
// Create a IOB buffer
|
||||||
std::unique_ptr<CellInfo> ice_cell = create_generic_cell(ctx, id_IOB, ci->name.str(ctx) + "$iob");
|
std::unique_ptr<CellInfo> ice_cell = create_generic_cell(ctx, new_cell_type, ci->name.str(ctx) + "$iob");
|
||||||
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();
|
||||||
|
Loading…
Reference in New Issue
Block a user