Gowin. Use two additional DFFs.

The GW-5A series has 8 flip-flops in a cell instead of 6. These
additional flip-flops can be used if the control network matches that
for the 4th and 5th DFFs in this cell.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2025-08-14 13:53:24 +10:00 committed by Lofty
parent 95ab16f380
commit 2d0ad9f9b1
2 changed files with 38 additions and 7 deletions

View File

@ -1059,6 +1059,28 @@ bool GowinImpl::slice_valid(int x, int y, int z) const
return false;
}
}
// Check whether the current architecture allows 6 and 7 DFFs
if (z > 3 && ctx->getBelByLocation(Loc(x, y, 6 * 2 + 1)) != BelId()) {
// The 4th, 5th, 6th, and 7th DFFs have the same control wires. Let's check this.
const int adj_top_ff_z = (5 - (z >> 1)) * 4 + 1;
for (int i = 0; i < 4; i += 2) {
const CellInfo *adj_top_ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(x, y, adj_top_ff_z + i)));
if (adj_top_ff) {
const auto &adj_top_ff_data = fast_cell_info.at(adj_top_ff->flat_index);
if (adj_top_ff_data.ff_lsr != ff_data.ff_lsr) {
return false;
}
if (adj_top_ff_data.ff_clk != ff_data.ff_clk) {
return false;
}
if (adj_top_ff_data.ff_ce != ff_data.ff_ce) {
return false;
}
// It is sufficient to check only one DFF.
break;
}
}
}
}
return true;
}

View File

@ -964,7 +964,7 @@ def create_logic_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tde
for j, inp_name in enumerate(lut_inputs):
tt.add_bel_pin(lut, f"I{j}", f"{inp_name}{i}", PinType.INPUT)
tt.add_bel_pin(lut, "F", f"F{i}", PinType.OUTPUT)
if i < 6:
if i < 6 or chip.name == "GW5A-25A":
tt.create_pip(f"F{i}", f"XD{i}", get_tm_class(db, f"F{i}"))
# also experimental input for FF using SEL wire - this theory will
# allow to place unrelated LUT and FF next to each other
@ -974,14 +974,23 @@ def create_logic_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tde
# FF
ff = tt.create_bel(f"DFF{i}", "DFF", z =(i * 2 + 1))
tt.add_bel_pin(ff, "D", f"XD{i}", PinType.INPUT)
tt.add_bel_pin(ff, "CLK", f"CLK{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "Q", f"Q{i}", PinType.OUTPUT)
tt.add_bel_pin(ff, "SET", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "RESET", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "PRESET", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "CLEAR", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "CE", f"CE{i // 2}", PinType.INPUT)
if i < 6:
tt.add_bel_pin(ff, "CLK", f"CLK{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "SET", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "RESET", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "PRESET", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "CLEAR", f"LSR{i // 2}", PinType.INPUT)
tt.add_bel_pin(ff, "CE", f"CE{i // 2}", PinType.INPUT)
else:
tt.add_bel_pin(ff, "CLK", "CLK2", PinType.INPUT)
tt.add_bel_pin(ff, "SET", "LSR2", PinType.INPUT)
tt.add_bel_pin(ff, "RESET", "LSR2", PinType.INPUT)
tt.add_bel_pin(ff, "PRESET", "LSR2", PinType.INPUT)
tt.add_bel_pin(ff, "CLEAR", "LSR2", PinType.INPUT)
tt.add_bel_pin(ff, "CE", "CE2", PinType.INPUT)
if i < 6:
# ALU
ff = tt.create_bel(f"ALU{i}", "ALU", z = i + ALU0_Z)
tt.add_bel_pin(ff, "SUM", f"F{i}", PinType.OUTPUT)