From b97a9cd3f3619f035af4792de199298487c689a9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 11:49:13 -0800 Subject: [PATCH 1/8] Supress error for unhandled \init if whole module selected --- passes/techmap/zinit.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index a427c4987..5cfc82ac9 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -141,9 +141,10 @@ struct ZinitPass : public Pass { cell->setPort(ID::Q, initwire); } - for (auto &it : initbits) - if (donebits.count(it.first) == 0) - log_error("Failed to handle init bit %s = %s.\n", log_signal(it.first), log_signal(it.second)); + if (!design->selected_whole_module(module)) + for (auto &it : initbits) + if (donebits.count(it.first) == 0) + log_error("Failed to handle init bit %s = %s.\n", log_signal(it.first), log_signal(it.second)); } } } ZinitPass; From 3c5a9411b1c17d9e4474fb7edb54117c2298cfc1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 12:10:30 -0800 Subject: [PATCH 2/8] Add testcase for $_DFF_[NP][NP][01]_ --- tests/techmap/zinit.ys | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/techmap/zinit.ys diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys new file mode 100644 index 000000000..3652f2d72 --- /dev/null +++ b/tests/techmap/zinit.ys @@ -0,0 +1,24 @@ +read_verilog -icells < Date: Wed, 11 Dec 2019 12:17:01 -0800 Subject: [PATCH 3/8] zinit to transform set/reset value of $_DFF_[NP][NP][01]_ --- passes/techmap/zinit.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 5cfc82ac9..f982dbb30 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -139,6 +139,20 @@ struct ZinitPass : public Pass { cell->setPort(ID::D, sig_d); cell->setPort(ID::Q, initwire); + + /*if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), + ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) + { + // TODO: I think I need a $_DFFRS_* cell where R has priority over S... + std::swap(cell->connections_.at(ID(R)), cell->connections_.at(ID(S))); + } + else*/ if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) + { + std::string t = cell->type.str(); + t[8] = (t[8] == '0' ? '1' : '0'); + cell->type = t; + } } if (!design->selected_whole_module(module)) From 1cdfdbc6d106cf706c22518a80837e9ed769711b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 11 Dec 2019 14:31:23 -0800 Subject: [PATCH 4/8] Fix S/R comment; thanks @mwkmwkmwk --- passes/techmap/zinit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index f982dbb30..f7c63b8f8 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -143,7 +143,7 @@ struct ZinitPass : public Pass { /*if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) { - // TODO: I think I need a $_DFFRS_* cell where R has priority over S... + // TODO: I think I need a $_DFFRS_* cell where S has priority over R... std::swap(cell->connections_.at(ID(R)), cell->connections_.at(ID(S))); } else*/ if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), From 70bca35f9cc820c05ddbd02703c13f9cf9135756 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Apr 2020 14:28:53 -0700 Subject: [PATCH 5/8] zinit: operate on $adff, erase (* init *) entries on consumption --- passes/techmap/zinit.cc | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index f7c63b8f8..fb2f92d4e 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -57,8 +57,7 @@ struct ZinitPass : public Pass { for (auto module : design->selected_modules()) { SigMap sigmap(module); - dict initbits; - pool donebits; + dict> initbits; for (auto wire : module->selected_wires()) { @@ -67,7 +66,6 @@ struct ZinitPass : public Pass { SigSpec wirebits = sigmap(wire); Const initval = wire->attributes.at(ID::init); - wire->attributes.erase(ID::init); for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) { @@ -78,22 +76,25 @@ struct ZinitPass : public Pass { continue; if (initbits.count(bit)) { - if (initbits.at(bit) != val) + if (initbits.at(bit).first != val) log_error("Conflicting init values for signal %s (%s = %s != %s).\n", log_signal(bit), log_signal(SigBit(wire, i)), - log_signal(val), log_signal(initbits.at(bit))); + log_signal(val), log_signal(initbits.at(bit).first)); continue; } - initbits[bit] = val; + initbits[bit] = std::make_pair(val,SigBit(wire,i)); } } pool dff_types = { - ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($adff), + // FIXME: It would appear that supporting + // $dffsr/$_DFFSR_* would require a new + // cell type where S has priority over R + ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff), ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), - ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_), + /*ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), + ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),*/ ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_) }; @@ -113,8 +114,10 @@ struct ZinitPass : public Pass { for (int i = 0; i < GetSize(sig_q); i++) { if (initbits.count(sig_q[i])) { - initval.bits.push_back(initbits.at(sig_q[i])); - donebits.insert(sig_q[i]); + const auto &d = initbits.at(sig_q[i]); + initval.bits.push_back(d.first); + const auto &b = d.second; + b.wire->attributes.at(ID::init)[b.offset]; } else initval.bits.push_back(all_mode ? State::S0 : State::Sx); } @@ -140,13 +143,13 @@ struct ZinitPass : public Pass { cell->setPort(ID::D, sig_d); cell->setPort(ID::Q, initwire); - /*if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_))) - { - // TODO: I think I need a $_DFFRS_* cell where S has priority over R... - std::swap(cell->connections_.at(ID(R)), cell->connections_.at(ID(S))); + if (cell->type == ID($adff)) { + auto val = cell->getParam(ID::ARST_VALUE); + for (auto &b : val) + b = (b == State::S1 ? State::S0 : State::S1); + cell->setParam(ID::ARST_VALUE, std::move(val)); } - else*/ if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), + else if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) { std::string t = cell->type.str(); @@ -154,11 +157,6 @@ struct ZinitPass : public Pass { cell->type = t; } } - - if (!design->selected_whole_module(module)) - for (auto &it : initbits) - if (donebits.count(it.first) == 0) - log_error("Failed to handle init bit %s = %s.\n", log_signal(it.first), log_signal(it.second)); } } } ZinitPass; From 091297b9ee9c7874f17abb855f6c612c448cec70 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 13 Apr 2020 14:29:44 -0700 Subject: [PATCH 6/8] tests: zinit on $adff --- tests/techmap/zinit.ys | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys index 3652f2d72..caeab69d3 100644 --- a/tests/techmap/zinit.ys +++ b/tests/techmap/zinit.ys @@ -1,24 +1,23 @@ read_verilog -icells < Date: Mon, 13 Apr 2020 15:16:51 -0700 Subject: [PATCH 7/8] zinit: fix review comments from @mwkmwkmwk --- passes/techmap/zinit.cc | 11 ++++++----- tests/techmap/zinit.ys | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index fb2f92d4e..b7beb4e9d 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -117,7 +117,7 @@ struct ZinitPass : public Pass { const auto &d = initbits.at(sig_q[i]); initval.bits.push_back(d.first); const auto &b = d.second; - b.wire->attributes.at(ID::init)[b.offset]; + b.wire->attributes.at(ID::init)[b.offset] = State::Sx; } else initval.bits.push_back(all_mode ? State::S0 : State::Sx); } @@ -126,11 +126,11 @@ struct ZinitPass : public Pass { initwire->attributes[ID::init] = initval; for (int i = 0; i < GetSize(initwire); i++) - if (initval.bits.at(i) == State::S1) + if (initval[i] == State::S1) { sig_d[i] = module->NotGate(NEW_ID, sig_d[i]); module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]); - initwire->attributes[ID::init].bits.at(i) = State::S0; + initwire->attributes[ID::init][i] = State::S0; } else { @@ -145,8 +145,9 @@ struct ZinitPass : public Pass { if (cell->type == ID($adff)) { auto val = cell->getParam(ID::ARST_VALUE); - for (auto &b : val) - b = (b == State::S1 ? State::S0 : State::S1); + for (int i = 0; i < GetSize(initwire); i++) + if (initval[i] == State::S1) + val[i] = (val[i] == State::S1 ? State::S0 : State::S1); cell->setParam(ID::ARST_VALUE, std::move(val)); } else if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys index caeab69d3..c74218f7c 100644 --- a/tests/techmap/zinit.ys +++ b/tests/techmap/zinit.ys @@ -1,5 +1,5 @@ read_verilog -icells < Date: Mon, 13 Apr 2020 15:25:37 -0700 Subject: [PATCH 8/8] zinit: resolve one more comment by @mwkmwkmwk --- passes/techmap/zinit.cc | 8 +++++--- tests/techmap/zinit.ys | 9 ++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index b7beb4e9d..9eb47ff6d 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -153,9 +153,11 @@ struct ZinitPass : public Pass { else if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) { - std::string t = cell->type.str(); - t[8] = (t[8] == '0' ? '1' : '0'); - cell->type = t; + if (initval == State::S1) { + std::string t = cell->type.str(); + t[8] = (t[8] == '0' ? '1' : '0'); + cell->type = t; + } } } } diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys index c74218f7c..18b17621f 100644 --- a/tests/techmap/zinit.ys +++ b/tests/techmap/zinit.ys @@ -23,6 +23,8 @@ design -load postopt select -assert-count 20 t:$_NOT_ select -assert-count 1 w:unused a:init %i select -assert-count 1 w:Q a:init=13'bxxxx1xxxxxxxx %i +select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFF_??1_ %i +select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFF_??0_ %i design -reset @@ -45,6 +47,11 @@ $adff #(.WIDTH(2), .CLK_POLARITY(1), .ARST_POLARITY(1'b0), .ARST_VALUE(2'b10)) d $adff #(.WIDTH(2), .CLK_POLARITY(0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'b01)) dff9 (.CLK(C), .ARST(R), .D(D), .Q(Q[12:11])); endmodule EOT +equiv_opt -assert -map +/simcells.v -multiclock zinit +design -load postopt + select -assert-count 0 t:$_NOT_ select -assert-count 1 w:unused a:init %i -select -assert-count 1 w:Q a:init=13'bx00x100000000 %i +select -assert-count 1 w:Q a:init=13'bxxxx1xxxxxxxx %i +select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFF_??0_ %i +select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFF_??1_ %i