diff options
Diffstat (limited to 'passes/techmap/dfflegalize.cc')
-rw-r--r-- | passes/techmap/dfflegalize.cc | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc index 7f2cdc6ac..13ce4f49a 100644 --- a/passes/techmap/dfflegalize.cc +++ b/passes/techmap/dfflegalize.cc @@ -364,7 +364,7 @@ flip_dqi: // Some DFF is supported with this init val. Just pick a type. if (ff_type == FF_DFF) { // Try adding a set or reset pin. - for (auto new_type: {FF_ADFF0, FF_ADFF1, FF_SDFF0, FF_SDFF1}) + for (auto new_type: {FF_SDFF0, FF_SDFF1, FF_ADFF0, FF_ADFF1}) if (supported_cells[new_type] & initmask) { ff_type = new_type; sig_r = State::S0; @@ -529,7 +529,7 @@ unmap_enable: } if (supported_dffsr & flip_initmask(initmask)) { flip_dqisr:; - log_warning("Flipping D/Q/init and inseerting set/reset fixup to handle init value on %s.%s [%s]\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type)); + log_warning("Flipping D/Q/init and inserting set/reset fixup to handle init value on %s.%s [%s]\n", log_id(cell->module->name), log_id(cell->name), log_id(cell->type)); SigSpec new_r; bool neg_r = (ff_neg & NEG_R); bool neg_s = (ff_neg & NEG_S); @@ -659,6 +659,24 @@ flip_dqisr:; // This init value is not supported at all... if (supported_dlatch & flip_initmask(initmask)) goto flip_dqi; + + if ((sig_d == State::S0 && (supported_adff0 & initmask)) || + (sig_d == State::S1 && (supported_adff1 & initmask)) || + (sig_d == State::S0 && (supported_adff1 & flip_initmask(initmask))) || + (sig_d == State::S1 && (supported_adff0 & flip_initmask(initmask))) + ) { + // Special case: const-D dlatch can be converted into adff with const clock. + ff_type = (sig_d == State::S0) ? FF_ADFF0 : FF_ADFF1; + if (ff_neg & NEG_E) { + ff_neg &= ~NEG_E; + ff_neg |= NEG_R; + } + sig_r = sig_e; + sig_d = State::Sx; + sig_c = State::S1; + continue; + } + if (!supported_dlatch) reason = "dlatch are not supported"; else @@ -1278,7 +1296,7 @@ unrecognized: sigmap.set(module); initbits.clear(); - for (auto wire : module->selected_wires()) + for (auto wire : module->wires()) { if (wire->attributes.count(ID::init) == 0) continue; |