current progress

This commit is contained in:
Lofty 2025-06-27 09:03:51 +01:00
parent 7122a98c13
commit bdf235721e
2 changed files with 38 additions and 12 deletions

View File

@ -43,7 +43,7 @@ struct ZeroDriver
// Propagate A0 through OUT1 and A1 through OUT2; zero COUTX and POUTX.
struct APassThroughCell
{
APassThroughCell(CellInfo *lower, CellInfo *upper, IdString name);
APassThroughCell(CellInfo *lower, CellInfo *upper, IdString name, bool inverted);
void clean_up(Context *ctx);

View File

@ -48,7 +48,8 @@ ZeroDriver::ZeroDriver(CellInfo *lower, CellInfo *upper, IdString name) : lower{
upper->params[id_C_O2] = Property(0b11, 2); // COMB2OUT -> OUT2
}
APassThroughCell::APassThroughCell(CellInfo *lower, CellInfo *upper, IdString name) : lower{lower}, upper{upper}
APassThroughCell::APassThroughCell(CellInfo *lower, CellInfo *upper, IdString name, bool inverted)
: lower{lower}, upper{upper}, inverted{inverted}
{
lower->params[id_INIT_L02] = Property(LUT_D0, 4); // IN5
lower->params[id_INIT_L03] = Property(LUT_ZERO, 4); // (unused)
@ -78,23 +79,31 @@ void APassThroughCell::clean_up(Context *ctx)
NPNR_ASSERT(upper_net != nullptr);
{
bool net_is_gnd = lower_net->name == ctx->idf("$PACKER_GND");
bool net_is_vcc = lower_net->name == ctx->idf("$PACKER_VCC");
bool net_is_gnd =
lower_net->name == ctx->idf("$PACKER_GND") || (inverted && lower_net->name == ctx->idf("$PACKER_VCC"));
bool net_is_vcc =
lower_net->name == ctx->idf("$PACKER_VCC") || (inverted && lower_net->name == ctx->idf("$PACKER_GND"));
if (net_is_gnd || net_is_vcc) {
lower->params[id_INIT_L02] = Property(LUT_ZERO, 4);
lower->params[id_INIT_L11] = Property(LUT_ZERO, 4);
lower->params[id_INIT_L20] = Property(net_is_vcc ? LUT_ONE : LUT_ZERO, 4);
lower->disconnectPort(id_IN1);
} else if (inverted) {
lower->params[id_INIT_L02] = Property(LUT_INV_D0, 4);
}
}
{
bool net_is_gnd = lower_net->name == ctx->idf("$PACKER_GND");
bool net_is_vcc = lower_net->name == ctx->idf("$PACKER_VCC");
bool net_is_gnd =
upper_net->name == ctx->idf("$PACKER_GND") || (inverted && upper_net->name == ctx->idf("$PACKER_VCC"));
bool net_is_vcc =
upper_net->name == ctx->idf("$PACKER_VCC") || (inverted && upper_net->name == ctx->idf("$PACKER_GND"));
if (net_is_gnd || net_is_vcc) {
upper->params[id_INIT_L00] = Property(LUT_ZERO, 4);
upper->params[id_INIT_L10] = Property(net_is_vcc ? LUT_ONE : LUT_ZERO, 4);
upper->disconnectPort(id_IN1);
} else if (inverted) {
upper->params[id_INIT_L00] = Property(LUT_INV_D0, 4);
}
}
}
@ -313,10 +322,10 @@ void GateMatePacker::pack_mult()
return ZeroDriver{zero_lower, zero_upper, name};
};
auto create_a_passthru = [&](IdString name) {
auto create_a_passthru = [&](IdString name, bool inverted) {
auto *a_passthru_lower = create_cell_ptr(id_CPE_HALF_L, ctx->idf("%s$a_passthru_lower", name.c_str(ctx)));
auto *a_passthru_upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$a_passthru_upper", name.c_str(ctx)));
return APassThroughCell{a_passthru_lower, a_passthru_upper, name};
return APassThroughCell{a_passthru_lower, a_passthru_upper, name, inverted};
};
auto create_mult_col = [&](IdString name, int a_width, bool is_even_x) {
@ -336,8 +345,10 @@ void GateMatePacker::pack_mult()
}
{
auto *multfab_lower = create_cell_ptr(id_CPE_HALF_L, ctx->idf("%s$multfab_lower", name.c_str(ctx)));
auto *multfab_upper = create_cell_ptr(id_CPE_HALF_U, ctx->idf("%s$multfab_upper", name.c_str(ctx)));
auto *multfab_lower = create_cell_ptr(id_CPE_HALF_L,
ctx->idf("%s$multf%c_lower", name.c_str(ctx), is_even_x ? 'a' : 'b'));
auto *multfab_upper = create_cell_ptr(id_CPE_HALF_U,
ctx->idf("%s$multf%c_upper", name.c_str(ctx), is_even_x ? 'a' : 'b'));
col.multfab = MultfabCell{multfab_lower, multfab_upper, name, is_even_x};
}
@ -389,12 +400,24 @@ void GateMatePacker::pack_mult()
a_width += 1;
}
// Keep extending until we reach p_width
while (a_width < p_width) {
mult->copyPortTo(ctx->idf("A[%d]", a_width - 1), mult, ctx->idf("A[%d]", a_width));
a_width += 1;
}
// Sign-extend odd B_WIDTH to even, because we're working with 2x2 multiplier cells.
if (b_width % 2 == 1) {
mult->copyPortTo(ctx->idf("B[%d]", b_width - 1), mult, ctx->idf("B[%d]", b_width));
b_width += 1;
}
// Keep extending until we reach p_width
while (b_width < p_width) {
mult->copyPortTo(ctx->idf("B[%d]", b_width - 1), mult, ctx->idf("B[%d]", b_width));
b_width += 1;
}
log_info(" Configuring '%s' as a %d-bit * %d-bit = %d-bit multiplier.\n", mult->name.c_str(ctx), a_width,
b_width, p_width);
@ -402,8 +425,11 @@ void GateMatePacker::pack_mult()
// Step 1: instantiate all the CPEs.
m.zero = create_zero_driver(ctx->idf("%s$col0", mult->name.c_str(ctx)));
for (int a = 0; a < a_width / 2; a++)
m.a_passthrus.push_back(create_a_passthru(ctx->idf("%s$col0$row%d", mult->name.c_str(ctx), a)));
for (int a = 0; a < a_width / 2; a++) {
bool inverted = false;
log_info("row %d inverted? %d\n", a, inverted);
m.a_passthrus.push_back(create_a_passthru(ctx->idf("%s$col0$row%d", mult->name.c_str(ctx), a), inverted));
}
for (int b = 0; b < b_width / 2; b++)
m.cols.push_back(create_mult_col(ctx->idf("%s$col%d", mult->name.c_str(ctx), b + 1), a_width, b % 2 == 0));