Added $lcu cell type
[yosys.git] / passes / tests / test_cell.cc
index a38023d147a7d1ed314f98007d95aa50d39047bd..1fa90b540075d956810720f3da734504ed1b8598 100644 (file)
@@ -33,12 +33,66 @@ static uint32_t xorshift32(uint32_t limit) {
        return xorshift32_state % limit;
 }
 
-static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags)
+static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags, bool constmode)
 {
        RTLIL::Module *module = design->addModule("\\gold");
        RTLIL::Cell *cell = module->addCell("\\UUT", cell_type);
        RTLIL::Wire *wire;
 
+       if (cell_type == "$fa")
+       {
+               int width = 1 + xorshift32(8);
+
+               wire = module->addWire("\\A");
+               wire->width = width;
+               wire->port_input = true;
+               cell->setPort("\\A", wire);
+
+               wire = module->addWire("\\B");
+               wire->width = width;
+               wire->port_input = true;
+               cell->setPort("\\B", wire);
+
+               wire = module->addWire("\\C");
+               wire->width = width;
+               wire->port_input = true;
+               cell->setPort("\\C", wire);
+
+               wire = module->addWire("\\X");
+               wire->width = width;
+               wire->port_output = true;
+               cell->setPort("\\X", wire);
+
+               wire = module->addWire("\\Y");
+               wire->width = width;
+               wire->port_output = true;
+               cell->setPort("\\Y", wire);
+       }
+
+       if (cell_type == "$lcu")
+       {
+               int width = 1 + xorshift32(8);
+
+               wire = module->addWire("\\P");
+               wire->width = width;
+               wire->port_input = true;
+               cell->setPort("\\P", wire);
+
+               wire = module->addWire("\\G");
+               wire->width = width;
+               wire->port_input = true;
+               cell->setPort("\\G", wire);
+
+               wire = module->addWire("\\CI");
+               wire->port_input = true;
+               cell->setPort("\\CI", wire);
+
+               wire = module->addWire("\\CO");
+               wire->width = width;
+               wire->port_output = true;
+               cell->setPort("\\CO", wire);
+       }
+
        if (cell_type == "$macc")
        {
                Macc macc;
@@ -166,6 +220,41 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
                cell->setPort("\\CO", wire);
        }
 
+       if (constmode)
+       {
+               auto conn_list = cell->connections();
+               for (auto &conn : conn_list)
+               {
+                       RTLIL::SigSpec sig = conn.second;
+
+                       if (SIZE(sig) == 0 || sig[0].wire == nullptr || sig[0].wire->port_output)
+                               continue;
+
+                       int n, m;
+                       switch (xorshift32(5))
+                       {
+                       case 0:
+                               n = xorshift32(SIZE(sig) + 1);
+                               for (int i = 0; i < n; i++)
+                                       sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0;
+                               break;
+                       case 1:
+                               n = xorshift32(SIZE(sig) + 1);
+                               for (int i = n; i < SIZE(sig); i++)
+                                       sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0;
+                               break;
+                       case 2:
+                               n = xorshift32(SIZE(sig));
+                               m = xorshift32(SIZE(sig));
+                               for (int i = std::min(n, m); i < std::max(n, m); i++)
+                                       sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0;
+                               break;
+                       }
+
+                       cell->setPort(conn.first, sig);
+               }
+       }
+
        module->fixup_ports();
        cell->fixup_parameters();
        cell->check();
@@ -412,7 +501,7 @@ struct TestCellPass : public Pass {
                log("\n");
                log("    test_cell [options] {cell-types}\n");
                log("\n");
-               log("Tests the internal implementation of the given cell type (for example '$mux')\n");
+               log("Tests the internal implementation of the given cell type (for example '$add')\n");
                log("by comparing SAT solver, EVAL and TECHMAP implementations of the cell types..\n");
                log("\n");
                log("Run with 'all' instead of a cell type to run the test on all supported\n");
@@ -436,6 +525,9 @@ struct TestCellPass : public Pass {
                log("    -script {script_file}\n");
                log("        instead of calling \"techmap\", call \"script {script_file}\".\n");
                log("\n");
+               log("    -const\n");
+               log("        set some input bits to random constant values\n");
+               log("\n");
                log("    -nosat\n");
                log("        do not check SAT model or run SAT equivalence checking\n");
                log("\n");
@@ -454,6 +546,7 @@ struct TestCellPass : public Pass {
                xorshift32_state = 0;
                std::ofstream vlog_file;
                bool verbose = false;
+               bool constmode = false;
                bool nosat = false;
 
                int argidx;
@@ -484,6 +577,10 @@ struct TestCellPass : public Pass {
                                techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc";
                                continue;
                        }
+                       if (args[argidx] == "-const") {
+                               constmode = true;
+                               continue;
+                       }
                        if (args[argidx] == "-nosat") {
                                nosat = true;
                                continue;
@@ -559,7 +656,9 @@ struct TestCellPass : public Pass {
 
                cell_types["$lut"] = "*";
                cell_types["$alu"] = "ABSY";
+               cell_types["$lcu"] = "*";
                cell_types["$macc"] = "*";
+               cell_types["$fa"] = "*";
 
                for (; argidx < SIZE(args); argidx++)
                {
@@ -610,7 +709,7 @@ struct TestCellPass : public Pass {
                                if (cell_type == "ilang")
                                        Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file);
                                else
-                                       create_gold_module(design, cell_type, cell_types.at(cell_type));
+                                       create_gold_module(design, cell_type, cell_types.at(cell_type), constmode);
                                Pass::call(design, stringf("copy gold gate; cd gate; %s; cd ..; opt -fast gate", techmap_cmd.c_str()));
                                if (!nosat)
                                        Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter");