From d61391390558eac2c79d45c021bea7b916813ac7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:17:23 +1300 Subject: [PATCH] select: Add cell type property selector Looks up the cell type for each cell in the design, returning the value of `CellType::is_`. Only works for exact match, and only for internal cells. Also add a simple test checking a small design with an $add cell and an $sdff cell. --- passes/cmds/select.cc | 34 ++++++++++++++++++++++++++++++ tests/select/type_props.ys | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 tests/select/type_props.ys diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index aec4c964b..dccc99d02 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,6 +141,30 @@ static bool match_attr(const dict &attributes, co return match_attr(attributes, match_expr, std::string(), 0); } +static bool match_type_prop(RTLIL::IdString type, const std::string &property) +{ + auto *ct = yosys_celltypes.get_cell(type); + if (ct == nullptr) { + return false; + } else + if (property.compare("evaluable") == 0) { + return ct->is_evaluable; + } else + if (property.compare("combinatorial") == 0) { + return ct->is_combinatorial; + } else + if (property.compare("synthesizable") == 0) { + return ct->is_synthesizable; + } else + if (property.compare("builtin_ff") == 0) { + return ct->is_builtin_ff; + } else + if (property.compare("formal") == 0) { + return ct->is_formal; + } else + log_cmd_error("Unsupported type property '%s'!\n", property.c_str()); +} + static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { if (lhs.full_selection) { @@ -891,6 +915,11 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp sel.selected_members[mod->name].insert(cell->name); } } else + if (arg_memb.compare(0, 2, "y:") == 0) { + for (auto cell : mod->cells()) + if (match_type_prop(cell->type, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); + } else if (arg_memb.compare(0, 2, "p:") == 0) { for (auto &it : mod->processes) if (match_ids(it.first, arg_memb.substr(2))) @@ -1178,6 +1207,11 @@ struct SelectPass : public Pass { log(" t:@\n"); log(" all cells with a type matching a module in the saved selection \n"); log("\n"); + log(" y:\n"); + log(" all cells with a given type property, possible values are:\n"); + log(" evaluable, combinatorial, synthesizable, builtin_ff, formal\n"); + log(" (currently only internal cells can have type properties)\n"); + log("\n"); log(" p:\n"); log(" all processes with a name matching the given pattern\n"); log("\n"); diff --git a/tests/select/type_props.ys b/tests/select/type_props.ys new file mode 100644 index 000000000..44f181054 --- /dev/null +++ b/tests/select/type_props.ys @@ -0,0 +1,42 @@ +read_rtlil << EOF +module \sm2 + + wire input 1 \clk + wire input 2 \rst + wire width 2 input 3 \a + + wire width 2 \add_Y + + attribute \init 2'00 + wire width 2 output 4 \y + + cell $add \add + parameter \A_SIGNED 0 + parameter \A_WIDTH 2 + parameter \B_SIGNED 0 + parameter \B_WIDTH 2 + parameter \Y_WIDTH 2 + connect \A \y + connect \B \a + connect \Y \add_Y + end + + cell $sdff \sdff + parameter \CLK_POLARITY 1 + parameter \SRST_POLARITY 1 + parameter \SRST_VALUE 2'00 + parameter \WIDTH 2 + connect \CLK \clk + connect \D \add_Y + connect \Q \y + connect \SRST \rst + end +end + +EOF + +select -assert-count 1 y:evaluable +select -assert-count 1 y:combinatorial +select -assert-count 2 y:synthesizable +select -assert-count 1 y:builtin_ff +select -assert-count 0 y:formal