mirror of
https://github.com/YosysHQ/nextpnr.git
synced 2026-01-11 23:53:21 +00:00
Gowin. Remove the special status of corner tiles. (#1565)
Over time, it became clear that the special status of corner tiles is handled in other parts of the toolchain, and in the GW5A chip series, it began to interfere—in this series, IO can be located in the corners. So we move the only function (creating VCC and GND) to the extra function itself, and at the same time create a mechanism for explicitly specifying the location of these sources in Apicula when necessary. Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
parent
ad76625d4d
commit
57f70aeeb8
@ -184,7 +184,7 @@ NPNR_PACKED_STRUCT(struct Extra_package_data_POD { RelSlice<Constraint_POD> cst;
|
|||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct Extra_chip_data_POD {
|
NPNR_PACKED_STRUCT(struct Extra_chip_data_POD {
|
||||||
int32_t chip_flags;
|
int32_t chip_flags;
|
||||||
IdString dcs_prefix;
|
int32_t dcs_prefix;
|
||||||
Bottom_io_POD bottom_io;
|
Bottom_io_POD bottom_io;
|
||||||
RelSlice<IdString> diff_io_types;
|
RelSlice<IdString> diff_io_types;
|
||||||
RelSlice<Spine_bel_POD> dqce_bels;
|
RelSlice<Spine_bel_POD> dqce_bels;
|
||||||
|
|||||||
@ -786,6 +786,17 @@ def create_extra_funcs(tt: TileType, db: chipdb, x: int, y: int):
|
|||||||
for pin, wire in desc['inputs'].items():
|
for pin, wire in desc['inputs'].items():
|
||||||
tt.create_wire(wire, "PLL_I")
|
tt.create_wire(wire, "PLL_I")
|
||||||
tt.add_bel_pin(pll, pin, wire, PinType.INPUT)
|
tt.add_bel_pin(pll, pin, wire, PinType.INPUT)
|
||||||
|
elif func == 'gnd_source':
|
||||||
|
# GND is the logic low level generator
|
||||||
|
tt.create_wire('VSS', 'GND', const_value = 'VSS')
|
||||||
|
gnd = tt.create_bel('GND', 'GND', z = GND_Z)
|
||||||
|
tt.add_bel_pin(gnd, "G", "VSS", PinType.OUTPUT)
|
||||||
|
elif func == 'vcc_source':
|
||||||
|
# VCC is the logic high level generator
|
||||||
|
tt.create_wire('VCC', 'VCC', const_value = 'VCC')
|
||||||
|
gnd = tt.create_bel('VCC', 'VCC', z = VCC_Z)
|
||||||
|
tt.add_bel_pin(gnd, "V", "VCC", PinType.OUTPUT)
|
||||||
|
|
||||||
|
|
||||||
def set_wire_flags(tt: TileType, tdesc: TypeDesc):
|
def set_wire_flags(tt: TileType, tdesc: TypeDesc):
|
||||||
if tdesc.extra_func and 'clock_gates' in tdesc.extra_func:
|
if tdesc.extra_func and 'clock_gates' in tdesc.extra_func:
|
||||||
@ -869,29 +880,6 @@ def create_null_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdes
|
|||||||
tdesc.tiletype = tiletype
|
tdesc.tiletype = tiletype
|
||||||
return tt
|
return tt
|
||||||
|
|
||||||
# responsible nodes, there will be IO banks, configuration, etc.
|
|
||||||
def create_corner_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc):
|
|
||||||
typename = "CORNER"
|
|
||||||
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))
|
|
||||||
|
|
||||||
if x == 0 and y == 0:
|
|
||||||
# GND is the logic low level generator
|
|
||||||
tt.create_wire('VSS', 'GND', const_value = 'VSS')
|
|
||||||
gnd = tt.create_bel('GND', 'GND', z = GND_Z)
|
|
||||||
tt.add_bel_pin(gnd, "G", "VSS", PinType.OUTPUT)
|
|
||||||
# VCC is the logic high level generator
|
|
||||||
tt.create_wire('VCC', 'VCC', const_value = 'VCC')
|
|
||||||
gnd = tt.create_bel('VCC', 'VCC', z = VCC_Z)
|
|
||||||
tt.add_bel_pin(gnd, "V", "VCC", PinType.OUTPUT)
|
|
||||||
|
|
||||||
tdesc.tiletype = tiletype
|
|
||||||
return tt
|
|
||||||
|
|
||||||
|
|
||||||
# IO
|
# IO
|
||||||
def create_io_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc):
|
def create_io_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc):
|
||||||
typename = "IO"
|
typename = "IO"
|
||||||
@ -1580,6 +1568,15 @@ def create_timing_info(chip: Chip, db: chipdb.Device):
|
|||||||
for name, mapping in [("LUT_OUT", "FFan"), ("FF_OUT", "QFan"), ("OF", "OFFan")]:
|
for name, mapping in [("LUT_OUT", "FFan"), ("FF_OUT", "QFan"), ("OF", "OFFan")]:
|
||||||
tmg.set_pip_class(speed, name, TimingValue(), group_to_timingvalue(groups["fanout"][mapping]), TimingValue(round(1e6 / groups["fanout"][f"{mapping}Num"])))
|
tmg.set_pip_class(speed, name, TimingValue(), group_to_timingvalue(groups["fanout"][mapping]), TimingValue(round(1e6 / groups["fanout"][f"{mapping}Num"])))
|
||||||
|
|
||||||
|
# If Apicula does not specify a special location for the global GND and VCC
|
||||||
|
# sources, place them at X0Y0.
|
||||||
|
def check_place_VCC_GND(db: chipdb.Device):
|
||||||
|
for funcs in db.extra_func.values():
|
||||||
|
if 'gnd_source' in funcs or 'vcc_source' in funcs:
|
||||||
|
return
|
||||||
|
db.extra_func.setdefault((0, 0), {}).update({'gnd_source':{}, 'vcc_source': {}})
|
||||||
|
|
||||||
|
# *******************************
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description='Make Gowin BBA')
|
parser = argparse.ArgumentParser(description='Make Gowin BBA')
|
||||||
parser.add_argument('-d', '--device', required=True)
|
parser.add_argument('-d', '--device', required=True)
|
||||||
@ -1639,15 +1636,15 @@ def main():
|
|||||||
bsram_tiletypes = db.tile_types.get('B', set())
|
bsram_tiletypes = db.tile_types.get('B', set())
|
||||||
dsp_tiletypes = db.tile_types.get('D', set())
|
dsp_tiletypes = db.tile_types.get('D', set())
|
||||||
|
|
||||||
|
# If Apicula does not specify a special location for the global GND and VCC
|
||||||
|
# sources, place them at X0Y0.
|
||||||
|
check_place_VCC_GND(db)
|
||||||
|
|
||||||
# Setup tile grid
|
# Setup tile grid
|
||||||
for x in range(X):
|
for x in range(X):
|
||||||
for y in range(Y):
|
for y in range(Y):
|
||||||
ttyp = db.grid[y][x].ttyp
|
ttyp = db.grid[y][x].ttyp
|
||||||
if (x == 0 or x == X - 1) and (y == 0 or y == Y - 1):
|
if ttyp in logic_tiletypes:
|
||||||
assert ttyp not in created_tiletypes, "Duplication of corner types"
|
|
||||||
create_tiletype(create_corner_tiletype, ch, db, x, y, ttyp)
|
|
||||||
continue
|
|
||||||
elif ttyp in logic_tiletypes:
|
|
||||||
create_tiletype(create_logic_tiletype, ch, db, x, y, ttyp)
|
create_tiletype(create_logic_tiletype, ch, db, x, y, ttyp)
|
||||||
elif ttyp in ssram_tiletypes:
|
elif ttyp in ssram_tiletypes:
|
||||||
create_tiletype(create_ssram_tiletype, ch, db, x, y, ttyp)
|
create_tiletype(create_ssram_tiletype, ch, db, x, y, ttyp)
|
||||||
|
|||||||
@ -293,7 +293,7 @@ BelId GowinUtils::get_dhcen_bel(WireId hclkin_wire, IdString &side)
|
|||||||
IdString GowinUtils::get_dcs_prefix(void)
|
IdString GowinUtils::get_dcs_prefix(void)
|
||||||
{
|
{
|
||||||
const Extra_chip_data_POD *extra = reinterpret_cast<const Extra_chip_data_POD *>(ctx->chip_info->extra_data.get());
|
const Extra_chip_data_POD *extra = reinterpret_cast<const Extra_chip_data_POD *>(ctx->chip_info->extra_data.get());
|
||||||
return extra->dcs_prefix;
|
return IdString(extra->dcs_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GowinUtils::is_simple_io_bel(BelId bel)
|
bool GowinUtils::is_simple_io_bel(BelId bel)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user