Added support for dlatchsr cells
authorClifford Wolf <clifford@clifford.at>
Mon, 31 Mar 2014 12:14:40 +0000 (14:14 +0200)
committerClifford Wolf <clifford@clifford.at>
Mon, 31 Mar 2014 12:14:40 +0000 (14:14 +0200)
kernel/celltypes.h
kernel/rtlil.cc
kernel/rtlil.h
techlibs/common/simcells.v
techlibs/common/simlib.v

index 4a600af9d1c8c3595e86af337d833936a1450d8e..769145838367af8ac283309af21d3b4301057579 100644 (file)
@@ -108,6 +108,7 @@ struct CellTypes
                cell_types.insert("$dffsr");
                cell_types.insert("$adff");
                cell_types.insert("$dlatch");
+               cell_types.insert("$dlatchsr");
                cell_types.insert("$memrd");
                cell_types.insert("$memwr");
                cell_types.insert("$mem");
@@ -149,6 +150,14 @@ struct CellTypes
                cell_types.insert("$_DFFSR_PPP_");
                cell_types.insert("$_DLATCH_N_");
                cell_types.insert("$_DLATCH_P_");
+               cell_types.insert("$_DLATCHSR_NNN_");
+               cell_types.insert("$_DLATCHSR_NNP_");
+               cell_types.insert("$_DLATCHSR_NPN_");
+               cell_types.insert("$_DLATCHSR_NPP_");
+               cell_types.insert("$_DLATCHSR_PNN_");
+               cell_types.insert("$_DLATCHSR_PNP_");
+               cell_types.insert("$_DLATCHSR_PPN_");
+               cell_types.insert("$_DLATCHSR_PPP_");
        }
 
        void clear()
index 1d53bc79ba20f97c552e77551bec9bf39bd0943c..1168102a3d88f91aebb1054b0bba682238bdf23a 100644 (file)
@@ -569,6 +569,19 @@ namespace {
                                return;
                        }
 
+                       if (cell->type == "$dlatchsr") {
+                               param_bool("\\EN_POLARITY");
+                               param_bool("\\SET_POLARITY");
+                               param_bool("\\CLR_POLARITY");
+                               port("\\EN", 1);
+                               port("\\SET", param("\\WIDTH"));
+                               port("\\CLR", param("\\WIDTH"));
+                               port("\\D", param("\\WIDTH"));
+                               port("\\Q", param("\\WIDTH"));
+                               check_expected();
+                               return;
+                       }
+
                        if (cell->type == "$fsm") {
                                param("\\NAME");
                                param_bool("\\CLK_POLARITY");
@@ -675,6 +688,15 @@ namespace {
                        if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; }
                        if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; }
 
+                       if (cell->type == "$_DLATCHSR_NNN_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_NNP_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_NPN_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_NPP_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_PNN_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_PNP_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_PPN_") { check_gate("ESRDQ"); return; }
+                       if (cell->type == "$_DLATCHSR_PPP_") { check_gate("ESRDQ"); return; }
+
                        error(__LINE__);
                }
        };
@@ -1113,7 +1135,7 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e
 {
        RTLIL::Cell *cell = new RTLIL::Cell;
        cell->name = name;
-       cell->type = "$dffsr";
+       cell->type = "$dlatch";
        cell->parameters["\\EN_POLARITY"] = en_polarity;
        cell->parameters["\\WIDTH"] = sig_q.width;
        cell->connections["\\EN"] = sig_en;
@@ -1123,6 +1145,25 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e
        return cell;
 }
 
+RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
+               RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity)
+{
+       RTLIL::Cell *cell = new RTLIL::Cell;
+       cell->name = name;
+       cell->type = "$dlatchsr";
+       cell->parameters["\\EN_POLARITY"] = en_polarity;
+       cell->parameters["\\SET_POLARITY"] = set_polarity;
+       cell->parameters["\\CLR_POLARITY"] = clr_polarity;
+       cell->parameters["\\WIDTH"] = sig_q.width;
+       cell->connections["\\EN"] = sig_en;
+       cell->connections["\\SET"] = sig_set;
+       cell->connections["\\CLR"] = sig_clr;
+       cell->connections["\\D"] = sig_d;
+       cell->connections["\\Q"] = sig_q;
+       add(cell);
+       return cell;
+}
+
 RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
 {
        RTLIL::Cell *cell = new RTLIL::Cell;
@@ -1176,6 +1217,22 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec s
        return cell;
 }
 
+RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
+               RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity)
+{
+       RTLIL::Cell *cell = new RTLIL::Cell;
+       cell->name = name;
+       cell->type = stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N');
+       cell->connections["\\E"] = sig_en;
+       cell->connections["\\S"] = sig_set;
+       cell->connections["\\R"] = sig_clr;
+       cell->connections["\\D"] = sig_d;
+       cell->connections["\\Q"] = sig_q;
+       add(cell);
+       return cell;
+}
+
+
 RTLIL::Wire::Wire()
 {
        width = 1;
index 44142bf2968b3e8ac5421a2510bd13e480241fbf..b95a044225c8dba88d89af0304267cc5dbde6794 100644 (file)
@@ -351,6 +351,8 @@ struct RTLIL::Module {
        RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
                        RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true);
        RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true);
+       RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
+                       RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true);
 
        RTLIL::Cell* addInvGate  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y);
        RTLIL::Cell* addAndGate  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y);
@@ -364,6 +366,8 @@ struct RTLIL::Module {
        RTLIL::Cell* addAdffGate   (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
                        bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true);
        RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true);
+       RTLIL::Cell* addDlatchsrGate  (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
+                       RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true);
 };
 
 struct RTLIL::Wire {
index 10a809db6706b3e77fab6788e0491432e9625348..5ecec7891708ff447e20eb790489f23317da00b5 100644 (file)
@@ -325,3 +325,107 @@ always @* begin
 end
 endmodule
 
+module  \$_DLATCHSR_NNN_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 0)
+               Q <= 0;
+       else if (S == 0)
+               Q <= 1;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_NNP_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 1)
+               Q <= 0;
+       else if (S == 0)
+               Q <= 1;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_NPN_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 0)
+               Q <= 0;
+       else if (S == 1)
+               Q <= 1;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_NPP_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 1)
+               Q <= 0;
+       else if (S == 1)
+               Q <= 1;
+       else if (E == 0)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_PNN_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 0)
+               Q <= 0;
+       else if (S == 0)
+               Q <= 1;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_PNP_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 1)
+               Q <= 0;
+       else if (S == 0)
+               Q <= 1;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_PPN_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 0)
+               Q <= 0;
+       else if (S == 1)
+               Q <= 1;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
+module  \$_DLATCHSR_PPP_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+       if (R == 1)
+               Q <= 0;
+       else if (S == 1)
+               Q <= 1;
+       else if (E == 1)
+               Q <= D;
+end
+endmodule
+
index 4436abfe73fc832376404167fe8293f41efd7b6a..908314f84c378b3fd41408c9263401776e70557b 100644 (file)
@@ -1097,6 +1097,38 @@ endmodule
 
 // --------------------------------------------------------
 
+module \$dlatchsr (EN, SET, CLR, D, Q);
+
+parameter WIDTH = 0;
+parameter EN_POLARITY = 1'b1;
+parameter SET_POLARITY = 1'b1;
+parameter CLR_POLARITY = 1'b1;
+
+input EN;
+input [WIDTH-1:0] SET, CLR, D;
+output reg [WIDTH-1:0] Q;
+
+wire pos_en = EN == EN_POLARITY;
+wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
+wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR;
+
+genvar i;
+generate
+       for (i = 0; i < WIDTH; i = i+1) begin:bit
+               always @*
+                       if (pos_clr[i])
+                               Q[i] <= 0;
+                       else if (pos_set[i])
+                               Q[i] <= 1;
+                       else if (pos_en)
+                               Q[i] <= D[i];
+       end
+endgenerate
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$fsm (CLK, ARST, CTRL_IN, CTRL_OUT);
 
 parameter NAME = "";