From 4d5c48ad834550e5821b42eada5085d339f79cd7 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Wed, 17 Apr 2024 14:52:34 +1000 Subject: [PATCH] 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 --- himbaechel/uarch/gowin/constids.inc | 5 +++++ himbaechel/uarch/gowin/gowin_arch_gen.py | 12 ++++++++++-- himbaechel/uarch/gowin/pack.cc | 10 ++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/himbaechel/uarch/gowin/constids.inc b/himbaechel/uarch/gowin/constids.inc index 78ddb1fb..77de2ee8 100644 --- a/himbaechel/uarch/gowin/constids.inc +++ b/himbaechel/uarch/gowin/constids.inc @@ -933,6 +933,11 @@ X(ASIGN0) X(BSIGN0) X(ASIGN1) X(BSIGN1) +X(ZERO_SIGN) +X(ZERO_ASIGN0) +X(ZERO_BSIGN0) +X(ZERO_ASIGN1) +X(ZERO_BSIGN1) X(ASEL) X(ASEL0) X(ASEL1) diff --git a/himbaechel/uarch/gowin/gowin_arch_gen.py b/himbaechel/uarch/gowin/gowin_arch_gen.py index 2aab88f6..e84e853b 100644 --- a/himbaechel/uarch/gowin/gowin_arch_gen.py +++ b/himbaechel/uarch/gowin/gowin_arch_gen.py @@ -421,14 +421,17 @@ def create_tiletype(create_func, chip: Chip, db: chipdb, x: int, y: int, ttyp: i create_switch_matrix(tt, db, x, y) 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] 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) + if pin_name: + tt.add_bel_pin(bel, pin_name, wire, port_type) + else: + 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): typename = "NULL" @@ -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 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 sfx in {'A', 'B'}: for inp in range(36): diff --git a/himbaechel/uarch/gowin/pack.cc b/himbaechel/uarch/gowin/pack.cc index e20ac712..193892e2 100644 --- a/himbaechel/uarch/gowin/pack.cc +++ b/himbaechel/uarch/gowin/pack.cc @@ -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%d1", i)); } + // only MSB sign bits 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_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_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) { ci->renamePort(ctx->idf("DOUT[%d]", i), ctx->idf("DOUT%d", i)); }