Add $aldff and $aldffe: flip-flops with async load.
authorMarcelina Kościelnicka <mwk@0x04.net>
Fri, 1 Oct 2021 02:33:00 +0000 (04:33 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Sat, 2 Oct 2021 16:12:52 +0000 (18:12 +0200)
CHANGELOG
kernel/celltypes.h
kernel/constids.inc
kernel/rtlil.cc
kernel/rtlil.h
manual/CHAPTER_CellLib.tex
techlibs/common/gen_fine_ffs.py
techlibs/common/simcells.v
techlibs/common/simlib.v

index fe85723af8b536e9beead457be2ae0709f975b7d..a6285ddb2944ecc572cee11a76a8fcd65093b401 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,8 @@ List of major changes and improvements between releases
 Yosys 0.10 .. Yosys 0.10-dev
 --------------------------
 
+ * Various
+    - Added $aldff and $aldffe (flip-flops with async load) cells
 
 Yosys 0.9 .. Yosys 0.10
 --------------------------
index a977501e3e81727e0097fa8e59d4f8976e3a767b..879ac0edc0b34bb0bcdfb250b3d75614992f1c21 100644 (file)
@@ -142,6 +142,8 @@ struct CellTypes
                setup_type(ID($dffsre), {ID::CLK, ID::SET, ID::CLR, ID::D, ID::EN}, {ID::Q});
                setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q});
                setup_type(ID($adffe), {ID::CLK, ID::ARST, ID::D, ID::EN}, {ID::Q});
+               setup_type(ID($aldff), {ID::CLK, ID::ALOAD, ID::AD, ID::D}, {ID::Q});
+               setup_type(ID($aldffe), {ID::CLK, ID::ALOAD, ID::AD, ID::D, ID::EN}, {ID::Q});
                setup_type(ID($sdff), {ID::CLK, ID::SRST, ID::D}, {ID::Q});
                setup_type(ID($sdffe), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q});
                setup_type(ID($sdffce), {ID::CLK, ID::SRST, ID::D, ID::EN}, {ID::Q});
