gowin: Himbaechel. Implement the GSR primitive

On GW2A chips, the global set/reset is in its own cell.
Also corrections to ALU generation.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2023-07-19 13:29:18 +10:00 committed by myrtle
parent 6cac19c055
commit b2ec06dfe8
4 changed files with 77 additions and 2 deletions

View File

@ -1076,3 +1076,11 @@ X(MUX_SEL)
X(ALU_CIN)
X(ALU_COUT)
// fake dff inputs
X(XD0)
X(XD1)
X(XD2)
X(XD3)
X(XD4)
X(XD5)

View File

@ -90,6 +90,7 @@ void GowinImpl::init(Context *ctx)
partno = ctx->id(pn);
ctx->settings[ctx->id("packer.partno")] = pn;
// package and speed class
std::regex speedre = std::regex("(.*)(C[0-9]/I[0-9])$");
std::smatch match;
@ -106,7 +107,7 @@ void GowinImpl::init(Context *ctx)
}
if (ctx->debug) {
log_info("packages:%d\n", ctx->chip_info->packages.ssize());
log_info("packages:%ld\n", ctx->chip_info->packages.ssize());
}
for (int i = 0; i < ctx->chip_info->packages.ssize(); ++i) {
if (IdString(ctx->chip_info->packages[i].name) == package_idx) {
@ -121,6 +122,7 @@ void GowinImpl::init(Context *ctx)
log_error("No package for partnumber %s\n", partno.c_str(ctx));
}
// constraints
if (args.options.count("cst")) {
ctx->settings[ctx->id("cst.filename")] = args.options.at("cst");
}

View File

@ -22,6 +22,7 @@ MUX27_Z = 29
ALU0_Z = 30 # : 35, 6 ALUs
RAMW_Z = 36 # RAM16SDP4
GSR_Z = 276
VCC_Z = 277
GND_Z = 278
@ -140,6 +141,8 @@ def create_switch_matrix(tt: TileType, db: chipdb, x: int, y: int):
def get_wire_type(name):
if name.startswith('GB') or name.startswith('GT'):
return "GLOBAL_CLK"
elif name in {'XD0', 'XD1', 'XD2', 'XD3', 'XD4', 'XD5',}:
return "X0"
return ""
for dst, srcs in db.grid[y][x].pips.items():
@ -188,6 +191,22 @@ def create_corner_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int):
create_switch_matrix(tt, db, x, y)
return (ttyp, tt)
# Global set/reset. GW2A series has special cell for it
def create_gsr_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int):
if ttyp in created_tiletypes:
return ttyp, None
typename = "GSR"
tt = chip.create_tile_type(f"{typename}_{ttyp}")
tt.extra_data = TileExtraData(chip.strs.id(typename))
portmap = db.grid[y][x].bels['GSR'].portmap
tt.create_wire(portmap['GSRI'], "GSRI")
io = tt.create_bel("GSR", "GSR", z = GSR_Z)
tt.add_bel_pin(io, "GSRI", portmap['GSRI'], PinType.INPUT)
create_switch_matrix(tt, db, x, y)
return (ttyp, tt)
# simple IO - only A and B
def create_io_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int):
if ttyp in created_tiletypes:
@ -393,6 +412,7 @@ def main():
logic_tiletypes = {12, 13, 14, 15, 16}
io_tiletypes = {52, 53, 55, 58, 59, 64, 65, 66}
ssram_tiletypes = {17, 18, 19}
gsr_tiletypes = {1}
# Setup tile grid
for x in range(X):
for y in range(Y):
@ -403,7 +423,11 @@ def main():
created_tiletypes.add(ttyp)
ch.set_tile_type(x, y, f"CORNER_{ttyp}")
continue
if ttyp in logic_tiletypes:
if ttyp in gsr_tiletypes:
ttyp, _ = create_gsr_tiletype(ch, db, x, y, ttyp)
created_tiletypes.add(ttyp)
ch.set_tile_type(x, y, f"GSR_{ttyp}")
elif ttyp in logic_tiletypes:
ttyp, _ = create_logic_tiletype(ch, db, x, y, ttyp)
created_tiletypes.add(ttyp)
ch.set_tile_type(x, y, f"LOGIC_{ttyp}")

View File

@ -249,10 +249,14 @@ struct GowinPacker
if (cin_net->name == ctx->id("$PACKER_GND")) {
cin_ci->params[id_ALU_MODE] = std::string("C2L");
cin_ci->addInput(id_I2);
cin_ci->connectPort(id_I2, ctx->nets[ctx->id("$PACKER_VCC")].get());
return cin_ci;
}
if (cin_net->name == ctx->id("$PACKER_VCC")) {
cin_ci->params[id_ALU_MODE] = std::string("ONE2C");
cin_ci->addInput(id_I2);
cin_ci->connectPort(id_I2, ctx->nets[ctx->id("$PACKER_VCC")].get());
return cin_ci;
}
// CIN from logic
@ -501,10 +505,47 @@ struct GowinPacker
}
}
// Pack global set-reset
void pack_gsr(void)
{
log_info("Packing GSR..\n");
bool user_gsr = false;
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
if (ctx->verbose)
log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx));
if (ci->type == id_GSR) {
user_gsr = true;
break;
}
}
if (!user_gsr) {
bool have_gsr_bel = false;
auto bels = ctx->getBels();
for (auto bid : bels) {
if (ctx->getBelType(bid) == id_GSR) {
have_gsr_bel = true;
break;
}
}
if (have_gsr_bel) {
// make default GSR
auto gsr_cell = std::make_unique<CellInfo>(ctx, id_GSR, id_GSR);
gsr_cell->addInput(id_GSRI);
gsr_cell->connectPort(id_GSRI, ctx->nets[ctx->id("$PACKER_VCC")].get());
ctx->cells[gsr_cell->name] = std::move(gsr_cell);
} else {
log_info("No GSR in the chip base\n");
}
}
}
void run(void)
{
pack_iobs();
handle_constants();
pack_gsr();
pack_wideluts();
pack_alus();
constrain_lutffs();