From 56abb53658b50fa5687b0ca36400f8cfb2c0f811 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:37:40 +1200 Subject: [PATCH 1/7] test_cell: Disable $macc testing Needs updating to `$macc_v2`. --- passes/tests/test_cell.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index a34eafc2f..deba6142e 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -937,7 +937,7 @@ struct TestCellPass : public Pass { cell_types[ID($sop)] = "*"; cell_types[ID($alu)] = "ABSY"; cell_types[ID($lcu)] = "*"; - cell_types[ID($macc)] = "*"; + // cell_types[ID($macc)] = "*"; cell_types[ID($fa)] = "*"; for (; argidx < GetSize(args); argidx++) From 2d069c8a5eb53fe61a0511785d647f042e394c43 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 15 Apr 2025 15:51:40 +1200 Subject: [PATCH 2/7] test_cell: Support more cell types Still unsupported: - wide muxes (`$_MUX16_` and friends) Partially supported types have comments in `test_cell.cc`. Fix `CellTypes::eval() for `$_NMUX_`. Fix `RTLIL::Cell::fixup_parameters()` for $concat, $bwmux and $bweqx. --- kernel/celltypes.h | 2 + kernel/rtlil.cc | 6 +- passes/tests/test_cell.cc | 162 +++++++++++++++++++++++++++++++++++--- 3 files changed, 157 insertions(+), 13 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 0ce5db54d..9aeba6797 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -507,6 +507,8 @@ struct CellTypes { if (cell->type.in(ID($mux), ID($_MUX_))) return const_mux(arg1, arg2, arg3); + if (cell->type == ID($_NMUX_)) + return eval_not(const_mux(arg1, arg2, arg3)); if (cell->type == ID($bwmux)) return const_bwmux(arg1, arg2, arg3); if (cell->type == ID($pmux)) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dd78b202d..618812fc5 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -4242,9 +4242,9 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:")) return; - if (type == ID($buf) || type == ID($mux) || type == ID($pmux) || type == ID($bmux)) { + if (type == ID($buf) || type == ID($mux) || type == ID($pmux) || type == ID($bmux) || type == ID($bwmux) || type == ID($bweqx)) { parameters[ID::WIDTH] = GetSize(connections_[ID::Y]); - if (type != ID($buf) && type != ID($mux)) + if (type.in(ID($pmux), ID($bmux))) parameters[ID::S_WIDTH] = GetSize(connections_[ID::S]); check(); return; @@ -4299,7 +4299,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) parameters[ID::B_WIDTH] = GetSize(connections_[ID::B]); } - if (connections_.count(ID::Y)) + if (connections_.count(ID::Y) && type != ID($concat)) parameters[ID::Y_WIDTH] = GetSize(connections_[ID::Y]); if (connections_.count(ID::Q)) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index deba6142e..2efccebdd 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -71,6 +71,29 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce cell->setPort(ID::Y, wire); } + if (cell_type.in(ID($_MUX_), ID($_NMUX_))) + { + wire = module->addWire(ID::A); + wire->width = 1; + wire->port_input = true; + cell->setPort(ID::A, wire); + + wire = module->addWire(ID::B); + wire->width = 1; + wire->port_input = true; + cell->setPort(ID::B, wire); + + wire = module->addWire(ID::S); + wire->width = 1; + wire->port_input = true; + cell->setPort(ID::S, wire); + + wire = module->addWire(ID::Y); + wire->width = 1; + wire->port_output = true; + cell->setPort(ID::Y, wire); + } + if (cell_type == ID($bmux)) { int width = 1 + xorshift32(8 * bloat_factor); @@ -273,14 +296,19 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce if (cell_type_flags.find('A') != std::string::npos) { wire = module->addWire(ID::A); - wire->width = 1 + xorshift32(8 * bloat_factor); + if (cell_type_flags.find('b') != std::string::npos) + wire->width = 1; + else + wire->width = 1 + xorshift32(8 * bloat_factor); wire->port_input = true; cell->setPort(ID::A, wire); } if (cell_type_flags.find('B') != std::string::npos) { wire = module->addWire(ID::B); - if (cell_type_flags.find('h') != std::string::npos) + if (cell_type_flags.find('b') != std::string::npos) + wire->width = 1; + else if (cell_type_flags.find('h') != std::string::npos) wire->width = 1 + xorshift32(6 * bloat_factor); else wire->width = 1 + xorshift32(8 * bloat_factor); @@ -288,6 +316,26 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce cell->setPort(ID::B, wire); } + if (cell_type_flags.find('C') != std::string::npos) { + wire = module->addWire(ID::C); + if (cell_type_flags.find('b') != std::string::npos) + wire->width = 1; + else + wire->width = 1 + xorshift32(8 * bloat_factor); + wire->port_input = true; + cell->setPort(ID::C, wire); + } + + if (cell_type_flags.find('D') != std::string::npos) { + wire = module->addWire(ID::D); + if (cell_type_flags.find('b') != std::string::npos) + wire->width = 1; + else + wire->width = 1 + xorshift32(8 * bloat_factor); + wire->port_input = true; + cell->setPort(ID::D, wire); + } + if (cell_type_flags.find('S') != std::string::npos && xorshift32(2)) { if (cell_type_flags.find('A') != std::string::npos) cell->parameters[ID::A_SIGNED] = true; @@ -304,7 +352,10 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce if (cell_type_flags.find('Y') != std::string::npos) { wire = module->addWire(ID::Y); - wire->width = 1 + xorshift32(8 * bloat_factor); + if (cell_type_flags.find('b') != std::string::npos) + wire->width = 1; + else + wire->width = 1 + xorshift32(8 * bloat_factor); wire->port_output = true; cell->setPort(ID::Y, wire); } @@ -345,6 +396,58 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce cell->setPort(ID::CO, wire); } + if (cell_type == ID($slice)) + { + int a_size = GetSize(cell->getPort(ID::A)); + int y_size = 1; + if (a_size > 1) + y_size += (xorshift32(8 * bloat_factor) % (a_size - 1)); + wire = module->addWire(ID::Y); + wire->width = y_size; + wire->port_output = true; + cell->setPort(ID::Y, wire); + if (a_size > y_size) + cell->setParam(ID::OFFSET, (xorshift32(8 * bloat_factor) % (a_size - y_size))); + else + cell->setParam(ID::OFFSET, 0); + } + + if (cell_type == ID($concat)) + { + wire = module->addWire(ID::Y); + wire->width = GetSize(cell->getPort(ID::A)) + GetSize(cell->getPort(ID::B)); + wire->port_output = true; + cell->setPort(ID::Y, wire); + } + + if (cell_type == ID($buf)) + { + wire = module->addWire(ID::Y); + wire->width = GetSize(cell->getPort(ID::A)); + wire->port_output = true; + cell->setPort(ID::Y, wire); + } + + if (cell_type.in(ID($bwmux), ID($bweqx))) + { + int a_size = GetSize(cell->getPort(ID::A)); + wire = module->addWire(ID::B); + wire->width = a_size; + wire->port_output = true; + cell->setPort(ID::B, wire); + if (cell_type == ID($bwmux)) + { + wire = module->addWire(ID::S); + wire->width = a_size; + wire->port_output = true; + cell->setPort(ID::S, wire); + } + wire = module->addWire(ID::Y); + wire->width = a_size; + wire->port_output = true; + cell->setPort(ID::Y, wire); + } + if (constmode) { auto conn_list = cell->connections(); @@ -882,6 +985,9 @@ struct TestCellPass : public Pass { cell_types[ID($not)] = "ASY"; cell_types[ID($pos)] = "ASY"; cell_types[ID($neg)] = "ASY"; + // $buf is unsupported with techmap -assert + if (techmap_cmd.compare("techmap -assert") != 0) + cell_types[ID($buf)] = "A"; cell_types[ID($and)] = "ABSY"; cell_types[ID($or)] = "ABSY"; @@ -905,8 +1011,16 @@ struct TestCellPass : public Pass { cell_types[ID($le)] = "ABSY"; cell_types[ID($eq)] = "ABSY"; cell_types[ID($ne)] = "ABSY"; - // cell_types[ID($eqx)] = "ABSY"; - // cell_types[ID($nex)] = "ABSY"; + // $eqx, $nex, and $bweqx don't work in sat, and are unsupported with + // 'techmap -assert' + if (nosat && techmap_cmd.compare("techmap -assert") != 0) + { + cell_types[ID($eqx)] = "ABSY"; + cell_types[ID($nex)] = "ABSY"; + } + // $bweqx is additionally unsupported by ConstEval + if (nosat && techmap_cmd.compare("techmap -assert") != 0 && noeval) + cell_types[ID($bweqx)] = "A"; cell_types[ID($ge)] = "ABSY"; cell_types[ID($gt)] = "ABSY"; @@ -917,7 +1031,10 @@ struct TestCellPass : public Pass { cell_types[ID($mod)] = "ABSY"; cell_types[ID($divfloor)] = "ABSY"; cell_types[ID($modfloor)] = "ABSY"; - // cell_types[ID($pow)] = "ABsY"; + // $pow doesnt work in sat, not supported with 'techmap -assert', and only + // only partially supported with '-simlib' + if (nosat && techmap_cmd.compare("aigmap") == 0) + cell_types[ID($pow)] = "ABsY"; cell_types[ID($logic_not)] = "ASY"; cell_types[ID($logic_and)] = "ABSY"; @@ -926,20 +1043,45 @@ struct TestCellPass : public Pass { cell_types[ID($mux)] = "*"; cell_types[ID($bmux)] = "*"; cell_types[ID($demux)] = "*"; - if (edges) { + // $pmux doesn't work in sat, and is not supported with 'techmap -assert' + if (nosat && techmap_cmd.compare("aigmap") == 0) cell_types[ID($pmux)] = "*"; - } + // $bwmux is not supported by ConstEval + if (noeval) + cell_types[ID($bwmux)] = "A"; - // cell_types[ID($slice)] = "A"; - // cell_types[ID($concat)] = "A"; + cell_types[ID($slice)] = "A"; + cell_types[ID($concat)] = "AB"; cell_types[ID($lut)] = "*"; cell_types[ID($sop)] = "*"; cell_types[ID($alu)] = "ABSY"; cell_types[ID($lcu)] = "*"; + // create_gold_module() needs updating for $macc_v2 // cell_types[ID($macc)] = "*"; cell_types[ID($fa)] = "*"; + cell_types[ID($_BUF_)] = "AYb"; + cell_types[ID($_NOT_)] = "AYb"; + cell_types[ID($_AND_)] = "ABYb"; + cell_types[ID($_NAND_)] = "ABYb"; + cell_types[ID($_OR_)] = "ABYb"; + cell_types[ID($_NOR_)] = "ABYb"; + cell_types[ID($_XOR_)] = "ABYb"; + cell_types[ID($_XNOR_)] = "ABYb"; + cell_types[ID($_ANDNOT_)] = "ABYb"; + cell_types[ID($_ORNOT_)] = "ABYb"; + cell_types[ID($_MUX_)] = "*"; + cell_types[ID($_NMUX_)] = "*"; + // wide $_MUX_ cells are not yet implemented + // cell_types[ID($_MUX4_)] = "*"; + // cell_types[ID($_MUX8_)] = "*"; + // cell_types[ID($_MUX16_)] = "*"; + cell_types[ID($_AOI3_)] = "ABCYb"; + cell_types[ID($_OAI3_)] = "ABCYb"; + cell_types[ID($_AOI4_)] = "ABCDYb"; + cell_types[ID($_OAI4_)] = "ABCDYb"; + for (; argidx < GetSize(args); argidx++) { if (args[argidx].rfind("-", 0) == 0) From 31aaf6e7f78271df9a288d6652ca4cd55984635d Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 15 Apr 2025 17:00:07 +1200 Subject: [PATCH 3/7] test_cell: Fix $bweqx --- passes/tests/test_cell.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 2efccebdd..3a7e413ee 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -433,13 +433,13 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce int a_size = GetSize(cell->getPort(ID::A)); wire = module->addWire(ID::B); wire->width = a_size; - wire->port_output = true; + wire->port_input = true; cell->setPort(ID::B, wire); if (cell_type == ID($bwmux)) { wire = module->addWire(ID::S); wire->width = a_size; - wire->port_output = true; + wire->port_input = true; cell->setPort(ID::S, wire); } wire = module->addWire(ID::Y); @@ -1017,10 +1017,8 @@ struct TestCellPass : public Pass { { cell_types[ID($eqx)] = "ABSY"; cell_types[ID($nex)] = "ABSY"; - } - // $bweqx is additionally unsupported by ConstEval - if (nosat && techmap_cmd.compare("techmap -assert") != 0 && noeval) cell_types[ID($bweqx)] = "A"; + } cell_types[ID($ge)] = "ABSY"; cell_types[ID($gt)] = "ABSY"; From 49eec407c271cac488270676df9f534b143f71ca Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 15 Apr 2025 17:19:31 +1200 Subject: [PATCH 4/7] consteval: Fix $bwmux handling If the cell type has a S signal and hasn't already been handled, use `CellTypes::eval(cell, A, B, S)`. --- kernel/consteval.h | 6 +++++- passes/tests/test_cell.cc | 4 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/kernel/consteval.h b/kernel/consteval.h index 844120ef0..adcf86f8a 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -349,7 +349,11 @@ struct ConstEval return false; bool eval_err = false; - RTLIL::Const eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err); + RTLIL::Const eval_ret; + if (sig_s.size() > 0 && eval(sig_s, undef, cell)) { + eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_s.as_const(), &eval_err); + } else + eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err); if (eval_err) return false; diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 3a7e413ee..068386b49 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -1044,9 +1044,7 @@ struct TestCellPass : public Pass { // $pmux doesn't work in sat, and is not supported with 'techmap -assert' if (nosat && techmap_cmd.compare("aigmap") == 0) cell_types[ID($pmux)] = "*"; - // $bwmux is not supported by ConstEval - if (noeval) - cell_types[ID($bwmux)] = "A"; + cell_types[ID($bwmux)] = "A"; cell_types[ID($slice)] = "A"; cell_types[ID($concat)] = "AB"; From 7f68a1ebd6635f0147c4f65a620a3a50720aefac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 17 Apr 2025 10:53:13 +1200 Subject: [PATCH 5/7] test_cell: Update to $macc_v2 --- passes/tests/test_cell.cc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 068386b49..1fd2066f5 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -190,7 +190,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce cell->setPort(ID::CO, wire); } - if (cell_type == ID($macc)) + if (cell_type == ID($macc_v2)) { Macc macc; int width = 1 + xorshift32(8 * bloat_factor); @@ -224,6 +224,7 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce this_term.do_subtract = xorshift32(2) == 1; macc.terms.push_back(this_term); } + // Macc::to_cell sets the input ports macc.to_cell(cell); @@ -231,12 +232,6 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce wire->width = width; wire->port_output = true; cell->setPort(ID::Y, wire); - - // override the B input (macc helpers always sets an empty vector) - wire = module->addWire(ID::B); - wire->width = xorshift32(mulbits_a ? xorshift32(4)+1 : xorshift32(16)+1); - wire->port_input = true; - cell->setPort(ID::B, wire); } if (cell_type == ID($lut)) @@ -1053,8 +1048,7 @@ struct TestCellPass : public Pass { cell_types[ID($sop)] = "*"; cell_types[ID($alu)] = "ABSY"; cell_types[ID($lcu)] = "*"; - // create_gold_module() needs updating for $macc_v2 - // cell_types[ID($macc)] = "*"; + cell_types[ID($macc_v2)] = "*"; cell_types[ID($fa)] = "*"; cell_types[ID($_BUF_)] = "AYb"; From c04ea307ac3811d8be33ee398aea7631ed744e01 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:23:18 +1200 Subject: [PATCH 6/7] test_cell: Add comment on $pmux `-simlib` also doesn't work. --- passes/tests/test_cell.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 1fd2066f5..f5085cc1c 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -1036,7 +1036,8 @@ struct TestCellPass : public Pass { cell_types[ID($mux)] = "*"; cell_types[ID($bmux)] = "*"; cell_types[ID($demux)] = "*"; - // $pmux doesn't work in sat, and is not supported with 'techmap -assert' + // $pmux doesn't work in sat, and is not supported with 'techmap -assert' or + // '-simlib' if (nosat && techmap_cmd.compare("aigmap") == 0) cell_types[ID($pmux)] = "*"; cell_types[ID($bwmux)] = "A"; From c9c13379204dfab43057f24c48b7f8040bbdeac0 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:02:49 +1200 Subject: [PATCH 7/7] celltypes: Comment pointing to ConstEval `CellTypes::eval()` is more generic but also more limited. `ConstEval::eval()` requires more setup (both in code and at runtime) but has more complete support. --- kernel/celltypes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 9aeba6797..11640c25f 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -334,6 +334,7 @@ struct CellTypes return v; } + // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr) { if (type == ID($sshr) && !signed1) @@ -416,6 +417,7 @@ struct CellTypes log_abort(); } + // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr) { if (cell->type == ID($slice)) { @@ -503,6 +505,7 @@ struct CellTypes return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp); } + // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr) { if (cell->type.in(ID($mux), ID($_MUX_))) @@ -522,6 +525,7 @@ struct CellTypes return eval(cell, arg1, arg2, errp); } + // Consider using the ConstEval struct instead if you need named ports and/or multiple outputs static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr) { if (cell->type == ID($_AOI4_))