Gowin. Fix DSP MULT36X36

When multiplying 36 bits by 36 bits using four 18x18 multipliers, the
sign bits of the higher 18-bit parts of the multipliers were correctly
switched, but what was incorrect was leaving the sign bits of the lower
parts of the multipliers uninitialized. They now connect to VSS.

Addresses https://github.com/YosysHQ/apicula/issues/242

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2024-04-17 14:52:34 +10:00 committed by myrtle
parent d3b53d8e1a
commit 4d5c48ad83
3 changed files with 25 additions and 2 deletions

View File

@ -933,6 +933,11 @@ X(ASIGN0)
X(BSIGN0) X(BSIGN0)
X(ASIGN1) X(ASIGN1)
X(BSIGN1) X(BSIGN1)
X(ZERO_SIGN)
X(ZERO_ASIGN0)
X(ZERO_BSIGN0)
X(ZERO_ASIGN1)
X(ZERO_BSIGN1)
X(ASEL) X(ASEL)
X(ASEL0) X(ASEL0)
X(ASEL1) X(ASEL1)

View File

@ -421,13 +421,16 @@ def create_tiletype(create_func, chip: Chip, db: chipdb, x: int, y: int, ttyp: i
create_switch_matrix(tt, db, x, y) create_switch_matrix(tt, db, x, y)
chip.set_tile_type(x, y, tdesc.tiletype) chip.set_tile_type(x, y, tdesc.tiletype)
def add_port_wire(tt, bel, portmap, name, wire_type, port_type): def add_port_wire(tt, bel, portmap, name, wire_type, port_type, pin_name = None):
wire = portmap[name] wire = portmap[name]
if not tt.has_wire(wire): if not tt.has_wire(wire):
if name.startswith('CLK'): if name.startswith('CLK'):
tt.create_wire(wire, "TILE_CLK") tt.create_wire(wire, "TILE_CLK")
else: else:
tt.create_wire(wire, wire_type) tt.create_wire(wire, wire_type)
if pin_name:
tt.add_bel_pin(bel, pin_name, wire, port_type)
else:
tt.add_bel_pin(bel, name, wire, port_type) tt.add_bel_pin(bel, name, wire, port_type)
def create_null_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc): def create_null_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc: TypeDesc):
@ -776,6 +779,11 @@ def create_dsp_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc
portmap = db.grid[y][x].bels[belname].portmap portmap = db.grid[y][x].bels[belname].portmap
dsp = tt.create_bel(belname, "MULT36X36", MULT36X36_Z) dsp = tt.create_bel(belname, "MULT36X36", MULT36X36_Z)
# LSB 18x18 multipliers sign ports must be zero
add_port_wire(tt, dsp, db.grid[y][x].bels['MULT18X1800'].portmap, 'ASIGN', "DSP_I", PinType.INPUT, 'ZERO_ASIGN0')
add_port_wire(tt, dsp, db.grid[y][x].bels['MULT18X1800'].portmap, 'BSIGN', "DSP_I", PinType.INPUT, 'ZERO_BSIGN0')
add_port_wire(tt, dsp, db.grid[y][x].bels['MULT18X1801'].portmap, 'BSIGN', "DSP_I", PinType.INPUT, 'ZERO_BSIGN1')
add_port_wire(tt, dsp, db.grid[y][x].bels['MULT18X1810'].portmap, 'ASIGN', "DSP_I", PinType.INPUT, 'ZERO_ASIGN1')
for i in range(2): for i in range(2):
for sfx in {'A', 'B'}: for sfx in {'A', 'B'}:
for inp in range(36): for inp in range(36):

View File

@ -2288,6 +2288,7 @@ struct GowinPacker
ci->cell_bel_pins.at(ctx->idf("B[%d]", i)).push_back(ctx->idf("B%d0", i)); ci->cell_bel_pins.at(ctx->idf("B[%d]", i)).push_back(ctx->idf("B%d0", i));
ci->cell_bel_pins.at(ctx->idf("B[%d]", i)).push_back(ctx->idf("B%d1", i)); ci->cell_bel_pins.at(ctx->idf("B[%d]", i)).push_back(ctx->idf("B%d1", i));
} }
// only MSB sign bits
ci->cell_bel_pins.at(id_ASIGN).clear(); ci->cell_bel_pins.at(id_ASIGN).clear();
ci->cell_bel_pins.at(id_ASIGN).push_back(id_ASIGN0); ci->cell_bel_pins.at(id_ASIGN).push_back(id_ASIGN0);
ci->cell_bel_pins.at(id_ASIGN).push_back(id_ASIGN1); ci->cell_bel_pins.at(id_ASIGN).push_back(id_ASIGN1);
@ -2295,6 +2296,15 @@ struct GowinPacker
ci->cell_bel_pins.at(id_BSIGN).push_back(id_BSIGN0); ci->cell_bel_pins.at(id_BSIGN).push_back(id_BSIGN0);
ci->cell_bel_pins.at(id_BSIGN).push_back(id_BSIGN1); ci->cell_bel_pins.at(id_BSIGN).push_back(id_BSIGN1);
// LSB sign bits = 0
NetInfo *vss_net = ctx->nets.at(ctx->id("$PACKER_GND")).get();
ci->addInput(id_ZERO_SIGN);
ci->cell_bel_pins[id_ZERO_SIGN].push_back(id_ZERO_ASIGN0);
ci->cell_bel_pins.at(id_ZERO_SIGN).push_back(id_ZERO_BSIGN0);
ci->cell_bel_pins.at(id_ZERO_SIGN).push_back(id_ZERO_BSIGN1);
ci->cell_bel_pins.at(id_ZERO_SIGN).push_back(id_ZERO_ASIGN1);
ci->connectPort(id_ZERO_SIGN, vss_net);
for (int i = 0; i < 72; ++i) { for (int i = 0; i < 72; ++i) {
ci->renamePort(ctx->idf("DOUT[%d]", i), ctx->idf("DOUT%d", i)); ci->renamePort(ctx->idf("DOUT[%d]", i), ctx->idf("DOUT%d", i));
} }