current progress (passes 2x2\!)

This commit is contained in:
Lofty 2025-06-26 01:02:36 +01:00
parent f4179e0330
commit 4fd43f8928
3 changed files with 58 additions and 12 deletions

View File

@ -223,6 +223,46 @@ struct BitstreamBackend
void write_bitstream()
{
{
auto *lower = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col1$row0$mult_lower")).get();
auto *upper = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col1$row0$mult_upper")).get();
NPNR_ASSERT(lower && upper);
NPNR_ASSERT(!need_inversion(lower, id_IN4));
NPNR_ASSERT(!need_inversion(lower, id_IN1));
NPNR_ASSERT(!need_inversion(upper, id_IN1));
}
{
auto *lower = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col1$row1$mult_lower")).get();
auto *upper = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col1$row1$mult_upper")).get();
NPNR_ASSERT(lower && upper);
NPNR_ASSERT(!need_inversion(lower, id_IN4));
NPNR_ASSERT(!need_inversion(lower, id_IN1));
NPNR_ASSERT(!need_inversion(upper, id_IN1));
}
{
auto *lower = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col2$row0$mult_lower")).get();
auto *upper = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col2$row0$mult_upper")).get();
NPNR_ASSERT(lower && upper);
NPNR_ASSERT(need_inversion(lower, id_IN4));
NPNR_ASSERT(need_inversion(lower, id_IN1));
NPNR_ASSERT(need_inversion(upper, id_IN1));
}
{
auto *lower = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col2$row1$mult_lower")).get();
auto *upper = ctx->cells.at(ctx->idf("$mul$top.v:18$15$col2$row1$mult_upper")).get();
NPNR_ASSERT(lower && upper);
NPNR_ASSERT(need_inversion(lower, id_IN4));
NPNR_ASSERT(need_inversion(lower, id_IN1));
NPNR_ASSERT(need_inversion(upper, id_IN1));
}
ChipConfig cc;
cc.chip_name = device;
int bank[uarch->dies][9] = {0};

View File

@ -217,7 +217,7 @@ void GateMateImpl::postPlace()
}
}
void GateMateImpl::preRoute() { route_clock(); route_mults(); }
void GateMateImpl::preRoute() { route_clock(); }
void GateMateImpl::postRoute()
{

View File

@ -18,6 +18,7 @@
*/
#include "idstring.h"
#include "log.h"
#include "nextpnr_assertions.h"
#include "nextpnr_namespaces.h"
#include "nextpnr_types.h"
@ -84,7 +85,10 @@ struct APassThroughCell
auto *lower_net = lower->ports.at(id_IN1).net;
auto *upper_net = lower->ports.at(id_IN1).net;
if (lower_net) {
NPNR_ASSERT(lower_net != nullptr);
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");
if (net_is_gnd || net_is_vcc) {
@ -95,9 +99,9 @@ struct APassThroughCell
}
}
if (upper_net) {
bool net_is_gnd = upper_net->name == ctx->idf("$PACKER_GND");
bool net_is_vcc = upper_net->name == ctx->idf("$PACKER_VCC");
{
bool net_is_gnd = lower_net->name == ctx->idf("$PACKER_GND");
bool net_is_vcc = lower_net->name == ctx->idf("$PACKER_VCC");
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);
@ -108,6 +112,7 @@ struct APassThroughCell
CellInfo *lower;
CellInfo *upper;
bool inverted;
};
// Propagate B0 through POUTY1 and B1 through COUTY1
@ -139,7 +144,7 @@ struct BPassThroughCell
void clean_up(Context *ctx)
{
auto *lower_net = lower->ports.at(id_IN1).net;
auto *upper_net = lower->ports.at(id_IN1).net;
auto *upper_net = upper->ports.at(id_IN1).net;
if (lower_net) {
bool net_is_gnd = lower_net->name == ctx->idf("$PACKER_GND");
@ -491,13 +496,13 @@ void GateMatePacker::pack_mult()
// Sign-extend odd A_WIDTH to even, because we're working with 2x2 multiplier cells.
if (a_width % 2 == 1) {
mult->copyPortTo(ctx->idf("A[%d]", a_width), mult, ctx->idf("A[%d]", a_width + 1));
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), mult, ctx->idf("B[%d]", b_width + 1));
mult->copyPortTo(ctx->idf("B[%d]", b_width - 1), mult, ctx->idf("B[%d]", b_width));
b_width += 1;
}
@ -569,8 +574,6 @@ void GateMatePacker::pack_mult()
// Step 3: connect them.
// TODO: check this with odd bus widths.
// Zero driver.
auto *zero_net = ctx->createNet(m.zero.upper->name);
m.zero.upper->connectPort(id_OUT, zero_net);
@ -584,6 +587,7 @@ void GateMatePacker::pack_mult()
mult->movePortTo(ctx->idf("A[%d]", a), cpe_half, id_IN1);
// This may be GND/VCC; if so, clean it up.
if (a % 2 == 1)
a_passthru.clean_up(ctx);
// Connect A passthrough output to multiplier inputs.
@ -633,6 +637,7 @@ void GateMatePacker::pack_mult()
mult->movePortTo(ctx->idf("B[%d]", b), cpe_half, id_IN1);
// This may be GND/VCC; if so, clean it up.
if (b % 2 == 1)
b_passthru.clean_up(ctx);
}
{
@ -659,6 +664,7 @@ void GateMatePacker::pack_mult()
mult->movePortTo(ctx->idf("P[%d]", p + diagonal_p_width), cpe_half, id_OUT);
}
// We don't need the original cell anymore.
ctx->cells.erase(mult->name);
log_info(" Created %zu CPEs.\n", m.cpe_count());