Gowin. BUGFIX. Fix placement checks

It was not taken into account that there are only 6 ALUs per cell. As a
result, on complex designs where ALUs and LUT-based memory are involved
and there are many LUTs (like in the RISCV emulator), there were
sometimes false positives about placement conflicts.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2024-07-29 16:19:04 +10:00
parent eb099a9244
commit ec4d783d4c

View File

@ -539,8 +539,10 @@ bool GowinImpl::dsp_valid(Loc l, IdString bel_type, bool explain_invalid) const
bool GowinImpl::slice_valid(int x, int y, int z) const bool GowinImpl::slice_valid(int x, int y, int z) const
{ {
const CellInfo *lut = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, z * 2))); const CellInfo *lut = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, z * 2)));
const bool lut_in_4_5 = lut && (z == 4 || z == 5);
const CellInfo *ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, z * 2 + 1))); const CellInfo *ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, z * 2 + 1)));
const CellInfo *alu = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, z + BelZ::ALU0_Z))); // There are only 6 ALUs
const CellInfo *alu = (z < 6) ? ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, z + BelZ::ALU0_Z))) : nullptr;
const CellInfo *ramw = const CellInfo *ramw =
(z == 4 || z == 5) ? ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, BelZ::RAMW_Z))) : nullptr; (z == 4 || z == 5) ? ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, BelZ::RAMW_Z))) : nullptr;
@ -549,7 +551,7 @@ bool GowinImpl::slice_valid(int x, int y, int z) const
} }
if (ramw) { if (ramw) {
if (alu || ff || lut) { if (alu || ff || lut_in_4_5) {
return false; return false;
} }
return true; return true;
@ -560,7 +562,9 @@ bool GowinImpl::slice_valid(int x, int y, int z) const
int adj_alu_z = adj_lut_z / 2 + BelZ::ALU0_Z; int adj_alu_z = adj_lut_z / 2 + BelZ::ALU0_Z;
const CellInfo *adj_lut = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_lut_z))); const CellInfo *adj_lut = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_lut_z)));
const CellInfo *adj_ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_lut_z + 1))); const CellInfo *adj_ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_lut_z + 1)));
const CellInfo *adj_alu = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_alu_z))); const CellInfo *adj_alu = adj_alu_z < (6 + BelZ::ALU0_Z)
? ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_alu_z)))
: nullptr;
if ((alu && (adj_lut || (adj_ff && !adj_alu))) || ((lut || (ff && !alu)) && adj_alu)) { if ((alu && (adj_lut || (adj_ff && !adj_alu))) || ((lut || (ff && !alu)) && adj_alu)) {
return false; return false;