Add new builtin FF types

The new types include:

- FFs with async reset and enable (`$adffe`, `$_DFFE_[NP][NP][01][NP]_`)
- FFs with sync reset (`$sdff`, `$_SDFF_[NP][NP][01]_`)
- FFs with sync reset and enable, reset priority (`$sdffs`, `$_SDFFE_[NP][NP][01][NP]_`)
- FFs with sync reset and enable, enable priority (`$sdffce`, `$_SDFFCE_[NP][NP][01][NP]_`)
- FFs with async reset, set, and enable (`$dffsre`, `$_DFFSRE_[NP][NP][NP][NP]_`)
- latches with reset or set (`$adlatch`, `$_DLATCH_[NP][NP][01]_`)

The new FF types are not actually used anywhere yet (this is left
for future commits).
This commit is contained in:
Marcelina Kościelnicka 2020-04-08 21:42:50 +02:00
parent 8c4cb1885b
commit b0bee396a8
8 changed files with 2736 additions and 70 deletions

View File

@ -139,8 +139,14 @@ struct CellTypes
setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q}); setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q});
setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q}); setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q});
setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q}); setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q});
setup_type(ID($dffsre), {ID::CLK, ID::SET, ID::CLR, ID::D, ID::E}, {ID::Q});
setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {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::E}, {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::E}, {ID::Q});
setup_type(ID($sdffce), {ID::CLK, ID::SRST, ID::D, ID::E}, {ID::Q});
setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q}); setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q});
setup_type(ID($adlatch), {ID::EN, ID::D, ID::ARST}, {ID::Q});
setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q}); setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q});
} }
@ -208,14 +214,48 @@ struct CellTypes
for (auto c3 : list_01) for (auto c3 : list_01)
setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q}); setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
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 c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_np) for (auto c3 : list_np)
setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {ID::C, ID::S, ID::R, ID::D}, {ID::Q}); setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {ID::C, ID::S, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
for (auto c4 : list_np)
setup_type(stringf("$_DFFSRE_%c%c%c%c_", c1, c2, c3, c4), {ID::C, ID::S, ID::R, ID::D, ID::E}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(stringf("$_SDFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(stringf("$_SDFFE_%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)
for (auto c3 : list_01)
for (auto c4 : list_np)
setup_type(stringf("$_SDFFCE_%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 c1 : list_np)
setup_type(stringf("$_DLATCH_%c_", c1), {ID::E, ID::D}, {ID::Q}); setup_type(stringf("$_DLATCH_%c_", c1), {ID::E, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
setup_type(stringf("$_DLATCH_%c%c%c_", c1, c2, c3), {ID::E, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np) for (auto c1 : list_np)
for (auto c2 : list_np) for (auto c2 : list_np)
for (auto c3 : list_np) for (auto c3 : list_np)

View File

@ -158,6 +158,9 @@ X(SRC_EN)
X(SRC_PEN) X(SRC_PEN)
X(SRC_POL) X(SRC_POL)
X(SRC_WIDTH) X(SRC_WIDTH)
X(SRST)
X(SRST_POLARITY)
X(SRST_VALUE)
X(STATE_BITS) X(STATE_BITS)
X(STATE_NUM) X(STATE_NUM)
X(STATE_NUM_LOG2) X(STATE_NUM_LOG2)

View File

@ -54,8 +54,14 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
ID($dff), ID($dff),
ID($dffe), ID($dffe),
ID($dffsr), ID($dffsr),
ID($dffsre),
ID($adff), ID($adff),
ID($adffe),
ID($sdff),
ID($sdffe),
ID($sdffce),
ID($dlatch), ID($dlatch),
ID($adlatch),
ID($dlatchsr), ID($dlatchsr),
ID($_DFFE_NN_), ID($_DFFE_NN_),
ID($_DFFE_NP_), ID($_DFFE_NP_),
@ -69,16 +75,102 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
ID($_DFFSR_PNP_), ID($_DFFSR_PNP_),
ID($_DFFSR_PPN_), ID($_DFFSR_PPN_),
ID($_DFFSR_PPP_), ID($_DFFSR_PPP_),
ID($_DFFSRE_NNNN_),
ID($_DFFSRE_NNNP_),
ID($_DFFSRE_NNPN_),
ID($_DFFSRE_NNPP_),
ID($_DFFSRE_NPNN_),
ID($_DFFSRE_NPNP_),
ID($_DFFSRE_NPPN_),
ID($_DFFSRE_NPPP_),
ID($_DFFSRE_PNNN_),
ID($_DFFSRE_PNNP_),
ID($_DFFSRE_PNPN_),
ID($_DFFSRE_PNPP_),
ID($_DFFSRE_PPNN_),
ID($_DFFSRE_PPNP_),
ID($_DFFSRE_PPPN_),
ID($_DFFSRE_PPPP_),
ID($_DFF_N_),
ID($_DFF_P_),
ID($_DFF_NN0_), ID($_DFF_NN0_),
ID($_DFF_NN1_), ID($_DFF_NN1_),
ID($_DFF_NP0_), ID($_DFF_NP0_),
ID($_DFF_NP1_), ID($_DFF_NP1_),
ID($_DFF_N_),
ID($_DFF_PN0_), ID($_DFF_PN0_),
ID($_DFF_PN1_), ID($_DFF_PN1_),
ID($_DFF_PP0_), ID($_DFF_PP0_),
ID($_DFF_PP1_), ID($_DFF_PP1_),
ID($_DFF_P_), ID($_DFFE_NN0N_),
ID($_DFFE_NN0P_),
ID($_DFFE_NN1N_),
ID($_DFFE_NN1P_),
ID($_DFFE_NP0N_),
ID($_DFFE_NP0P_),
ID($_DFFE_NP1N_),
ID($_DFFE_NP1P_),
ID($_DFFE_PN0N_),
ID($_DFFE_PN0P_),
ID($_DFFE_PN1N_),
ID($_DFFE_PN1P_),
ID($_DFFE_PP0N_),
ID($_DFFE_PP0P_),
ID($_DFFE_PP1N_),
ID($_DFFE_PP1P_),
ID($_SDFF_NN0_),
ID($_SDFF_NN1_),
ID($_SDFF_NP0_),
ID($_SDFF_NP1_),
ID($_SDFF_PN0_),
ID($_SDFF_PN1_),
ID($_SDFF_PP0_),
ID($_SDFF_PP1_),
ID($_SDFFE_NN0N_),
ID($_SDFFE_NN0P_),
ID($_SDFFE_NN1N_),
ID($_SDFFE_NN1P_),
ID($_SDFFE_NP0N_),
ID($_SDFFE_NP0P_),
ID($_SDFFE_NP1N_),
ID($_SDFFE_NP1P_),
ID($_SDFFE_PN0N_),
ID($_SDFFE_PN0P_),
ID($_SDFFE_PN1N_),
ID($_SDFFE_PN1P_),
ID($_SDFFE_PP0N_),
ID($_SDFFE_PP0P_),
ID($_SDFFE_PP1N_),
ID($_SDFFE_PP1P_),
ID($_SDFFCE_NN0N_),
ID($_SDFFCE_NN0P_),
ID($_SDFFCE_NN1N_),
ID($_SDFFCE_NN1P_),
ID($_SDFFCE_NP0N_),
ID($_SDFFCE_NP0P_),
ID($_SDFFCE_NP1N_),
ID($_SDFFCE_NP1P_),
ID($_SDFFCE_PN0N_),
ID($_SDFFCE_PN0P_),
ID($_SDFFCE_PN1N_),
ID($_SDFFCE_PN1P_),
ID($_SDFFCE_PP0N_),
ID($_SDFFCE_PP0P_),
ID($_SDFFCE_PP1N_),
ID($_SDFFCE_PP1P_),
ID($_SR_NN_),
ID($_SR_NP_),
ID($_SR_PN_),
ID($_SR_PP_),
ID($_DLATCH_N_),
ID($_DLATCH_P_),
ID($_DLATCH_NN0_),
ID($_DLATCH_NN1_),
ID($_DLATCH_NP0_),
ID($_DLATCH_NP1_),
ID($_DLATCH_PN0_),
ID($_DLATCH_PN1_),
ID($_DLATCH_PP0_),
ID($_DLATCH_PP1_),
ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNN_),
ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NNP_),
ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPN_),
@ -87,8 +179,6 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PNP_),
ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPN_),
ID($_DLATCHSR_PPP_), ID($_DLATCHSR_PPP_),
ID($_DLATCH_N_),
ID($_DLATCH_P_),
ID($_FF_), ID($_FF_),
}; };
return res; return res;
@ -1139,6 +1229,21 @@ namespace {
return; return;
} }
if (cell->type == ID($dffsre)) {
param_bool(ID::CLK_POLARITY);
param_bool(ID::SET_POLARITY);
param_bool(ID::CLR_POLARITY);
param_bool(ID::EN_POLARITY);
port(ID::CLK, 1);
port(ID::EN, 1);
port(ID::SET, param(ID::WIDTH));
port(ID::CLR, param(ID::WIDTH));
port(ID::D, param(ID::WIDTH));
port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($adff)) { if (cell->type == ID($adff)) {
param_bool(ID::CLK_POLARITY); param_bool(ID::CLK_POLARITY);
param_bool(ID::ARST_POLARITY); param_bool(ID::ARST_POLARITY);
@ -1151,6 +1256,46 @@ namespace {
return; return;
} }
if (cell->type == ID($sdff)) {
param_bool(ID::CLK_POLARITY);
param_bool(ID::SRST_POLARITY);
param_bits(ID::SRST_VALUE, param(ID::WIDTH));
port(ID::CLK, 1);
port(ID::SRST, 1);
port(ID::D, param(ID::WIDTH));
port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type.in(ID($sdffe), ID($sdffce))) {
param_bool(ID::CLK_POLARITY);
param_bool(ID::EN_POLARITY);
param_bool(ID::SRST_POLARITY);
param_bits(ID::SRST_VALUE, param(ID::WIDTH));
port(ID::CLK, 1);
port(ID::EN, 1);
port(ID::SRST, 1);
port(ID::D, param(ID::WIDTH));
port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($adffe)) {
param_bool(ID::CLK_POLARITY);
param_bool(ID::EN_POLARITY);
param_bool(ID::ARST_POLARITY);
param_bits(ID::ARST_VALUE, param(ID::WIDTH));
port(ID::CLK, 1);
port(ID::EN, 1);
port(ID::ARST, 1);
port(ID::D, param(ID::WIDTH));
port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dlatch)) { if (cell->type == ID($dlatch)) {
param_bool(ID::EN_POLARITY); param_bool(ID::EN_POLARITY);
port(ID::EN, 1); port(ID::EN, 1);
@ -1160,6 +1305,18 @@ namespace {
return; return;
} }
if (cell->type == ID($adlatch)) {
param_bool(ID::EN_POLARITY);
param_bool(ID::ARST_POLARITY);
param_bits(ID::ARST_VALUE, param(ID::WIDTH));
port(ID::EN, 1);
port(ID::ARST, 1);
port(ID::D, param(ID::WIDTH));
port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dlatchsr)) { if (cell->type == ID($dlatchsr)) {
param_bool(ID::EN_POLARITY); param_bool(ID::EN_POLARITY);
param_bool(ID::SET_POLARITY); param_bool(ID::SET_POLARITY);
@ -1351,49 +1508,69 @@ namespace {
if (cell->type == ID($_MUX8_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::Y,1); check_expected(); return; } if (cell->type == ID($_MUX8_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::Y,1); check_expected(); return; }
if (cell->type == ID($_MUX16_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::I,1); port(ID::J,1); port(ID::K,1); port(ID::L,1); port(ID::M,1); port(ID::N,1); port(ID::O,1); port(ID::P,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::V,1); port(ID::Y,1); check_expected(); return; } if (cell->type == ID($_MUX16_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::I,1); port(ID::J,1); port(ID::K,1); port(ID::L,1); port(ID::M,1); port(ID::N,1); port(ID::O,1); port(ID::P,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::V,1); port(ID::Y,1); check_expected(); return; }
if (cell->type == ID($_SR_NN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } if (cell->type.in(ID($_SR_NN_), ID($_SR_NP_), ID($_SR_PN_), ID($_SR_PP_)))
if (cell->type == ID($_SR_NP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; } { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_SR_PN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_SR_PP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; } if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DFF_N_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; }
if (cell->type == ID($_DFF_P_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; }
if (cell->type == ID($_DFFE_NN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
if (cell->type == ID($_DFFE_NP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; } { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; }
if (cell->type == ID($_DFFE_PN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
if (cell->type == ID($_DFFE_PP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
if (cell->type == ID($_DFF_NN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
if (cell->type == ID($_DFF_NN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; } { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
if (cell->type == ID($_DFF_NP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFF_NP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFF_PN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFF_PN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFF_PP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFF_PP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFFSR_NNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } if (cell->type.in(
if (cell->type == ID($_DFFSR_NNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
if (cell->type == ID($_DFFSR_NPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)))
if (cell->type == ID($_DFFSR_NPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type == ID($_DFFSR_PNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DFFSR_PNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DFFSR_PPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DFFSR_PPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DLATCH_N_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } if (cell->type.in(
if (cell->type == ID($_DLATCH_P_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFFE_NN0N_), ID($_DFFE_NN0P_), ID($_DFFE_NN1N_), ID($_DFFE_NN1P_),
ID($_DFFE_NP0N_), ID($_DFFE_NP0P_), ID($_DFFE_NP1N_), ID($_DFFE_NP1P_),
ID($_DFFE_PN0N_), ID($_DFFE_PN0P_), ID($_DFFE_PN1N_), ID($_DFFE_PN1P_),
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 == ID($_DLATCHSR_NNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } if (cell->type.in(
if (cell->type == ID($_DLATCHSR_NNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
if (cell->type == ID($_DLATCHSR_NPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
if (cell->type == ID($_DLATCHSR_NPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DLATCHSR_PNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type == ID($_DLATCHSR_PNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } if (cell->type.in(
if (cell->type == ID($_DLATCHSR_PPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFFSRE_NNNN_), ID($_DFFSRE_NNNP_), ID($_DFFSRE_NNPN_), ID($_DFFSRE_NNPP_),
if (cell->type == ID($_DLATCHSR_PPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } ID($_DFFSRE_NPNN_), ID($_DFFSRE_NPNP_), ID($_DFFSRE_NPPN_), ID($_DFFSRE_NPPP_),
ID($_DFFSRE_PNNN_), ID($_DFFSRE_PNNP_), ID($_DFFSRE_PNPN_), ID($_DFFSRE_PNPP_),
ID($_DFFSRE_PPNN_), ID($_DFFSRE_PPNP_), ID($_DFFSRE_PPPN_), ID($_DFFSRE_PPPP_)))
{ port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::E,1); port(ID::Q,1); check_expected(); return; }
if (cell->type.in(
ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_),
ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_)))
{ port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
if (cell->type.in(
ID($_SDFFE_NN0N_), ID($_SDFFE_NN0P_), ID($_SDFFE_NN1N_), ID($_SDFFE_NN1P_),
ID($_SDFFE_NP0N_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1N_), ID($_SDFFE_NP1P_),
ID($_SDFFE_PN0N_), ID($_SDFFE_PN0P_), ID($_SDFFE_PN1N_), ID($_SDFFE_PN1P_),
ID($_SDFFE_PP0N_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1N_), ID($_SDFFE_PP1P_),
ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NN1P_),
ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1N_), ID($_SDFFCE_NP1P_),
ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PN1P_),
ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1N_), ID($_SDFFCE_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($_DLATCH_N_), ID($_DLATCH_P_)))
{ port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type.in(
ID($_DLATCH_NN0_), ID($_DLATCH_NN1_), ID($_DLATCH_NP0_), ID($_DLATCH_NP1_),
ID($_DLATCH_PN0_), ID($_DLATCH_PN1_), ID($_DLATCH_PP0_), ID($_DLATCH_PP1_)))
{ port(ID::E,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
if (cell->type.in(
ID($_DLATCHSR_NNN_), ID($_DLATCHSR_NNP_), ID($_DLATCHSR_NPN_), ID($_DLATCHSR_NPP_),
ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_)))
{ port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
error(__LINE__); error(__LINE__);
} }

View File

@ -234,16 +234,6 @@ Clock is active on the positive edge if this parameter has the value {\tt 1'b1}
edge if this parameter is {\tt 1'b0}. edge if this parameter is {\tt 1'b0}.
\end{itemize} \end{itemize}
D-type flip-flops with enable are represented by {\tt \$dffe} 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{EN}
input port for the enable pin and the following parameter:
\begin{itemize}
\item \B{EN\_POLARITY} \\
The enable input 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 reset are represented by {\tt \$adff} cells. As the {\tt \$dff} D-type flip-flops with asynchronous reset are represented by {\tt \$adff} 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{ARST} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have a single-bit \B{ARST}
input port for the reset pin and the following additional two parameters: input port for the reset pin and the following additional two parameters:
@ -257,13 +247,26 @@ if this parameter is {\tt 1'b0}.
The state of \B{Q} will be set to this value when the reset is active. The state of \B{Q} will be set to this value when the reset is active.
\end{itemize} \end{itemize}
Note that the {\tt \$adff} cell can only be used when the reset value is constant.
\begin{sloppypar} \begin{sloppypar}
Usually these cells are generated by the {\tt proc} pass using the information Usually these cells are generated by the {\tt proc} pass using the information
in the designs RTLIL::Process objects. in the designs RTLIL::Process objects.
\end{sloppypar} \end{sloppypar}
D-type flip-flops with synchronous reset are represented by {\tt \$sdff} 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{SRST}
input port for the reset pin and the following additional two parameters:
\begin{itemize}
\item \B{SRST\_POLARITY} \\
The synchronous reset is active-high if this parameter has the value {\tt 1'b1} and active-low
if this parameter is {\tt 1'b0}.
\item \B{SRST\_VALUE} \\
The state of \B{Q} will be set to this value when the reset is active.
\end{itemize}
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 set and reset are represented by {\tt \$dffsr} cells. 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 As the {\tt \$dff} cells they have \B{CLK}, \B{D} and \B{Q} ports. In addition they also have
a single-bit \B{SET} input port for the set pin, a single-bit \B{CLR} input port for the reset pin, a single-bit \B{SET} input port for the set pin, a single-bit \B{CLR} input port for the reset pin,
@ -282,9 +285,21 @@ if this parameter is {\tt 1'b0}.
When both the set and reset inputs of a {\tt \$dffsr} cell are active, the reset input takes When both the set and reset inputs of a {\tt \$dffsr} cell are active, the reset input takes
precedence. precedence.
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},
{\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:
\begin{itemize}
\item \B{EN\_POLARITY} \\
The enable input is active-high if this parameter has the value {\tt 1'b1} and active-low
if this parameter is {\tt 1'b0}.
\end{itemize}
\begin{fixme} \begin{fixme}
Add information about {\tt \$sr} cells (set-reset flip-flops), {\tt \$dlatch} cells (d-type latches), Add information about {\tt \$sr} cells (set-reset flip-flops), {\tt \$dlatch} cells (d-type latches),
and {\tt \$dlatchsr} cells (d-type latches with set/reset). {\tt \$adlatch} and {\tt \$dlatchsr} cells (d-type latches with set/reset).
\end{fixme} \end{fixme}
\subsection{Memories} \subsection{Memories}
@ -490,20 +505,29 @@ Verilog & Cell Type \\
\lstinline[language=Verilog]; always @(negedge C) Q <= D; & {\tt \$\_DFF\_N\_} \\ \lstinline[language=Verilog]; always @(negedge C) Q <= D; & {\tt \$\_DFF\_N\_} \\
\lstinline[language=Verilog]; always @(posedge C) Q <= D; & {\tt \$\_DFF\_P\_} \\ \lstinline[language=Verilog]; always @(posedge C) Q <= D; & {\tt \$\_DFF\_P\_} \\
\end{tabular} \end{tabular}
\caption{Cell types for gate level logic networks (main list)}
\label{tab:CellLib_gates}
\end{table}
\begin{table}[t]
\hfil \hfil
\begin{tabular}[t]{llll} \begin{tabular}[t]{llll}
$ClkEdge$ & $RstLvl$ & $RstVal$ & Cell Type \\ $ClkEdge$ & $RstLvl$ & $RstVal$ & Cell Type \\
\hline \hline
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NN0\_} \\ \lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NN0\_}, {\tt \$\_SDFF\_NN0\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NN1\_} \\ \lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NN1\_}, {\tt \$\_SDFF\_NN1\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NP0\_} \\ \lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_NP0\_}, {\tt \$\_SDFF\_NP0\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NP1\_} \\ \lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_NP1\_}, {\tt \$\_SDFF\_NP1\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PN0\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PN0\_}, {\tt \$\_SDFF\_PN0\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PN1\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PN1\_}, {\tt \$\_SDFF\_PN1\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PP0\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFF\_PP0\_}, {\tt \$\_SDFF\_PP0\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PP1\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFF\_PP1\_}, {\tt \$\_SDFF\_PP1\_} \\
\end{tabular} \end{tabular}
% FIXME: the layout of this is broken and I have no idea how to fix it \caption{Cell types for gate level logic networks (FFs with reset)}
\label{tab:CellLib_gates_adff}
\end{table}
\begin{table}[t]
\hfil \hfil
\begin{tabular}[t]{lll} \begin{tabular}[t]{lll}
$ClkEdge$ & $EnLvl$ & Cell Type \\ $ClkEdge$ & $EnLvl$ & Cell Type \\
@ -513,7 +537,36 @@ $ClkEdge$ & $EnLvl$ & Cell Type \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP\_} \\
\end{tabular} \end{tabular}
% FIXME: the layout of this is broken too \caption{Cell types for gate level logic networks (FFs with enable)}
\label{tab:CellLib_gates_dffe}
\end{table}
\begin{table}[t]
\begin{tabular}[t]{lllll}
$ClkEdge$ & $RstLvl$ & $RstVal$ & $EnLvl$ & Cell Type \\
\hline
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NN0N\_}, {\tt \$\_SDFFE\_NN0N\_}, {\tt \$\_SDFFCE\_NN0N\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NN0P\_}, {\tt \$\_SDFFE\_NN0P\_}, {\tt \$\_SDFFCE\_NN0P\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NN1N\_}, {\tt \$\_SDFFE\_NN1N\_}, {\tt \$\_SDFFCE\_NN1N\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NN1P\_}, {\tt \$\_SDFFE\_NN1P\_}, {\tt \$\_SDFFCE\_NN1P\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NP0N\_}, {\tt \$\_SDFFE\_NP0N\_}, {\tt \$\_SDFFCE\_NP0N\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NP0P\_}, {\tt \$\_SDFFE\_NP0P\_}, {\tt \$\_SDFFCE\_NP0P\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_NP1N\_}, {\tt \$\_SDFFE\_NP1N\_}, {\tt \$\_SDFFCE\_NP1N\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_NP1P\_}, {\tt \$\_SDFFE\_NP1P\_}, {\tt \$\_SDFFCE\_NP1P\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN0N\_}, {\tt \$\_SDFFE\_PN0N\_}, {\tt \$\_SDFFCE\_PN0N\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PN0P\_}, {\tt \$\_SDFFE\_PN0P\_}, {\tt \$\_SDFFCE\_PN0P\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PN1N\_}, {\tt \$\_SDFFE\_PN1N\_}, {\tt \$\_SDFFCE\_PN1N\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PN1P\_}, {\tt \$\_SDFFE\_PN1P\_}, {\tt \$\_SDFFCE\_PN1P\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PP0N\_}, {\tt \$\_SDFFE\_PP0N\_}, {\tt \$\_SDFFCE\_PP0N\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP0P\_}, {\tt \$\_SDFFE\_PP0P\_}, {\tt \$\_SDFFCE\_PP0P\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFE\_PP1N\_}, {\tt \$\_SDFFE\_PP1N\_}, {\tt \$\_SDFFCE\_PP1N\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFE\_PP1P\_}, {\tt \$\_SDFFE\_PP1P\_}, {\tt \$\_SDFFCE\_PP1P\_} \\
\end{tabular}
\caption{Cell types for gate level logic networks (FFs with reset and enable)}
\label{tab:CellLib_gates_adffe}
\end{table}
\begin{table}[t]
\hfil \hfil
\begin{tabular}[t]{llll} \begin{tabular}[t]{llll}
$ClkEdge$ & $SetLvl$ & $RstLvl$ & Cell Type \\ $ClkEdge$ & $SetLvl$ & $RstLvl$ & Cell Type \\
@ -527,11 +580,37 @@ $ClkEdge$ & $SetLvl$ & $RstLvl$ & Cell Type \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_PPN\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSR\_PPN\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_PPP\_} \\ \lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSR\_PPP\_} \\
\end{tabular} \end{tabular}
\caption{Cell types for gate level logic networks} \caption{Cell types for gate level logic networks (FFs with set and reset)}
\label{tab:CellLib_gates} \label{tab:CellLib_gates_dffsr}
\end{table} \end{table}
Table~\ref{tab:CellLib_gates} lists all cell types used for gate level logic. The cell types \begin{table}[t]
\hfil
\begin{tabular}[t]{lllll}
$ClkEdge$ & $SetLvl$ & $RstLvl$ & $EnLvl$ & Cell Type \\
\hline
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NNNN\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NNNP\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NNPN\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NNPP\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NPNN\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NPNP\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_NPPN\_} \\
\lstinline[language=Verilog];negedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_NPPP\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PNNN\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PNNP\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PNPN\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PNPP\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PPNN\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PPNP\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];0; & {\tt \$\_DFFSRE\_PPPN\_} \\
\lstinline[language=Verilog];posedge; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & \lstinline[language=Verilog];1; & {\tt \$\_DFFSRE\_PPPP\_} \\
\end{tabular}
\caption{Cell types for gate level logic networks (FFs with set and reset and enable)}
\label{tab:CellLib_gates_dffsre}
\end{table}
Tables~\ref{tab:CellLib_gates}, \ref{tab:CellLib_gates_dffe}, \ref{tab:CellLib_gates_adff}, \ref{tab:CellLib_gates_adffe}, \ref{tab:CellLib_gates_dffsr} and \ref{tab:CellLib_gates_dffsre} list all cell types used for gate level logic. The cell types
{\tt \$\_NOT\_}, {\tt \$\_AND\_}, {\tt \$\_NAND\_}, {\tt \$\_ANDNOT\_}, {\tt \$\_OR\_}, {\tt \$\_NOR\_}, {\tt \$\_NOT\_}, {\tt \$\_AND\_}, {\tt \$\_NAND\_}, {\tt \$\_ANDNOT\_}, {\tt \$\_OR\_}, {\tt \$\_NOR\_},
{\tt \$\_ORNOT\_}, {\tt \$\_XOR\_}, {\tt \$\_XNOR\_} and {\tt \$\_MUX\_} are used to model combinatorial logic. {\tt \$\_ORNOT\_}, {\tt \$\_XOR\_}, {\tt \$\_XNOR\_} and {\tt \$\_MUX\_} are used to model combinatorial logic.
The cell type {\tt \$\_TBUF\_} is used to model tristate logic. The cell type {\tt \$\_TBUF\_} is used to model tristate logic.
@ -563,8 +642,61 @@ otherwise.
Q <= D; Q <= D;
\end{lstlisting} \end{lstlisting}
The cell types {\tt \$\_DFFSR\_NNN\_}, {\tt \$\_DFFSR\_NNP\_}, {\tt \$\_DFFSR\_NPN\_}, {\tt \$\_DFFSR\_NPP\_}, The cell types {\tt \$\_SDFF\_NN0\_}, {\tt \$\_SDFF\_NN1\_}, {\tt \$\_SDFF\_NP0\_}, {\tt \$\_SDFF\_NP1\_},
{\tt \$\_DFFSR\_PNN\_}, {\tt \$\_DFFSR\_PNP\_}, {\tt \$\_DFFSR\_PPN\_} and {\tt \$\_DFFSR\_PPP\_} implement {\tt \$\_SDFF\_PN0\_}, {\tt \$\_SDFF\_PN1\_}, {\tt \$\_SDFF\_PP0\_} and {\tt \$\_SDFF\_PP1\_} implement
d-type flip-flops with synchronous reset. The values in the table for these cell types relate to the
following Verilog code template:
\begin{lstlisting}[mathescape,language=Verilog]
always @($ClkEdge$ C)
if (R == $RstLvl$)
Q <= $RstVal$;
else
Q <= D;
\end{lstlisting}
The cell types {\tt \$\_DFFE\_[NP][NP][01][NP]\_} implement
d-type flip-flops with asynchronous reset and enable. The values in the table for these cell types relate to the
following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge;
if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, and \lstinline[language=Verilog];negedge;
otherwise.
\begin{lstlisting}[mathescape,language=Verilog]
always @($ClkEdge$ C, $RstEdge$ R)
if (R == $RstLvl$)
Q <= $RstVal$;
else if (EN == $EnLvl$)
Q <= D;
\end{lstlisting}
The cell types {\tt \$\_SDFFE\_[NP][NP][01][NP]\_} implement d-type flip-flops
with synchronous reset and enable, with reset having priority over enable.
The values in the table for these cell types relate to the
following Verilog code template:
\begin{lstlisting}[mathescape,language=Verilog]
always @($ClkEdge$ C)
if (R == $RstLvl$)
Q <= $RstVal$;
else if (EN == $EnLvl$)
Q <= D;
\end{lstlisting}
The cell types {\tt \$\_SDFFCE\_[NP][NP][01][NP]\_} implement d-type flip-flops
with synchronous reset and enable, with enable having priority over reset.
The values in the table for these cell types relate to the
following Verilog code template:
\begin{lstlisting}[mathescape,language=Verilog]
always @($ClkEdge$ C)
if (EN == $EnLvl$)
if (R == $RstLvl$)
Q <= $RstVal$;
else
Q <= D;
\end{lstlisting}
The cell types {\tt \$\_DFFSR\_[NP][NP][NP]\_} implement
d-type flip-flops with asynchronous set and reset. The values in the table for these cell types relate to the d-type flip-flops with asynchronous set and reset. The values in the table for these cell types relate to the
following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge; following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge;
if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge; if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge;
@ -582,6 +714,24 @@ otherwise.
Q <= D; Q <= D;
\end{lstlisting} \end{lstlisting}
The cell types {\tt \$\_DFFSRE\_[NP][NP][NP][NP]\_} implement
d-type flip-flops with asynchronous set and reset and enable. The values in the table for these cell types relate to the
following Verilog code template, where \lstinline[mathescape,language=Verilog];$RstEdge$; is \lstinline[language=Verilog];posedge;
if \lstinline[mathescape,language=Verilog];$RstLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge;
otherwise, and \lstinline[mathescape,language=Verilog];$SetEdge$; is \lstinline[language=Verilog];posedge;
if \lstinline[mathescape,language=Verilog];$SetLvl$; if \lstinline[language=Verilog];1;, \lstinline[language=Verilog];negedge;
otherwise.
\begin{lstlisting}[mathescape,language=Verilog]
always @($ClkEdge$ C, $RstEdge$ R, $SetEdge$ S)
if (R == $RstLvl$)
Q <= 0;
else if (S == $SetLvl$)
Q <= 1;
else if (E == $EnLvl$)
Q <= D;
\end{lstlisting}
In most cases gate level logic networks are created from RTL networks using the {\tt techmap} pass. The flip-flop cells In most cases gate level logic networks are created from RTL networks using the {\tt techmap} pass. The flip-flop cells
from the gate level logic network can be mapped to physical flip-flop cells from a Liberty file using the {\tt dfflibmap} from the gate level logic network can be mapped to physical flip-flop cells from a Liberty file using the {\tt dfflibmap}
pass. The combinatorial logic cells can be mapped to physical cells from a Liberty file via ABC \citeweblink{ABC} pass. The combinatorial logic cells can be mapped to physical cells from a Liberty file via ABC \citeweblink{ABC}

View File

@ -117,7 +117,10 @@ struct statdata_t
} }
else if (cell_type.in(ID($mux), ID($pmux))) else if (cell_type.in(ID($mux), ID($pmux)))
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y))); cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y)));
else if (cell_type.in(ID($sr), ID($dff), ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr))) else if (cell_type.in(
ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre),
ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce),
ID($dlatch), ID($adlatch), ID($dlatchsr)))
cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q))); cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q)));
} }

View File

@ -108,6 +108,31 @@ endmodule
""" """
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//- //-
//- $_DFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity {V:reset|set} and {E:negative|positive}
//- polarity clock enable.
//-
//- Truth table: D C R E | Q
//- ---------+---
//- - - {R:0|1} - | {V:0|1}
//- d {C:\\|/} - {E:0|1} | d
//- - - - - | q
//-
module \$_DFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q);
input D, C, R, E;
output reg Q;
always @({C:neg|pos}edge C or {R:neg|pos}edge R) begin
if (R == {R:0|1})
Q <= {V:0|1};
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) //- $_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} //- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive}
@ -136,6 +161,110 @@ endmodule
""" """
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//- //-
//- $_DFFSRE_{C:N|P}{S:N|P}{R:N|P}{E:N|P}_ (C, S, R, E, D, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set, {R:negative|positive}
//- polarity reset and {E:negative|positive} polarity clock enable.
//-
//- Truth table: C S R E D | Q
//- -----------+---
//- - - {R:0|1} - - | 0
//- - {S:0|1} - - - | 1
//- {C:\\|/} - - {E:0|1} d | d
//- - - - - - | q
//-
module \$_DFFSRE_{C:N|P}{S:N|P}{R:N|P}{E:N|P}_ (C, S, R, E, D, Q);
input C, S, R, E, D;
output reg Q;
always @({C:neg|pos}edge C, {S:neg|pos}edge S, {R:neg|pos}edge R) begin
if (R == {R:0|1})
Q <= 0;
else if (S == {S:0|1})
Q <= 1;
else if (E == {E:0|1})
Q <= D;
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_SDFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set}.
//-
//- Truth table: D C R | Q
//- -------+---
//- - {C:\\|/} {R:0|1} | {V:0|1}
//- d {C:\\|/} - | d
//- - - - | q
//-
module \$_SDFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @({C:neg|pos}edge C) begin
if (R == {R:0|1})
Q <= {V:0|1};
else
Q <= D;
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_SDFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set} and {E:negative|positive}
//- polarity clock enable (with {V:reset|set} having priority).
//-
//- Truth table: D C R E | Q
//- ---------+---
//- - {C:\\|/} {R:0|1} - | {V:0|1}
//- d {C:\\|/} - {E:0|1} | d
//- - - - - | q
//-
module \$_SDFFE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q);
input D, C, R, E;
output reg Q;
always @({C:neg|pos}edge C) begin
if (R == {R:0|1})
Q <= {V:0|1};
else if (E == {E:0|1})
Q <= D;
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_SDFFCE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q)
//-
//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity synchronous {V:reset|set} and {E:negative|positive}
//- polarity clock enable (with clock enable having priority).
//-
//- Truth table: D C R E | Q
//- ---------+---
//- - {C:\\|/} {R:0|1} {E:0|1} | {V:0|1}
//- d {C:\\|/} - {E:0|1} | d
//- - - - - | q
//-
module \$_SDFFCE_{C:N|P}{R:N|P}{V:0|1}{E:N|P}_ (D, C, R, E, Q);
input D, C, R, E;
output reg Q;
always @({C:neg|pos}edge C) begin
if (E == {E:0|1}) begin
if (R == {R:0|1})
Q <= {V:0|1};
else
Q <= D;
end
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_DLATCH_{E:N|P}_ (E, D, Q) //- $_DLATCH_{E:N|P}_ (E, D, Q)
//- //-
//- A {E:negative|positive} enable D-type latch. //- A {E:negative|positive} enable D-type latch.
@ -157,6 +286,30 @@ endmodule
""" """
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//- //-
//- $_DLATCH_{E:N|P}{R:N|P}{V:0|1}_ (E, R, D, Q)
//-
//- A {E:negative|positive} enable D-type latch with {R:negative|positive} polarity {V:reset|set}.
//-
//- Truth table: E R D | Q
//- -------+---
//- - {R:0|1} - | {V:0|1}
//- {E:0|1} - d | d
//- - - - | q
//-
module \$_DLATCH_{E:N|P}{R:N|P}{V:0|1}_ (E, R, D, Q);
input E, R, D;
output reg Q;
always @* begin
if (R == {E:0|1})
Q <= {V:0|1};
else if (E == {E:0|1})
Q <= D;
end
endmodule
""",
"""
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q) //- $_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q)
//- //-
//- A {E:negative|positive} enable D-type latch with {S:negative|positive} polarity set and {R:negative|positive} //- A {E:negative|positive} enable D-type latch with {S:negative|positive} polarity set and {R:negative|positive}