@@ -224,6 +226,15 @@ struct CellTypes
                for (auto c4 : list_np)
                        setup_type(stringf("$_DFFE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::R, ID::D, ID::E}, {ID::Q});
 
+               for (auto c1 : list_np)
+               for (auto c2 : list_np)
+                       setup_type(stringf("$_ALDFF_%c%c_", c1, c2), {ID::C, ID::L, ID::AD, ID::D}, {ID::Q});
+
+               for (auto c1 : list_np)
+               for (auto c2 : list_np)
+               for (auto c3 : list_np)
+                       setup_type(stringf("$_ALDFFE_%c%c%c_", c1, c2, c3), {ID::C, ID::L, ID::AD, ID::D, ID::E}, {ID::Q});
+
                for (auto c1 : list_np)
                for (auto c2 : list_np)
                for (auto c3 : list_np)
index 68d10def6c986cd2eeeedfbe3293c90edf4831d8..8d8e97eb7fbaf0675104e11898821b602a94d091 100644 (file)
@@ -11,9 +11,12 @@ X(abc9_mergeability)
 X(abc9_scc_id)
 X(abcgroup)
 X(ABITS)
+X(AD)
 X(ADDR)
 X(allconst)
 X(allseq)
+X(ALOAD)
+X(ALOAD_POLARITY)
 X(always_comb)
 X(always_ff)
 X(always_latch)
index a05023c52936eb619b61221e1ce89d1cc5edf713..3778972bcfd619fa2f97e6e7f43c127be70dd573 100644 (file)
@@ -58,6 +58,8 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
                ID($dffsre),
                ID($adff),
                ID($adffe),
+               ID($aldff),
+               ID($aldffe),
                ID($sdff),
                ID($sdffe),
                ID($sdffce),
@@ -118,6 +120,18 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
                ID($_DFFE_PP0P_),
                ID($_DFFE_PP1N_),
                ID($_DFFE_PP1P_),
+               ID($_ALDFF_NN_),
+               ID($_ALDFF_NP_),
+               ID($_ALDFF_PN_),
+               ID($_ALDFF_PP_),
+               ID($_ALDFFE_NNN_),
+               ID($_ALDFFE_NNP_),
+               ID($_ALDFFE_NPN_),
+               ID($_ALDFFE_NPP_),
+               ID($_ALDFFE_PNN_),
+               ID($_ALDFFE_PNP_),
+               ID($_ALDFFE_PPN_),
+               ID($_ALDFFE_PPP_),
                ID($_SDFF_NN0_),
                ID($_SDFF_NN1_),
                ID($_SDFF_NP0_),
@@ -1337,6 +1351,32 @@ namespace {
                                return;
                        }
 
+                       if (cell->type == ID($aldff)) {
+                               param_bool(ID::CLK_POLARITY);
+                               param_bool(ID::ALOAD_POLARITY);
+                               port(ID::CLK, 1);
+                               port(ID::ALOAD, 1);
+                               port(ID::D, param(ID::WIDTH));
+                               port(ID::AD, param(ID::WIDTH));
+                               port(ID::Q, param(ID::WIDTH));
+                               check_expected();
+                               return;
+                       }
+
+                       if (cell->type == ID($aldffe)) {
+                               param_bool(ID::CLK_POLARITY);
+                               param_bool(ID::EN_POLARITY);
+                               param_bool(ID::ALOAD_POLARITY);
+                               port(ID::CLK, 1);
+                               port(ID::EN, 1);
+                               port(ID::ALOAD, 1);
+                               port(ID::D, param(ID::WIDTH));
+                               port(ID::AD, param(ID::WIDTH));
+                               port(ID::Q, param(ID::WIDTH));
+                               check_expected();
+                               return;
+                       }
+
                        if (cell->type == ID($dlatch)) {
                                param_bool(ID::EN_POLARITY);
                                port(ID::EN, 1);
@@ -1648,6 +1688,15 @@ namespace {
                                        ID($_DFFE_PP0N_), ID($_DFFE_PP0P_), ID($_DFFE_PP1N_), ID($_DFFE_PP1P_)))
                                { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); port(ID::E,1); check_expected(); return; }
 
+                       if (cell->type.in(
+                                       ID($_ALDFF_NN_), ID($_ALDFF_NP_), ID($_ALDFF_PN_), ID($_ALDFF_PP_)))
+                               { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::L,1); port(ID::AD,1); check_expected(); return; }
+
+                       if (cell->type.in(
+                                       ID($_ALDFFE_NNN_), ID($_ALDFFE_NNP_), ID($_ALDFFE_NPN_), ID($_ALDFFE_NPP_),
+                                       ID($_ALDFFE_PNN_), ID($_ALDFFE_PNP_), ID($_ALDFFE_PPN_), ID($_ALDFFE_PPP_)))
+                               { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::L,1); port(ID::AD,1); port(ID::E,1); check_expected(); return; }
+
                        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_)))
@@ -2675,6 +2724,40 @@ RTLIL::Cell* RTLIL::Module::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec
        return cell;
 }
 
