From d4a1b0af5b41d1360c74a73fb2ae92ee5f6c3bd0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 31 Mar 2014 14:14:40 +0200 Subject: [PATCH] Added support for dlatchsr cells --- kernel/celltypes.h | 9 ++++ kernel/rtlil.cc | 59 ++++++++++++++++++++- kernel/rtlil.h | 4 ++ techlibs/common/simcells.v | 104 +++++++++++++++++++++++++++++++++++++ techlibs/common/simlib.v | 32 ++++++++++++ 5 files changed, 207 insertions(+), 1 deletion(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 4a600af9d..769145838 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -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() diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1d53bc79b..1168102a3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -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; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 44142bf29..b95a04422 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -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 { diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 10a809db6..5ecec7891 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -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 + diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 4436abfe7..908314f84 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -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 = ""; -- 2.30.2