gowin: Himbaechel. Initial BSRAM support
Only pROM/pROMX9 for now Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
parent
e3f4578b3b
commit
f2c280feda
@ -885,6 +885,27 @@ X(DIC)
|
||||
X(DID)
|
||||
X(WRE)
|
||||
|
||||
// BSRAM
|
||||
X(BSRAM_SUBTYPE)
|
||||
X(BIT_WIDTH)
|
||||
X(ROM)
|
||||
X(SP)
|
||||
X(SPX9)
|
||||
X(pROM)
|
||||
X(pROMX9)
|
||||
X(BSRAM)
|
||||
X(OCE)
|
||||
X(OCEA)
|
||||
X(OCEB)
|
||||
X(CEA)
|
||||
X(CEB)
|
||||
X(RESETA)
|
||||
X(RESETB)
|
||||
X(WREA)
|
||||
X(WREB)
|
||||
X(CLKA)
|
||||
X(CLKB)
|
||||
|
||||
// IOB types
|
||||
X(IBUF)
|
||||
X(OBUF)
|
||||
@ -1064,6 +1085,8 @@ X(BOTTOM_IO_PORT_A)
|
||||
X(BOTTOM_IO_PORT_B)
|
||||
X(IOLOGIC_DUMMY)
|
||||
|
||||
//
|
||||
|
||||
// wire types
|
||||
X(GLOBAL_CLK)
|
||||
X(TILE_CLK)
|
||||
|
@ -266,6 +266,9 @@ IdString GowinImpl::getBelBucketForCellType(IdString cell_type) const
|
||||
if (type_is_iologic(cell_type)) {
|
||||
return id_IOLOGIC;
|
||||
}
|
||||
if (type_is_bsram(cell_type)) {
|
||||
return id_BSRAM;
|
||||
}
|
||||
if (cell_type == id_GOWIN_GND) {
|
||||
return id_GND;
|
||||
}
|
||||
@ -293,6 +296,9 @@ bool GowinImpl::isValidBelForCellType(IdString cell_type, BelId bel) const
|
||||
if (bel_type == id_IOLOGIC) {
|
||||
return type_is_iologic(cell_type);
|
||||
}
|
||||
if (bel_type == id_BSRAM) {
|
||||
return type_is_bsram(cell_type);
|
||||
}
|
||||
if (bel_type == id_GND) {
|
||||
return cell_type == id_GOWIN_GND;
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ inline bool is_iologic(const CellInfo *cell) { return type_is_iologic(cell->type
|
||||
inline bool type_is_ssram(IdString cell_type) { return cell_type.in(id_RAM16SDP1, id_RAM16SDP2, id_RAM16SDP4); }
|
||||
inline bool is_ssram(const CellInfo *cell) { return type_is_ssram(cell->type); }
|
||||
|
||||
// Return true if a cell is a SSRAM
|
||||
inline bool type_is_bsram(IdString cell_type) { return cell_type.in(id_SP, id_SPX9, id_pROM, id_pROMX9, id_ROM); }
|
||||
inline bool is_bsram(const CellInfo *cell) { return type_is_bsram(cell->type); }
|
||||
|
||||
// ==========================================
|
||||
// extra data in the chip db
|
||||
// ==========================================
|
||||
@ -89,6 +93,7 @@ enum
|
||||
OSER16_Z = 73,
|
||||
|
||||
BUFG_Z = 74, // : 81 reserve just in case
|
||||
BSRAM_Z = 100,
|
||||
|
||||
OSC_Z = 274,
|
||||
PLL_Z = 275,
|
||||
|
@ -33,6 +33,7 @@ IDES16_Z = 72
|
||||
OSER16_Z = 73
|
||||
|
||||
BUFG_Z = 74 # : 81 reserve just in case
|
||||
BSRAM_Z = 100
|
||||
|
||||
OSC_Z = 274
|
||||
PLL_Z = 275
|
||||
@ -561,9 +562,49 @@ def create_ssram_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tde
|
||||
tt.add_bel_pin(ff, f"RAD[{i}]", f"{lut_inputs[i]}0", PinType.INPUT)
|
||||
tt.add_bel_pin(ff, f"DO[{i}]", f"F{i}", PinType.OUTPUT)
|
||||
|
||||
tt.add_bel_pin(ff, f"CLK", "CLK2", PinType.INPUT)
|
||||
tt.add_bel_pin(ff, f"CE", "CE2", PinType.INPUT)
|
||||
tt.add_bel_pin(ff, f"WRE", "LSR2", PinType.INPUT)
|
||||
tt.add_bel_pin(ff, "CLK", "CLK2", PinType.INPUT)
|
||||
tt.add_bel_pin(ff, "CE", "CE2", PinType.INPUT)
|
||||
tt.add_bel_pin(ff, "WRE", "LSR2", PinType.INPUT)
|
||||
return tt
|
||||
|
||||
# BSRAM
|
||||
_bsram_inputs = {'CLK', 'OCE', 'CE', 'RESET', 'WRE'}
|
||||
def create_bsram_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc):
|
||||
typename = "BSRAM"
|
||||
tiletype = f"{typename}_{ttyp}"
|
||||
if tdesc.sfx != 0:
|
||||
tiletype += f"_{tdesc.sfx}"
|
||||
tt = chip.create_tile_type(tiletype)
|
||||
tt.extra_data = TileExtraData(chip.strs.id(typename))
|
||||
|
||||
portmap = db.grid[y][x].bels['BSRAM'].portmap
|
||||
bsram = tt.create_bel("BSRAM", "BSRAM", z = BSRAM_Z)
|
||||
|
||||
def add_port_wire(tt, bel, name, wire_type = "BSRAM_I", port_type = PinType.INPUT):
|
||||
wire = portmap[name]
|
||||
if not tt.has_wire(wire):
|
||||
if name.startswith('CLK'):
|
||||
tt.create_wire(wire, "TILE_CLK")
|
||||
else:
|
||||
tt.create_wire(wire, wire_type)
|
||||
tt.add_bel_pin(bel, name, wire, port_type)
|
||||
|
||||
for sfx in {'', 'A', 'B'}:
|
||||
for inp in _bsram_inputs:
|
||||
add_port_wire(tt, bsram, f"{inp}{sfx}")
|
||||
for idx in range(3):
|
||||
add_port_wire(tt, bsram, f"BLKSEL{sfx}{idx}")
|
||||
for idx in range(14):
|
||||
add_port_wire(tt, bsram, f"AD{sfx}{idx}")
|
||||
for idx in range(18):
|
||||
add_port_wire(tt, bsram, f"DI{sfx}{idx}")
|
||||
add_port_wire(tt, bsram, f"DO{sfx}{idx}", "BSRAM_O", PinType.OUTPUT)
|
||||
if not sfx:
|
||||
for idx in range(18, 36):
|
||||
add_port_wire(tt, bsram, f"DI{idx}")
|
||||
add_port_wire(tt, bsram, f"DO{idx}", "BSRAM_O", PinType.OUTPUT)
|
||||
|
||||
tdesc.tiletype = tiletype
|
||||
return tt
|
||||
|
||||
# PLL main tile
|
||||
@ -687,6 +728,7 @@ def main():
|
||||
io_tiletypes = db.tile_types['I']
|
||||
ssram_tiletypes = db.tile_types['M']
|
||||
pll_tiletypes = db.tile_types['P']
|
||||
bsram_tiletypes = db.tile_types['B']
|
||||
|
||||
# Setup tile grid
|
||||
for x in range(X):
|
||||
@ -704,6 +746,8 @@ def main():
|
||||
create_tiletype(create_io_tiletype, ch, db, x, y, ttyp)
|
||||
elif ttyp in pll_tiletypes:
|
||||
create_tiletype(create_pll_tiletype, ch, db, x, y, ttyp)
|
||||
elif ttyp in bsram_tiletypes:
|
||||
create_tiletype(create_bsram_tiletype, ch, db, x, y, ttyp)
|
||||
else:
|
||||
create_tiletype(create_null_tiletype, ch, db, x, y, ttyp)
|
||||
|
||||
|
@ -1191,7 +1191,6 @@ struct GowinPacker
|
||||
// ===================================
|
||||
// SSRAM cluster
|
||||
// ===================================
|
||||
// create ALU filler block
|
||||
std::unique_ptr<CellInfo> ssram_make_lut(Context *ctx, CellInfo *ci, int index)
|
||||
{
|
||||
IdString name_id = ctx->idf("%s_LUT%d", ci->name.c_str(ctx), index);
|
||||
@ -1273,6 +1272,82 @@ struct GowinPacker
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================
|
||||
// Block RAM
|
||||
// ===================================
|
||||
void pack_ROM(CellInfo *ci)
|
||||
{
|
||||
// use block 111
|
||||
ci->setParam(ctx->id("BLK_SEL"), Property(7, 32));
|
||||
if (ci->type == id_pROM) {
|
||||
ci->setAttr(id_BSRAM_SUBTYPE, Property(""));
|
||||
} else {
|
||||
ci->setAttr(id_BSRAM_SUBTYPE, Property("X9"));
|
||||
}
|
||||
|
||||
NetInfo *vcc_net = ctx->nets.at(ctx->id("$PACKER_VCC")).get();
|
||||
NetInfo *vss_net = ctx->nets.at(ctx->id("$PACKER_GND")).get();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
IdString port = ctx->idf("BLKSEL%d", i);
|
||||
ci->addInput(port);
|
||||
ci->connectPort(port, vcc_net);
|
||||
port = ctx->idf("BLKSELB%d", i);
|
||||
ci->addInput(port);
|
||||
ci->connectPort(port, vcc_net);
|
||||
}
|
||||
// use port B
|
||||
ci->renamePort(id_CLK, id_CLKB);
|
||||
ci->renamePort(id_OCE, id_OCEB);
|
||||
ci->renamePort(id_CE, id_CEB);
|
||||
ci->renamePort(id_RESET, id_RESETB);
|
||||
ci->addInput(id_WRE);
|
||||
ci->connectPort(id_WRE, vss_net);
|
||||
ci->addInput(id_WREB);
|
||||
ci->connectPort(id_WREB, vss_net);
|
||||
|
||||
if (!ci->params.count(id_BIT_WIDTH)) {
|
||||
ci->setParam(id_BIT_WIDTH, Property(32, 32));
|
||||
}
|
||||
int bit_width = ci->params[id_BIT_WIDTH].as_int64();
|
||||
if (bit_width == 32 || bit_width == 36) {
|
||||
log_error("Bit width %d is not supported\n", bit_width);
|
||||
}
|
||||
for (int i = 0; i < 14; ++i) {
|
||||
ci->renamePort(ctx->idf("AD[%d]", i), ctx->idf("ADB%d", i));
|
||||
}
|
||||
int out_num = (bit_width == 9 || bit_width == 18) ? 36 : 32;
|
||||
for (int i = 0, j = 18; i < out_num; ++i, ++j) {
|
||||
if (((i + 1) % 9) == 0 && bit_width == 16) {
|
||||
++j;
|
||||
}
|
||||
ci->renamePort(ctx->idf("DO[%d]", i), ctx->idf("DO%d", j % 36));
|
||||
}
|
||||
}
|
||||
|
||||
void pack_bsram(void)
|
||||
{
|
||||
log_info("Pack BSRAMs...\n");
|
||||
|
||||
for (auto &cell : ctx->cells) {
|
||||
auto ci = cell.second.get();
|
||||
|
||||
if (is_bsram(ci)) {
|
||||
if (ctx->verbose) {
|
||||
log_info(" pack %s\n", ci->type.c_str(ctx));
|
||||
}
|
||||
switch (ci->type.hash()) {
|
||||
case ID_pROM: /* fallthrough */
|
||||
case ID_pROMX9:
|
||||
pack_ROM(ci);
|
||||
ci->type = id_ROM;
|
||||
break;
|
||||
default:
|
||||
log_error("Unsupported BSRAM type '%s'\n", ci->type.c_str(ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================
|
||||
// Global set/reset
|
||||
// ===================================
|
||||
@ -1397,6 +1472,9 @@ struct GowinPacker
|
||||
pack_ram16sdp4();
|
||||
ctx->check();
|
||||
|
||||
pack_bsram();
|
||||
ctx->check();
|
||||
|
||||
pack_buffered_nets();
|
||||
|
||||
ctx->fixupHierarchy();
|
||||
|
Loading…
Reference in New Issue
Block a user