+RTLIL::Cell* RTLIL::Module::addAldff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
+               const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src)
+{
+       RTLIL::Cell *cell = addCell(name, ID($aldff));
+       cell->parameters[ID::CLK_POLARITY] = clk_polarity;
+       cell->parameters[ID::ALOAD_POLARITY] = aload_polarity;
+       cell->parameters[ID::WIDTH] = sig_q.size();
+       cell->setPort(ID::CLK, sig_clk);
+       cell->setPort(ID::ALOAD, sig_aload);
+       cell->setPort(ID::D, sig_d);
+       cell->setPort(ID::AD, sig_ad);
+       cell->setPort(ID::Q, sig_q);
+       cell->set_src_attribute(src);
+       return cell;
+}
+
+RTLIL::Cell* RTLIL::Module::addAldffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
+               const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src)
+{
+       RTLIL::Cell *cell = addCell(name, ID($aldffe));
+       cell->parameters[ID::CLK_POLARITY] = clk_polarity;
+       cell->parameters[ID::EN_POLARITY] = en_polarity;
+       cell->parameters[ID::ALOAD_POLARITY] = aload_polarity;
+       cell->parameters[ID::WIDTH] = sig_q.size();
+       cell->setPort(ID::CLK, sig_clk);
+       cell->setPort(ID::EN, sig_en);
+       cell->setPort(ID::ALOAD, sig_aload);
+       cell->setPort(ID::D, sig_d);
+       cell->setPort(ID::AD, sig_ad);
+       cell->setPort(ID::Q, sig_q);
+       cell->set_src_attribute(src);
+       return cell;
+}
+
 RTLIL::Cell* RTLIL::Module::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
                RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const std::string &src)
 {
@@ -2865,6 +2948,33 @@ RTLIL::Cell* RTLIL::Module::addAdffeGate(RTLIL::IdString name, const RTLIL::SigS
        return cell;
 }
 
+RTLIL::Cell* RTLIL::Module::addAldffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
+               const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const std::string &src)
+{
+       RTLIL::Cell *cell = addCell(name, stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N'));
+       cell->setPort(ID::C, sig_clk);
+       cell->setPort(ID::L, sig_aload);
+       cell->setPort(ID::D, sig_d);
+       cell->setPort(ID::AD, sig_ad);
+       cell->setPort(ID::Q, sig_q);
+       cell->set_src_attribute(src);
+       return cell;
+}
+
+RTLIL::Cell* RTLIL::Module::addAldffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
+               const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const std::string &src)
+{
+       RTLIL::Cell *cell = addCell(name, stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
+       cell->setPort(ID::C, sig_clk);
+       cell->setPort(ID::L, sig_aload);
+       cell->setPort(ID::E, sig_en);
+       cell->setPort(ID::D, sig_d);
+       cell->setPort(ID::AD, sig_ad);
+       cell->setPort(ID::Q, sig_q);
+       cell->set_src_attribute(src);
+       return cell;
+}
+
 RTLIL::Cell* RTLIL::Module::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
                bool srst_value, bool clk_polarity, bool srst_polarity, const std::string &src)
 {
index 06198b26a6d1e6da6d7e4a1ad2612d1757728c50..e072d5bd1a36b137bae11f2689f35b2bbadad8c4 100644 (file)
@@ -1312,6 +1312,8 @@ public:
        RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
        RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
        RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst,  const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
+       RTLIL::Cell* addAldff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = "");
+       RTLIL::Cell* addAldffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload,  const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = "");
        RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = "");
        RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst,  const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
        RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