File diff suppressed because it is too large Load Diff

View File

@ -1822,6 +1822,39 @@ endgenerate
endmodule endmodule
// --------------------------------------------------------
module \$dffsre (CLK, SET, CLR, EN, D, Q);
parameter WIDTH = 0;
parameter CLK_POLARITY = 1'b1;
parameter SET_POLARITY = 1'b1;
parameter CLR_POLARITY = 1'b1;
parameter EN_POLARITY = 1'b1;
input CLK, EN;
input [WIDTH-1:0] SET, CLR, D;
output reg [WIDTH-1:0] Q;
wire pos_clk = CLK == CLK_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:bitslices
always @(posedge pos_set[i], posedge pos_clr[i], posedge pos_clk)
if (pos_clr[i])
Q[i] <= 0;
else if (pos_set[i])
Q[i] <= 1;
else if (EN == EN_POLARITY)
Q[i] <= D[i];
end
endgenerate
endmodule
`endif `endif
// -------------------------------------------------------- // --------------------------------------------------------
@ -1849,6 +1882,107 @@ endmodule
// -------------------------------------------------------- // --------------------------------------------------------
module \$sdff (CLK, SRST, D, Q);
parameter WIDTH = 0;
parameter CLK_POLARITY = 1'b1;
parameter SRST_POLARITY = 1'b1;
parameter SRST_VALUE = 0;
input CLK, SRST;
input [WIDTH-1:0] D;
output reg [WIDTH-1:0] Q;
wire pos_clk = CLK == CLK_POLARITY;
wire pos_srst = SRST == SRST_POLARITY;
always @(posedge pos_clk) begin
if (pos_srst)
Q <= SRST_VALUE;
else
Q <= D;
end
endmodule
// --------------------------------------------------------
module \$adffe (CLK, ARST, EN, D, Q);
parameter WIDTH = 0;
parameter CLK_POLARITY = 1'b1;
parameter EN_POLARITY = 1'b1;
parameter ARST_POLARITY = 1'b1;
parameter ARST_VALUE = 0;
input CLK, ARST, EN;
input [WIDTH-1:0] D;
output reg [WIDTH-1:0] Q;
wire pos_clk = CLK == CLK_POLARITY;
wire pos_arst = ARST == ARST_POLARITY;
always @(posedge pos_clk, posedge pos_arst) begin
if (pos_arst)
Q <= ARST_VALUE;
else if (EN == EN_POLARITY)
Q <= D;
end
endmodule
// --------------------------------------------------------
module \$sdffe (CLK, SRST, EN, D, Q);
parameter WIDTH = 0;
parameter CLK_POLARITY = 1'b1;
parameter EN_POLARITY = 1'b1;
parameter SRST_POLARITY = 1'b1;
parameter SRST_VALUE = 0;
input CLK, SRST, EN;
input [WIDTH-1:0] D;
output reg [WIDTH-1:0] Q;
wire pos_clk = CLK == CLK_POLARITY;
wire pos_srst = SRST == SRST_POLARITY;
always @(posedge pos_clk) begin
if (pos_srst)
Q <= SRST_VALUE;
else if (EN == EN_POLARITY)
Q <= D;
end
endmodule
// --------------------------------------------------------
module \$sdffce (CLK, SRST, EN, D, Q);
parameter WIDTH = 0;
parameter CLK_POLARITY = 1'b1;
parameter EN_POLARITY = 1'b1;
parameter SRST_POLARITY = 1'b1;
parameter SRST_VALUE = 0;
input CLK, SRST, EN;
input [WIDTH-1:0] D;
output reg [WIDTH-1:0] Q;
wire pos_clk = CLK == CLK_POLARITY;
wire pos_srst = SRST == SRST_POLARITY;
always @(posedge pos_clk) begin
if (EN == EN_POLARITY) begin
if (pos_srst)
Q <= SRST_VALUE;
else
Q <= D;
end
end
endmodule
// --------------------------------------------------------
module \$dlatch (EN, D, Q); module \$dlatch (EN, D, Q);
parameter WIDTH = 0; parameter WIDTH = 0;
@ -1865,6 +1999,28 @@ end
endmodule endmodule
// --------------------------------------------------------
module \$adlatch (EN, ARST, D, Q);
parameter WIDTH = 0;
parameter EN_POLARITY = 1'b1;
parameter ARST_POLARITY = 1'b1;
parameter ARST_VALUE = 0;
input EN, ARST;
input [WIDTH-1:0] D;
output reg [WIDTH-1:0] Q;
always @* begin
if (ARST == ARST_POLARITY)
Q = ARST_VALUE;
else if (EN == EN_POLARITY)
Q = D;
end
endmodule
// -------------------------------------------------------- // --------------------------------------------------------
`ifndef SIMLIB_NOSR `ifndef SIMLIB_NOSR