From d1207b10c0b9d9d288d16382ec824ff244fe8e61 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 3 Jul 2024 09:30:36 +0200 Subject: [PATCH] Handle DFR --- himbaechel/uarch/ng-ultra/bitstream.cc | 25 ++++--- himbaechel/uarch/ng-ultra/pack.cc | 100 +++++++++++++++---------- himbaechel/uarch/ng-ultra/pack.h | 1 + 3 files changed, 77 insertions(+), 49 deletions(-) diff --git a/himbaechel/uarch/ng-ultra/bitstream.cc b/himbaechel/uarch/ng-ultra/bitstream.cc index 1120b59c..3ad0c2db 100644 --- a/himbaechel/uarch/ng-ultra/bitstream.cc +++ b/himbaechel/uarch/ng-ultra/bitstream.cc @@ -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: diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index 0f018233..1907d66a 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -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(); diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index 3f09f8d8..451d8066 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -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);