diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 34b013dd9..0cdce6b4e 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -110,6 +110,7 @@ struct CellTypes setup_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, pool()); setup_type(ID($original_tag), {ID::A}, {ID::Y}); setup_type(ID($future_ff), {ID::A}, {ID::Y}); + setup_type(ID($icg), {ID::CLK, ID::EN, ID::SE}, {ID::GCLK}, false, false, true); setup_type(ID($scopeinfo), {}, {}); setup_type(ID($input_port), {}, {ID::Y}); setup_type(ID($connect), {ID::A, ID::B}, {}); diff --git a/kernel/constids.inc b/kernel/constids.inc index c99aa788d..59f7246e9 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -221,6 +221,7 @@ X($future_ff) X($ge) X($get_tag) X($gt) +X($icg) X($initstate) X($input) X($input_port) @@ -488,6 +489,7 @@ X(FTCP_N) X(FTDCP) X(FULL) X(G) +X(GCLK) X(GP_DFF) X(GP_DFFI) X(GP_DFFR) @@ -720,6 +722,7 @@ X(SB_RAM40_4KNR) X(SB_RAM40_4KNRNW) X(SB_RAM40_4KNW) X(SD) +X(SE) X(SEL_MASK) X(SEL_PATTERN) X(SET) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index baf938660..40a1dd2f8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2083,6 +2083,15 @@ namespace { return; } + if (cell->type == ID($icg)) { + port(ID::CLK, 1); + port(ID::EN, 1); + port(ID::SE, 1); + port(ID::GCLK, 1); + check_expected(); + return; + } + if (cell->type == ID($dffsr)) { param_bool(ID::CLK_POLARITY); param_bool(ID::SET_POLARITY); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index a0cfee542..3530bc7af 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -536,6 +536,18 @@ struct SimInstance return; } + if (cell->type == ID($icg)) + { + // Integrated clock gate: GCLK = CLK & (EN | SE) + Const clk = get_state(cell->getPort(ID::CLK)); + Const en = get_state(cell->getPort(ID::EN)); + Const se = cell->hasPort(ID::SE) ? get_state(cell->getPort(ID::SE)) : Const(State::S0); + Const en_or_se = const_or(en, se, false, false, 1); + Const gclk = const_and(clk, en_or_se, false, false, 1); + set_state(cell->getPort(ID::GCLK), gclk); + return; + } + if (yosys_celltypes.cell_evaluable(cell->type)) { RTLIL::SigSpec sig_a, sig_b, sig_c, sig_d, sig_s, sig_y;