gowin: Himbaechel. Add the GW1N-4 simple IOs

And also fix the clock router to allow (with a warning) non-dedicated
routing in case of false detection of clock wires.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2023-08-15 13:14:29 +10:00 committed by myrtle
parent 0994e11b73
commit 4d0afdfd60
3 changed files with 18 additions and 11 deletions

View File

@ -53,12 +53,12 @@ struct GowinGlobalRouter
bool dst_valid = dst_type.in(id_GLOBAL_CLK, id_TILE_CLK, id_PLL_I, id_IO_I, id_HCLK); bool dst_valid = dst_type.in(id_GLOBAL_CLK, id_TILE_CLK, id_PLL_I, id_IO_I, id_HCLK);
bool res = (src_valid && dst_valid) || (src_valid && is_local(dst_type)) || (is_local(src_type) && dst_valid); bool res = (src_valid && dst_valid) || (src_valid && is_local(dst_type)) || (is_local(src_type) && dst_valid);
if (ctx->debug && res && false) { if (ctx->debug && false /*&& res*/) {
log_info("%s <- %s [%s <- %s]\n", ctx->getWireName(ctx->getPipDstWire(pip)).str(ctx).c_str(), log_info("%s <- %s [%s <- %s]\n", ctx->getWireName(ctx->getPipDstWire(pip)).str(ctx).c_str(),
ctx->getWireName(ctx->getPipSrcWire(pip)).str(ctx).c_str(), dst_type.c_str(ctx), ctx->getWireName(ctx->getPipSrcWire(pip)).str(ctx).c_str(), dst_type.c_str(ctx),
src_type.c_str(ctx)); src_type.c_str(ctx));
// log_info("res:%d, src_valid:%d, dst_valid:%d, src local:%d, dst local:%d\n", res, src_valid, dst_valid, log_info("res:%d, src_valid:%d, dst_valid:%d, src local:%d, dst local:%d\n", res, src_valid, dst_valid,
// is_local(src_type), is_local(dst_type)); is_local(src_type), is_local(dst_type));
} }
return res; return res;
} }
@ -86,8 +86,9 @@ struct GowinGlobalRouter
log_error("Net '%s' has an invalid sink port %s.%s\n", ctx->nameOf(net), log_error("Net '%s' has an invalid sink port %s.%s\n", ctx->nameOf(net),
ctx->nameOf(net->users.at(user_idx).cell), ctx->nameOf(net->users.at(user_idx).port)); ctx->nameOf(net->users.at(user_idx).cell), ctx->nameOf(net->users.at(user_idx).port));
if (ctx->getBoundWireNet(src) != net) if (ctx->getBoundWireNet(src) != net) {
ctx->bindWire(src, net, STRENGTH_LOCKED); ctx->bindWire(src, net, STRENGTH_LOCKED);
}
if (src == dst) { if (src == dst) {
// Nothing more to do // Nothing more to do
@ -152,10 +153,15 @@ struct GowinGlobalRouter
} }
return true; return true;
} else { } else {
if (strict) if (strict) {
log_error("Failed to route net '%s' from %s to %s using dedicated routing.\n", ctx->nameOf(net), log_error("Failed to route net '%s' from %s to %s using dedicated routing.\n", ctx->nameOf(net),
ctx->nameOfWire(src), ctx->nameOfWire(dst)); ctx->nameOfWire(src), ctx->nameOfWire(dst));
return false; } else {
log_warning("Failed to route net '%s' from %s to %s using dedicated routing.\n", ctx->nameOf(net),
ctx->nameOfWire(src), ctx->nameOfWire(dst));
ctx->unbindWire(src);
return false;
}
} }
} }
@ -163,7 +169,7 @@ struct GowinGlobalRouter
{ {
bool routed = false; bool routed = false;
for (auto usr : net->users.enumerate()) { for (auto usr : net->users.enumerate()) {
routed = backwards_bfs_route(net, usr.index, 1000000, true, [&](PipId pip) { routed = backwards_bfs_route(net, usr.index, 1000000, false, [&](PipId pip) {
return (is_relaxed_sink(usr.value) || global_pip_filter(pip)); return (is_relaxed_sink(usr.value) || global_pip_filter(pip));
}); });
if (!routed) { if (!routed) {

View File

@ -337,7 +337,6 @@ def create_tiletype(create_func, chip: Chip, db: chipdb, x: int, y: int, ttyp: i
return return
tt = create_func(chip, db, x, y, ttyp, tdesc) tt = create_func(chip, db, x, y, ttyp, tdesc)
print(ttyp, tdesc.tiletype)
create_extra_funcs(tt, db, x, y) create_extra_funcs(tt, db, x, y)
create_hclk_switch_matrix(tt, db, x, y) create_hclk_switch_matrix(tt, db, x, y)
@ -386,7 +385,7 @@ def create_io_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc:
tt = chip.create_tile_type(tiletype) tt = chip.create_tile_type(tiletype)
tt.extra_data = TileExtraData(chip.strs.id(typename)) tt.extra_data = TileExtraData(chip.strs.id(typename))
simple_io = y in db.simplio_rows and chip.name in {'GW1N-1', 'GW1NZ-1'} simple_io = y in db.simplio_rows and chip.name in {'GW1N-1', 'GW1NZ-1', 'GW1N-4'}
if simple_io: if simple_io:
rng = 10 rng = 10
else: else:
@ -559,7 +558,7 @@ _pll_inputs = {'CLKFB', 'FBDSEL0', 'FBDSEL1', 'FBDSEL2', 'FBDSEL3',
'IDSEL4', 'IDSEL5', 'ODSEL0', 'ODSEL1', 'ODSEL2', 'ODSEL3', 'IDSEL4', 'IDSEL5', 'ODSEL0', 'ODSEL1', 'ODSEL2', 'ODSEL3',
'ODSEL4', 'ODSEL5', 'RESET', 'RESET_P', 'PSDA0', 'PSDA1', 'ODSEL4', 'ODSEL5', 'RESET', 'RESET_P', 'PSDA0', 'PSDA1',
'PSDA2', 'PSDA3', 'DUTYDA0', 'DUTYDA1', 'DUTYDA2', 'DUTYDA3', 'PSDA2', 'PSDA3', 'DUTYDA0', 'DUTYDA1', 'DUTYDA2', 'DUTYDA3',
'FDLY0', 'FDLY1', 'FDLY2', 'FDLY3', 'CLKIN'} 'FDLY0', 'FDLY1', 'FDLY2', 'FDLY3', 'CLKIN', 'VREN'}
_pll_outputs = {'CLKOUT', 'LOCK', 'CLKOUTP', 'CLKOUTD', 'CLKOUTD3'} _pll_outputs = {'CLKOUT', 'LOCK', 'CLKOUTP', 'CLKOUTD', 'CLKOUTD3'}
def create_pll_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc): def create_pll_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc):
typename = "PLL" typename = "PLL"

View File

@ -151,7 +151,9 @@ struct GowinPacker
BelId bind_io(CellInfo &ci) BelId bind_io(CellInfo &ci)
{ {
BelId bel = ctx->getBelByName(IdStringList::parse(ctx, ci.attrs.at(id_BEL).as_string())); BelId bel = ctx->getBelByName(IdStringList::parse(ctx, ci.attrs.at(id_BEL).as_string()));
NPNR_ASSERT(bel != BelId()); if (bel == BelId()) {
log_error("No bel named %s\n", IdStringList::parse(ctx, ci.attrs.at(id_BEL).as_string()).str(ctx).c_str());
}
ci.unsetAttr(id_BEL); ci.unsetAttr(id_BEL);
ctx->bindBel(bel, &ci, PlaceStrength::STRENGTH_LOCKED); ctx->bindBel(bel, &ci, PlaceStrength::STRENGTH_LOCKED);
return bel; return bel;