@@ -1349,6 +1351,10 @@ public:
                        bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
        RTLIL::Cell* addAdffeGate  (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
                        bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
+       RTLIL::Cell* addAldffGate   (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
+                       const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = "");
+       RTLIL::Cell* addAldffeGate  (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
+                       const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = "");
        RTLIL::Cell* addSdffGate   (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
                        bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = "");
        RTLIL::Cell* addSdffeGate  (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
index 74ba224df5cee799adce631f88761f94f63f97d6..3c9fb31ccc4c3575bfdf57239d321e30870b2eeb 100644 (file)
@@ -287,13 +287,24 @@ The state of \B{Q} will be set to this value when the reset is active.
 
 Note that the {\tt \$adff} and {\tt \$sdff} cells can only be used when the reset value is constant.
 
+D-type flip-flops with asynchronous load are represented by {\tt \$aldff} cells. As the {\tt \$dff}
+cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{ALOAD}
+input port for the async load enable pin, a \B{AD} input port with the same width as data for
+the async load data, and the following additional parameter:
+
+\begin{itemize}
+\item \B{ALOAD\_POLARITY} \\
+The asynchronous load is active-high if this parameter has the value {\tt 1'b1} and active-low
+if this parameter is {\tt 1'b0}.
+\end{itemize}
+
 D-type flip-flops with asynchronous set and reset are represented by {\tt \$dffsr} cells.
 As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have
 multi-bit \B{SET} and \B{CLR} input ports and the corresponding polarity parameters, like 
 {\tt \$sr} cells.
 
-D-type flip-flops with enable are represented by {\tt \$dffe}, {\tt \$adffe}, {\tt \$dffsre},
-{\tt \$sdffe}, and {\tt \$sdffce} cells, which are enhanced variants of {\tt \$dff}, {\tt \$adff}, {\tt \$dffsr},
+D-type flip-flops with enable are represented by {\tt \$dffe}, {\tt \$adffe}, {\tt \$aldffe}, {\tt \$dffsre},
+{\tt \$sdffe}, and {\tt \$sdffce} cells, which are enhanced variants of {\tt \$dff}, {\tt \$adff}, {\tt \$aldff}, {\tt \$dffsr},
 {\tt \$sdff} (with reset over enable) and {\tt \$sdff} (with enable over reset)
 cells, respectively.  They have the same ports and parameters as their base cell.
 In addition they also have a single-bit \B{EN} input port for the enable pin and the following parameter:
index 5d331e7674601ef3d3b1b4c70ed17b16f3048f1a..25c6ef171c4593e4c215f41119bf5ef53131da63 100644 (file)
@@ -133,6 +133,55 @@ endmodule
 """
 //  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 //-
+//-     $_ALDFF_{C:N|P}{L:N|P}_ (D, C, L, AD, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {L:negative|positive} polarity async load.
+//-
+//- Truth table:    D C L AD | Q
+//-                ----------+---
+//-                 - - {L:0|1} a  | a
+//-                 d {C:\\|/} - -  | d
+//-                 - - - -  | q
+//-
+module \$_ALDFF_{C:N|P}{L:N|P}_ (D, C, L, AD, Q);
+input D, C, L, AD;
+output reg Q;
+always @({C:neg|pos}edge C or {L:neg|pos}edge L) begin
+       if (L == {L:0|1})
+               Q <= AD;
+       else
+               Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_{C:N|P}{L:N|P}{E:N|P}_ (D, C, L, AD, E, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {L:negative|positive} polarity async load and {E:negative|positive}
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - {L:0|1} a  - | a
+//-                 d {C:\\|/} - -  {E:0|1} | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_{C:N|P}{L:N|P}{E:N|P}_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @({C:neg|pos}edge C or {L:neg|pos}edge L) begin
+       if (L == {L:0|1})
+               Q <= AD;
+       else if (E == {E:0|1})
+               Q <= D;
+end
+endmodule
+""",
+"""
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
 //-     $_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q)
 //-
 //- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive}
index 7d9bebe2af099e53e7c859ed694ddfd6507c7082..ad1fdc817569ddda6c67159fd9a7023fb7e2f715 100644 (file)
@@ -1252,6 +1252,290 @@ always @(posedge C or posedge R) begin
 end
 endmodule
 
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFF_NN_ (D, C, L, AD, Q)
+//-
+//- A negative edge D-type flip-flop with negative polarity async load.
+//-
+//- Truth table:    D C L AD | Q
+//-                ----------+---
+//-                 - - 0 a  | a
+//-                 d \ - -  | d
+//-                 - - - -  | q
+//-
+module \$_ALDFF_NN_ (D, C, L, AD, Q);
+input D, C, L, AD;
+output reg Q;
+always @(negedge C or negedge L) begin
+       if (L == 0)
+               Q <= AD;
+       else
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFF_NP_ (D, C, L, AD, Q)
+//-
+//- A negative edge D-type flip-flop with positive polarity async load.
+//-
+//- Truth table:    D C L AD | Q
+//-                ----------+---
+//-                 - - 1 a  | a
+//-                 d \ - -  | d
+//-                 - - - -  | q
+//-
+module \$_ALDFF_NP_ (D, C, L, AD, Q);
+input D, C, L, AD;
+output reg Q;
+always @(negedge C or posedge L) begin
+       if (L == 1)
+               Q <= AD;
+       else
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFF_PN_ (D, C, L, AD, Q)
+//-
+//- A positive edge D-type flip-flop with negative polarity async load.
+//-
+//- Truth table:    D C L AD | Q
+//-                ----------+---
+//-                 - - 0 a  | a
+//-                 d / - -  | d
+//-                 - - - -  | q
+//-
+module \$_ALDFF_PN_ (D, C, L, AD, Q);
+input D, C, L, AD;
+output reg Q;
+always @(posedge C or negedge L) begin
+       if (L == 0)
+               Q <= AD;
+       else
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFF_PP_ (D, C, L, AD, Q)
+//-
+//- A positive edge D-type flip-flop with positive polarity async load.
+//-
+//- Truth table:    D C L AD | Q
+//-                ----------+---
+//-                 - - 1 a  | a
+//-                 d / - -  | d
+//-                 - - - -  | q
+//-
+module \$_ALDFF_PP_ (D, C, L, AD, Q);
+input D, C, L, AD;
+output reg Q;
+always @(posedge C or posedge L) begin
+       if (L == 1)
+               Q <= AD;
+       else
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_NNN_ (D, C, L, AD, E, Q)
+//-
+//- A negative edge D-type flip-flop with negative polarity async load and negative
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 0 a  - | a
+//-                 d \ - -  0 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_NNN_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(negedge C or negedge L) begin
+       if (L == 0)
+               Q <= AD;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_NNP_ (D, C, L, AD, E, Q)
+//-
+//- A negative edge D-type flip-flop with negative polarity async load and positive
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 0 a  - | a
+//-                 d \ - -  1 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_NNP_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(negedge C or negedge L) begin
+       if (L == 0)
+               Q <= AD;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_NPN_ (D, C, L, AD, E, Q)
+//-
+//- A negative edge D-type flip-flop with positive polarity async load and negative
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 1 a  - | a
+//-                 d \ - -  0 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_NPN_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(negedge C or posedge L) begin
+       if (L == 1)
+               Q <= AD;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_NPP_ (D, C, L, AD, E, Q)
+//-
+//- A negative edge D-type flip-flop with positive polarity async load and positive
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 1 a  - | a
+//-                 d \ - -  1 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_NPP_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(negedge C or posedge L) begin
+       if (L == 1)
+               Q <= AD;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_PNN_ (D, C, L, AD, E, Q)
+//-
+//- A positive edge D-type flip-flop with negative polarity async load and negative
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 0 a  - | a
+//-                 d / - -  0 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_PNN_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(posedge C or negedge L) begin
+       if (L == 0)
+               Q <= AD;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_PNP_ (D, C, L, AD, E, Q)
+//-
+//- A positive edge D-type flip-flop with negative polarity async load and positive
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 0 a  - | a
+//-                 d / - -  1 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_PNP_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(posedge C or negedge L) begin
+       if (L == 0)
+               Q <= AD;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_PPN_ (D, C, L, AD, E, Q)
+//-
+//- A positive edge D-type flip-flop with positive polarity async load and negative
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 1 a  - | a
+//-                 d / - -  0 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_PPN_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(posedge C or posedge L) begin
+       if (L == 1)
+               Q <= AD;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+//  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//-     $_ALDFFE_PPP_ (D, C, L, AD, E, Q)
+//-
+//- A positive edge D-type flip-flop with positive polarity async load and positive
+//- polarity clock enable.
+//-
+//- Truth table:    D C L AD E | Q
+//-                ------------+---
+//-                 - - 1 a  - | a
+//-                 d / - -  1 | d
+//-                 - - - -  - | q
+//-
+module \$_ALDFFE_PPP_ (D, C, L, AD, E, Q);
+input D, C, L, AD, E;
+output reg Q;
+always @(posedge C or posedge L) begin
+       if (L == 1)
+               Q <= AD;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
 //  |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 //-
 //-     $_DFFSR_NNN_ (C, S, R, D, Q)
index cf0839ebef72a081b0e999f2a5066730797e072a..e9129f690118e70be0e7dbf6e46f46c0c30b8b0d 100644 (file)
@@ -1890,6 +1890,30 @@ endmodule
 
 // --------------------------------------------------------
 
+module \$aldff (CLK, ALOAD, AD, D, Q);
+
+parameter WIDTH = 0;
+parameter CLK_POLARITY = 1'b1;
+parameter ALOAD_POLARITY = 1'b1;
+
+input CLK, ALOAD;
+input [WIDTH-1:0] AD;
+input [WIDTH-1:0] D;
+output reg [WIDTH-1:0] Q;
+wire pos_clk = CLK == CLK_POLARITY;
+wire pos_aload = ALOAD == ALOAD_POLARITY;
+
+always @(posedge pos_clk, posedge pos_aload) begin
+       if (pos_aload)
+               Q <= AD;
+       else
+               Q <= D;
+end
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$sdff (CLK, SRST, D, Q);
 
 parameter WIDTH = 0;
@@ -1939,6 +1963,31 @@ endmodule
 
 // --------------------------------------------------------
 
+module \$aldffe (CLK, ALOAD, AD, EN, D, Q);
+
+parameter WIDTH = 0;
+parameter CLK_POLARITY = 1'b1;
+parameter EN_POLARITY = 1'b1;
+parameter ALOAD_POLARITY = 1'b1;
+
+input CLK, ALOAD, EN;
+input [WIDTH-1:0] D;
+input [WIDTH-1:0] AD;
+output reg [WIDTH-1:0] Q;
+wire pos_clk = CLK == CLK_POLARITY;
+wire pos_aload = ALOAD == ALOAD_POLARITY;
+
+always @(posedge pos_clk, posedge pos_aload) begin
+       if (pos_aload)
+               Q <= AD;
+       else if (EN == EN_POLARITY)
+               Q <= D;
+end
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$sdffe (CLK, SRST, EN, D, Q);
 
 parameter WIDTH = 0;