mirror of https://github.com/YosysHQ/nextpnr.git
Gowin. DSP. Implement MULT27X36.
The new multiplier is made from two 27x18 units by switching inputs and creating a cluster connected via CASO->CASI. A second pass was required to process the multipliers created on the fly—the processing of DSP cells was separated into a separate function, which resulted in a large diff, but in reality there were very few changes. An important point is that in the 5A series, there is a gap between adjacent DSPs in one row. There are still SIA/CASI wires, so the DSPs on either side of the gap are connected, but the distance between them is greater than usual. We take this fact into account based on the gap coordinates from the chip database. Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
parent
8c2f8810d4
commit
008ccae25b
|
|
@ -974,6 +974,9 @@ X(ASEL1)
|
|||
X(BSEL)
|
||||
X(BSEL0)
|
||||
X(BSEL1)
|
||||
X(CSEL)
|
||||
X(PSEL)
|
||||
X(PADDSUB)
|
||||
X(SOA_REG)
|
||||
X(DSIGN)
|
||||
X(ACCLOAD)
|
||||
|
|
@ -1003,6 +1006,8 @@ X(RESET1)
|
|||
X(ACCSEL)
|
||||
X(ACCSEL0)
|
||||
X(ACCSEL1)
|
||||
X(MULT27X36_MAIN)
|
||||
X(MULT27X36_AUX)
|
||||
|
||||
// IOB types
|
||||
X(IBUF)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ inline bool is_bsram(const CellInfo *cell) { return type_is_bsram(cell->type); }
|
|||
inline bool type_is_dsp(IdString cell_type)
|
||||
{
|
||||
return cell_type.in(id_PADD9, id_PADD18, id_MULT9X9, id_MULT18X18, id_MULT36X36, id_ALU54D, id_MULTALU18X18,
|
||||
id_MULTALU36X18, id_MULTADDALU18X18, id_MULT12X12, id_MULTADDALU12X12, id_MULTALU27X18);
|
||||
id_MULTALU36X18, id_MULTADDALU18X18, id_MULT12X12, id_MULTADDALU12X12, id_MULTALU27X18,
|
||||
id_MULT27X36);
|
||||
}
|
||||
inline bool is_dsp(const CellInfo *cell) { return type_is_dsp(cell->type); }
|
||||
|
||||
|
|
@ -197,6 +198,8 @@ NPNR_PACKED_STRUCT(struct Extra_package_data_POD { RelSlice<Constraint_POD> cst;
|
|||
NPNR_PACKED_STRUCT(struct Extra_chip_data_POD {
|
||||
int32_t chip_flags;
|
||||
int32_t dcs_prefix;
|
||||
int16_t center_row;
|
||||
int16_t center_col;
|
||||
Bottom_io_POD bottom_io;
|
||||
RelSlice<IdString> diff_io_types;
|
||||
RelSlice<Spine_bel_POD> dqce_bels;
|
||||
|
|
|
|||
|
|
@ -295,6 +295,8 @@ class SpineSelectWire(BBAStruct):
|
|||
class ChipExtraData(BBAStruct):
|
||||
strs: StringPool
|
||||
flags: int
|
||||
center_row: int
|
||||
center_col: int
|
||||
dcs_prefix: IdString = field(default = None)
|
||||
bottom_io: BottomIO = field(default = None)
|
||||
diff_io_types: list[IdString] = field(default_factory = list)
|
||||
|
|
@ -383,6 +385,8 @@ class ChipExtraData(BBAStruct):
|
|||
def serialise(self, context: str, bba: BBAWriter):
|
||||
bba.u32(self.flags)
|
||||
bba.u32(self.dcs_prefix.index)
|
||||
bba.u16(self.center_row)
|
||||
bba.u16(self.center_col)
|
||||
self.bottom_io.serialise(f"{context}_bottom_io", bba)
|
||||
bba.slice(f"{context}_diff_io_types", len(self.diff_io_types))
|
||||
bba.slice(f"{context}_dqce_bels", len(self.dqce_bels))
|
||||
|
|
@ -1550,7 +1554,19 @@ def create_packages(chip: Chip, db: chipdb):
|
|||
|
||||
# Extra chip data
|
||||
def create_extra_data(chip: Chip, db: chipdb, chip_flags: int):
|
||||
chip.extra_data = ChipExtraData(chip.strs, chip_flags)
|
||||
# The coordinates of the chip center are useful when building a DSP chain
|
||||
# because there is an area around this particular point that does not
|
||||
# contain any DSP blocks, but there are cascade and shift wires, so the gap
|
||||
# between adjacent DSPs is larger than usual at this point. The coordinates
|
||||
# of this particular cell may be useful when working with 138k clock MUXs
|
||||
# in the future.
|
||||
center_row = 0
|
||||
center_col = 0
|
||||
if hasattr(db, 'center_row'):
|
||||
center_row = db.center_row
|
||||
center_col = db.center_col
|
||||
|
||||
chip.extra_data = ChipExtraData(chip.strs, chip_flags, center_row, center_col)
|
||||
if hasattr(db, "dcs_prefix"):
|
||||
chip.extra_data.set_dcs_prefix(db.dcs_prefix)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -510,7 +510,11 @@ Loc GowinUtils::get_dsp_next_in_chain_5a(Loc from) const
|
|||
Loc res;
|
||||
res.y = from.y;
|
||||
// next DSP
|
||||
res.x = from.x + 3;
|
||||
int off = 3;
|
||||
if (from.y == get_center_row() && (from.x + 5) == get_center_col()) {
|
||||
off = 9;
|
||||
}
|
||||
res.x = from.x + off;
|
||||
res.z = from.z;
|
||||
return res;
|
||||
}
|
||||
|
|
@ -741,4 +745,16 @@ void GowinUtils::find_connected_bels(const CellInfo *cell, IdString port, IdStri
|
|||
}
|
||||
}
|
||||
|
||||
// Get spec locations
|
||||
int GowinUtils::get_center_row(void) const
|
||||
{
|
||||
const Extra_chip_data_POD *extra = reinterpret_cast<const Extra_chip_data_POD *>(ctx->chip_info->extra_data.get());
|
||||
return extra->center_row;
|
||||
}
|
||||
int GowinUtils::get_center_col(void) const
|
||||
{
|
||||
const Extra_chip_data_POD *extra = reinterpret_cast<const Extra_chip_data_POD *>(ctx->chip_info->extra_data.get());
|
||||
return extra->center_col;
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
|
|
|||
|
|
@ -240,6 +240,10 @@ struct GowinUtils
|
|||
|
||||
// Find a maximum matching in a bipartite graph, g
|
||||
std::vector<int> kuhn_find_maximum_bipartite_matching(int n, int k, std::vector<std::vector<int>> &g);
|
||||
|
||||
// Get spec locations
|
||||
int get_center_row(void) const;
|
||||
int get_center_col(void) const;
|
||||
};
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue