Handle DFR
This commit is contained in:
parent
f7c446e930
commit
d1207b10c0
@ -290,15 +290,20 @@ struct BitstreamJsonBackend
|
|||||||
|
|
||||||
void write_dfr(CellInfo *cell) {
|
void write_dfr(CellInfo *cell) {
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
//add_config("data_inv", bool_or_default(cell->params, ctx->id("data_inv"), false));
|
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_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_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_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_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("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("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("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"), ""));
|
add_config("iobname", str_or_default(cell->params, ctx->id("iobname"), ""));
|
||||||
if (cell->params.count(ctx->id("data_inv"))) {
|
if (cell->params.count(ctx->id("data_inv"))) {
|
||||||
add_config("data_inv", bool_or_default(cell->params, ctx->id("data_inv"), false));
|
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_WFG.index: write_wfg(cell.second.get()); break;
|
||||||
case id_GCK.index: write_gck(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_IOM.index: write_iom(cell.second.get()); break;
|
||||||
case id_BFR.index:
|
case id_BFR.index: write_bfr(cell.second.get()); break;
|
||||||
case id_DDFR.index:
|
//case id_DDFR.index:
|
||||||
case id_DFR.index: write_dfr(cell.second.get()); break;
|
case id_DFR.index: write_dfr(cell.second.get()); break;
|
||||||
case id_RAM.index: write_ram(cell.second.get()); break;
|
case id_RAM.index: write_ram(cell.second.get()); break;
|
||||||
case id_RF.index:
|
case id_RF.index:
|
||||||
|
@ -131,6 +131,45 @@ void NgUltraPacker::update_lut_init()
|
|||||||
flush_cells();
|
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()
|
void NgUltraPacker::update_dffs()
|
||||||
{
|
{
|
||||||
log_info("Update DFFs...\n");
|
log_info("Update DFFs...\n");
|
||||||
@ -138,42 +177,7 @@ void NgUltraPacker::update_dffs()
|
|||||||
CellInfo &ci = *cell.second;
|
CellInfo &ci = *cell.second;
|
||||||
if (!ci.type.in(id_NX_DFF))
|
if (!ci.type.in(id_NX_DFF))
|
||||||
continue;
|
continue;
|
||||||
|
dff_rewrite(&ci);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,6 +530,7 @@ void NgUltraPacker::pack_iobs(void)
|
|||||||
to_update.push_back(&ci);
|
to_update.push_back(&ci);
|
||||||
}
|
}
|
||||||
int bfr_added = 0;
|
int bfr_added = 0;
|
||||||
|
int dfr_added = 0;
|
||||||
for (auto cell : to_update) {
|
for (auto cell : to_update) {
|
||||||
NetInfo *c_net = cell->getPort(id_C);
|
NetInfo *c_net = cell->getPort(id_C);
|
||||||
if (!c_net)
|
if (!c_net)
|
||||||
@ -567,7 +572,12 @@ void NgUltraPacker::pack_iobs(void)
|
|||||||
}
|
}
|
||||||
iod->connectPort(id_O, new_out);
|
iod->connectPort(id_O, new_out);
|
||||||
cell->connectPort(id_C,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();
|
Loc cd_loc = cell->getLocation();
|
||||||
cd_loc.z += 3;
|
cd_loc.z += 3;
|
||||||
BelId bel = ctx->getBelByLocation(cd_loc);
|
BelId bel = ctx->getBelByLocation(cd_loc);
|
||||||
@ -595,7 +605,12 @@ void NgUltraPacker::pack_iobs(void)
|
|||||||
}
|
}
|
||||||
iod->connectPort(id_O, new_out);
|
iod->connectPort(id_O, new_out);
|
||||||
cell->connectPort(id_I,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();
|
Loc cd_loc = cell->getLocation();
|
||||||
cd_loc.z += 2;
|
cd_loc.z += 2;
|
||||||
BelId bel = ctx->getBelByLocation(cd_loc);
|
BelId bel = ctx->getBelByLocation(cd_loc);
|
||||||
@ -619,7 +634,12 @@ void NgUltraPacker::pack_iobs(void)
|
|||||||
iod->connectPort(id_I, new_in);
|
iod->connectPort(id_I, new_in);
|
||||||
cell->connectPort(id_O,new_in);
|
cell->connectPort(id_O,new_in);
|
||||||
bfr_mode = true;
|
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();
|
Loc cd_loc = cell->getLocation();
|
||||||
cd_loc.z += 1;
|
cd_loc.z += 1;
|
||||||
BelId bel = ctx->getBelByLocation(cd_loc);
|
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)
|
if (bfr_added)
|
||||||
log_info(" %6d DFRs/DDFRs used as BFR\n", bfr_added);
|
log_info(" %6d DFRs/DDFRs used as BFR\n", bfr_added);
|
||||||
flush_cells();
|
flush_cells();
|
||||||
|
@ -77,6 +77,7 @@ private:
|
|||||||
void set_lut_input_if_constant(CellInfo *cell, IdString input);
|
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 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_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 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);
|
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user