Handle DFR

This commit is contained in:
Miodrag Milanovic 2024-07-03 09:30:36 +02:00
parent f7c446e930
commit d1207b10c0
3 changed files with 77 additions and 49 deletions

View File

@ -290,15 +290,20 @@ struct BitstreamJsonBackend
void write_dfr(CellInfo *cell) {
open_instance(cell);
//add_config("data_inv", bool_or_default(cell->params, ctx->id("data_inv"), false));
//add_config("dff_edge", bool_or_default(cell->params, ctx->id("dff_edge"), false));
//add_config("dff_init", bool_or_default(cell->params, ctx->id("dff_init"), false));
//add_config("dff_load", bool_or_default(cell->params, ctx->id("dff_load"), false));
//add_config("dff_sync", bool_or_default(cell->params, ctx->id("dff_sync"), false));
//add_config("dff_type", bool_or_default(cell->params, ctx->id("dff_type"), false));
//add_config("location", str_or_default(cell->params, ctx->id("location"), ""));
add_config("data_inv", bool_or_default(cell->params, ctx->id("data_inv"), false));
add_config("dff_edge", bool_or_default(cell->params, ctx->id("dff_edge"), false));
add_config("dff_init", bool_or_default(cell->params, ctx->id("dff_init"), false));
add_config("dff_load", bool_or_default(cell->params, ctx->id("dff_load"), false));
add_config("dff_sync", bool_or_default(cell->params, ctx->id("dff_sync"), false));
add_config("dff_type", bool_or_default(cell->params, ctx->id("dff_type"), false));
add_config("mode", int_or_default(cell->params, ctx->id("mode"), 3));
add_config("iobname", str_or_default(cell->params, ctx->id("iobname"), ""));
close_instance();
}
void write_bfr(CellInfo *cell) {
open_instance(cell);
add_config("mode", int_or_default(cell->params, ctx->id("mode"), 2));
//add_config("path", int_or_default(cell->params, ctx->id("path"), 0));
add_config("iobname", str_or_default(cell->params, ctx->id("iobname"), ""));
if (cell->params.count(ctx->id("data_inv"))) {
add_config("data_inv", bool_or_default(cell->params, ctx->id("data_inv"), false));
@ -531,8 +536,8 @@ struct BitstreamJsonBackend
case id_WFG.index: write_wfg(cell.second.get()); break;
case id_GCK.index: write_gck(cell.second.get()); break;
case id_IOM.index: write_iom(cell.second.get()); break;
case id_BFR.index:
case id_DDFR.index:
case id_BFR.index: write_bfr(cell.second.get()); break;
//case id_DDFR.index:
case id_DFR.index: write_dfr(cell.second.get()); break;
case id_RAM.index: write_ram(cell.second.get()); break;
case id_RF.index:

View File

@ -131,6 +131,45 @@ void NgUltraPacker::update_lut_init()
flush_cells();
}
void NgUltraPacker::dff_rewrite(CellInfo *cell)
{
if (int_or_default(cell->params, ctx->id("dff_init"), 0)==0) {
// Reset not used
cell->disconnectPort(id_R);
} else {
// Reset used
NetInfo *net = cell->getPort(id_R);
if (net) {
if (net->name == ctx->id("$PACKER_GND")) {
log_warning("Removing reset on '%s' since it is always 0.\n", cell->name.c_str(ctx));
cell->disconnectPort(id_R);
} else if (net->name == ctx->id("$PACKER_VCC")) {
log_error("Invalid DFF configuration, reset on '%s' is always 1.\n", cell->name.c_str(ctx));
}
}
}
if (int_or_default(cell->params, ctx->id("dff_load"), 0)==0) {
// Load not used
cell->disconnectPort(id_L);
} else {
// Load used
NetInfo *net = cell->getPort(id_L);
if (net) {
if (net->name == ctx->id("$PACKER_VCC")) {
log_warning("Removing load enable on '%s' since it is always 1.\n", cell->name.c_str(ctx));
cell->disconnectPort(id_L);
} else if (net->name == ctx->id("$PACKER_GND")) {
log_warning("Converting to self loop, since load enable on '%s' is always 0.\n", cell->name.c_str(ctx));
cell->disconnectPort(id_L);
cell->disconnectPort(id_I);
NetInfo *out = cell->getPort(id_O);
cell->connectPort(id_I, out);
}
}
}
}
void NgUltraPacker::update_dffs()
{
log_info("Update DFFs...\n");
@ -138,42 +177,7 @@ void NgUltraPacker::update_dffs()
CellInfo &ci = *cell.second;
if (!ci.type.in(id_NX_DFF))
continue;
if (int_or_default(ci.params, ctx->id("dff_init"), 0)==0) {
// Reset not used
ci.disconnectPort(id_R);
} else {
// Reset used
NetInfo *net = ci.getPort(id_R);
if (net) {
if (net->name == ctx->id("$PACKER_GND")) {
log_warning("Removing reset on '%s' since it is always 0.\n", ci.name.c_str(ctx));
ci.disconnectPort(id_R);
} else if (net->name == ctx->id("$PACKER_VCC")) {
log_error("Invalid DFF configuration, reset on '%s' is always 1.\n", ci.name.c_str(ctx));
}
}
}
if (int_or_default(ci.params, ctx->id("dff_load"), 0)==0) {
// Load not used
ci.disconnectPort(id_L);
} else {
// Load used
NetInfo *net = ci.getPort(id_L);
if (net) {
if (net->name == ctx->id("$PACKER_VCC")) {
log_warning("Removing load enable on '%s' since it is always 1.\n", ci.name.c_str(ctx));
ci.disconnectPort(id_L);
} else if (net->name == ctx->id("$PACKER_GND")) {
log_warning("Converting to self loop, since load enable on '%s' is always 0.\n", ci.name.c_str(ctx));
ci.disconnectPort(id_L);
ci.disconnectPort(id_I);
NetInfo *out = ci.getPort(id_O);
ci.connectPort(id_I, out);
}
}
}
dff_rewrite(&ci);
}
}
@ -526,6 +530,7 @@ void NgUltraPacker::pack_iobs(void)
to_update.push_back(&ci);
}
int bfr_added = 0;
int dfr_added = 0;
for (auto cell : to_update) {
NetInfo *c_net = cell->getPort(id_C);
if (!c_net)
@ -567,7 +572,12 @@ void NgUltraPacker::pack_iobs(void)
}
iod->connectPort(id_O, new_out);
cell->connectPort(id_C,new_out);
} else log_error("TODO handle DFR");
} else {
dfr_added++;
iod->type = id_DFR;
iod->setParam(ctx->id("iobname"),str_or_default(cell->params, ctx->id("iobname"), ""));
dff_rewrite(iod);
}
Loc cd_loc = cell->getLocation();
cd_loc.z += 3;
BelId bel = ctx->getBelByLocation(cd_loc);
@ -595,7 +605,12 @@ void NgUltraPacker::pack_iobs(void)
}
iod->connectPort(id_O, new_out);
cell->connectPort(id_I,new_out);
} else log_error("TODO handle DFR");
} else {
dfr_added++;
iod->type = id_DFR;
iod->setParam(ctx->id("iobname"),str_or_default(cell->params, ctx->id("iobname"), ""));
dff_rewrite(iod);
}
Loc cd_loc = cell->getLocation();
cd_loc.z += 2;
BelId bel = ctx->getBelByLocation(cd_loc);
@ -619,7 +634,12 @@ void NgUltraPacker::pack_iobs(void)
iod->connectPort(id_I, new_in);
cell->connectPort(id_O,new_in);
bfr_mode = true;
} else log_error("TODO handle DFR");
} else {
dfr_added++;
iod->type = id_DFR;
iod->setParam(ctx->id("iobname"),str_or_default(cell->params, ctx->id("iobname"), ""));
dff_rewrite(iod);
}
Loc cd_loc = cell->getLocation();
cd_loc.z += 1;
BelId bel = ctx->getBelByLocation(cd_loc);
@ -643,6 +663,8 @@ void NgUltraPacker::pack_iobs(void)
}
}
}
if (dfr_added)
log_info(" %6d DFRs/DDFRs used as DFR\n", dfr_added);
if (bfr_added)
log_info(" %6d DFRs/DDFRs used as BFR\n", bfr_added);
flush_cells();

View File

@ -77,6 +77,7 @@ private:
void set_lut_input_if_constant(CellInfo *cell, IdString input);
void lut_to_fe(CellInfo *lut, CellInfo *fe, bool no_dff, Property lut_table);
void dff_to_fe(CellInfo *dff, CellInfo *fe, bool pass_thru_lut);
void dff_rewrite(CellInfo *cell);
void exchange_if_constant(CellInfo *cell, IdString input1, IdString input2);
void pack_cy_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, int placer, int &lut_only, int &lut_and_ff, int &dff_only);