ql-qlf: k6n10f: DSP: adjust custom passes

Signed-off-by: Pawel Czarnecki <pczarnecki@antmicro.com>
diff --git a/ql-qlf-plugin/ql-dsp-io-regs.cc b/ql-qlf-plugin/ql-dsp-io-regs.cc
index 7161203..4befecf 100644
--- a/ql-qlf-plugin/ql-dsp-io-regs.cc
+++ b/ql-qlf-plugin/ql-dsp-io-regs.cc
@@ -4,34 +4,56 @@
 USING_YOSYS_NAMESPACE
 PRIVATE_NAMESPACE_BEGIN
 
+#define MODE_BITS_REGISTER_INPUTS_ID 92
+#define MODE_BITS_OUTPUT_SELECT_START_ID 81
+#define MODE_BITS_OUTPUT_SELECT_WIDTH 3
+
 // ============================================================================
 
-const std::vector<std::string> ports2del_mult = {"feedback", "load_acc", "saturate_enable", "shift_right", "round", "subtract", "acc_fir", "dly_b"};
-const std::vector<std::string> ports2del_mult_add_acc = {"saturate_enable", "shift_right", "round", "acc_fir", "dly_b"};
+const std::vector<std::string> ports2del_mult = {"feedback", "load_acc", "subtract", "acc_fir", "dly_b"};
+const std::vector<std::string> ports2del_mult_add_acc = {"acc_fir", "dly_b"};
+const std::vector<std::string> ports2del_extension = {"saturate_enable", "shift_right", "round"};
 
 void ql_dsp_io_regs_pass(RTLIL::Module *module)
 {
 
     for (auto cell : module->cells_) {
         std::string cell_type = cell.second->type.str();
-        if (cell_type == RTLIL::escape_id("QL_DSP2")) {
+        if (cell_type == RTLIL::escape_id("QL_DSP2") || cell_type == RTLIL::escape_id("QL_DSP3")) {
             auto dsp = cell.second;
             bool del_clk = false;
+            bool use_dsp_cfg_params = cell_type == RTLIL::escape_id("QL_DSP3");
+
+            int reg_in_i;
+            int out_sel_i;
 
             // Get DSP configuration
-            const RTLIL::SigSpec *register_inputs;
-            register_inputs = &dsp->getPort(RTLIL::escape_id("register_inputs"));
-            if (!register_inputs)
-                log_error("register_inputs port not found!");
-            auto reg_in_c = register_inputs->as_const();
-            int reg_in_i = reg_in_c.as_int();
+            if (use_dsp_cfg_params) {
+                // Read MODE_BITS at correct indexes
+                auto mode_bits = &dsp->getParam(RTLIL::escape_id("MODE_BITS"));
+                RTLIL::Const register_inputs;
+                register_inputs = mode_bits->bits.at(MODE_BITS_REGISTER_INPUTS_ID);
+                reg_in_i = register_inputs.as_int();
 
-            const RTLIL::SigSpec *output_select;
-            output_select = &dsp->getPort(RTLIL::escape_id("output_select"));
-            if (!output_select)
-                log_error("output_select port not found!");
-            auto out_sel_c = output_select->as_const();
-            int out_sel_i = out_sel_c.as_int();
+                RTLIL::Const output_select;
+                output_select = mode_bits->extract(MODE_BITS_OUTPUT_SELECT_START_ID, MODE_BITS_OUTPUT_SELECT_WIDTH);
+                out_sel_i = output_select.as_int();
+            } else {
+                // Read dedicated configuration ports
+                const RTLIL::SigSpec *register_inputs;
+                register_inputs = &dsp->getPort(RTLIL::escape_id("register_inputs"));
+                if (!register_inputs)
+                    log_error("register_inputs port not found!");
+                auto reg_in_c = register_inputs->as_const();
+                reg_in_i = reg_in_c.as_int();
+
+                const RTLIL::SigSpec *output_select;
+                output_select = &dsp->getPort(RTLIL::escape_id("output_select"));
+                if (!output_select)
+                    log_error("output_select port not found!");
+                auto out_sel_c = output_select->as_const();
+                out_sel_i = out_sel_c.as_int();
+            }
 
             // Build new type name
             std::string new_type = cell_type;
@@ -79,6 +101,11 @@
                 ports2del.insert(ports2del.end(), ports2del_mult_add_acc.begin(), ports2del_mult_add_acc.end());
             }
 
+            // Mark for deleton additional configuration ports
+            if (!use_dsp_cfg_params) {
+                ports2del.insert(ports2del.end(), ports2del_extension.begin(), ports2del_extension.end());
+            }
+
             for (auto portname : ports2del) {
                 const RTLIL::SigSpec *port = &dsp->getPort(RTLIL::escape_id(portname));
                 if (!port)
diff --git a/ql-qlf-plugin/ql-dsp-macc.cc b/ql-qlf-plugin/ql-dsp-macc.cc
index 4738634..7f865b5 100644
--- a/ql-qlf-plugin/ql-dsp-macc.cc
+++ b/ql-qlf-plugin/ql-dsp-macc.cc
@@ -8,7 +8,9 @@
 
 // ============================================================================
 
-void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
+bool use_dsp_cfg_params;
+
+static void create_ql_macc_dsp(ql_dsp_macc_pm &pm)
 {
     auto &st = pm.st_ql_dsp_macc;
 
@@ -78,16 +80,21 @@
     size_t tgt_b_width;
     size_t tgt_z_width;
 
+    string cell_base_name = "dsp_t1";
+    string cell_size_name = "";
+    string cell_cfg_name = "";
+    string cell_full_name = "";
+
     if (min_width <= 2 && max_width <= 2 && z_width <= 4) {
         // Too narrow
         return;
     } else if (min_width <= 9 && max_width <= 10 && z_width <= 19) {
-        type = RTLIL::escape_id("dsp_t1_10x9x32");
+        cell_size_name = "_10x9x32";
         tgt_a_width = 10;
         tgt_b_width = 9;
         tgt_z_width = 19;
     } else if (min_width <= 18 && max_width <= 20 && z_width <= 38) {
-        type = RTLIL::escape_id("dsp_t1_20x18x64");
+        cell_size_name = "_20x18x64";
         tgt_a_width = 20;
         tgt_b_width = 18;
         tgt_z_width = 38;
@@ -96,6 +103,14 @@
         return;
     }
 
+    if (use_dsp_cfg_params)
+        cell_cfg_name = "_cfg_params";
+    else
+        cell_cfg_name = "_cfg_ports";
+
+    cell_full_name = cell_base_name + cell_size_name + cell_cfg_name;
+
+    type = RTLIL::escape_id(cell_full_name);
     log("Inferring MACC %zux%zu->%zu as %s from:\n", a_width, b_width, z_width, RTLIL::unescape_id(type).c_str());
 
     for (auto cell : {st.mul, st.add, st.mux, st.ff}) {
@@ -199,19 +214,26 @@
     cell->setPort(RTLIL::escape_id("unsigned_a_i"), RTLIL::SigSpec(a_signed ? RTLIL::S0 : RTLIL::S1));
     cell->setPort(RTLIL::escape_id("unsigned_b_i"), RTLIL::SigSpec(b_signed ? RTLIL::S0 : RTLIL::S1));
 
-    // Connect config ports
-    cell->setPort(RTLIL::escape_id("saturate_enable_i"), RTLIL::SigSpec(RTLIL::S0));
-    cell->setPort(RTLIL::escape_id("shift_right_i"), RTLIL::SigSpec(RTLIL::S0, 6));
-    cell->setPort(RTLIL::escape_id("round_i"), RTLIL::SigSpec(RTLIL::S0));
-    cell->setPort(RTLIL::escape_id("register_inputs_i"), RTLIL::SigSpec(RTLIL::S0));
+    // Connect config bits
+    if (use_dsp_cfg_params) {
+        cell->setParam(RTLIL::escape_id("SATURATE_ENABLE"), RTLIL::Const(RTLIL::S0));
+        cell->setParam(RTLIL::escape_id("SHIFT_RIGHT"), RTLIL::Const(RTLIL::S0, 6));
+        cell->setParam(RTLIL::escape_id("ROUND"), RTLIL::Const(RTLIL::S0));
+        cell->setParam(RTLIL::escape_id("REGISTER_INPUTS"), RTLIL::Const(RTLIL::S0));
+        // 3 - output post acc; 1 - output pre acc
+        cell->setParam(RTLIL::escape_id("OUTPUT_SELECT"), out_ff ? RTLIL::Const(1, 3) : RTLIL::Const(3, 3));
+    } else {
+        cell->setPort(RTLIL::escape_id("saturate_enable_i"), RTLIL::SigSpec(RTLIL::S0));
+        cell->setPort(RTLIL::escape_id("shift_right_i"), RTLIL::SigSpec(RTLIL::S0, 6));
+        cell->setPort(RTLIL::escape_id("round_i"), RTLIL::SigSpec(RTLIL::S0));
+        cell->setPort(RTLIL::escape_id("register_inputs_i"), RTLIL::SigSpec(RTLIL::S0));
+        // 3 - output post acc; 1 - output pre acc
+        cell->setPort(RTLIL::escape_id("output_select_i"), out_ff ? RTLIL::Const(1, 3) : RTLIL::Const(3, 3));
+    }
 
     bool subtract = (st.add->type == RTLIL::escape_id("$sub"));
     cell->setPort(RTLIL::escape_id("subtract_i"), RTLIL::SigSpec(subtract ? RTLIL::S1 : RTLIL::S0));
 
-    // 3 - output post acc
-    // 1 - output pre acc
-    cell->setPort(RTLIL::escape_id("output_select_i"), out_ff ? RTLIL::Const(1, 3) : RTLIL::Const(3, 3));
-
     // Mark the cells for removal
     pm.autoremove(st.mul);
     pm.autoremove(st.add);
@@ -230,14 +252,25 @@
         log("\n");
         log("    ql_dsp_macc [options] [selection]\n");
         log("\n");
+        log("    -use_dsp_cfg_params\n");
+        log("        By default use DSP blocks with configuration bits available at module ports.\n");
+        log("        Specifying this forces usage of DSP block with configuration bits available as module parameters\n");
+        log("\n");
     }
 
+    void clear_flags() override { use_dsp_cfg_params = false; }
+
     void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
     {
         log_header(a_Design, "Executing QL_DSP_MACC pass.\n");
 
         size_t argidx;
         for (argidx = 1; argidx < a_Args.size(); argidx++) {
+            if (a_Args[argidx] == "-use_dsp_cfg_params") {
+                use_dsp_cfg_params = true;
+                continue;
+            }
+
             break;
         }
         extra_args(a_Args, argidx, a_Design);
@@ -246,6 +279,7 @@
             ql_dsp_macc_pm(module, module->selected_cells()).run_ql_dsp_macc(create_ql_macc_dsp);
         }
     }
+
 } QlDspMacc;
 
 PRIVATE_NAMESPACE_END
diff --git a/ql-qlf-plugin/ql-dsp-simd.cc b/ql-qlf-plugin/ql-dsp-simd.cc
index edf432a..b2935a9 100644
--- a/ql-qlf-plugin/ql-dsp-simd.cc
+++ b/ql-qlf-plugin/ql-dsp-simd.cc
@@ -24,6 +24,9 @@
 USING_YOSYS_NAMESPACE
 PRIVATE_NAMESPACE_BEGIN
 
+#define MODE_BITS_BASE_SIZE 80
+#define MODE_BITS_EXTENSION_SIZE 13
+
 // ============================================================================
 
 struct QlDspSimdPass : public Pass {
@@ -48,6 +51,9 @@
         // Port connections
         dict<RTLIL::IdString, RTLIL::SigSpec> connections;
 
+        // Whether DSPs pass configuration bits through ports of parameters
+        bool use_cfg_params;
+
         // TODO: Possibly include parameters here. For now we have just
         // connections.
 
@@ -58,7 +64,7 @@
 
         unsigned int hash() const { return connections.hash(); }
 
-        bool operator==(const DspConfig &ref) const { return connections == ref.connections; }
+        bool operator==(const DspConfig &ref) const { return connections == ref.connections && use_cfg_params == ref.use_cfg_params; }
     };
 
     // ..........................................
@@ -73,12 +79,14 @@
                                                                             std::make_pair("unsigned_a_i", "unsigned_a"),
                                                                             std::make_pair("unsigned_b_i", "unsigned_b"),
 
-                                                                            std::make_pair("output_select_i", "output_select"),
-                                                                            std::make_pair("saturate_enable_i", "saturate_enable"),
-                                                                            std::make_pair("shift_right_i", "shift_right"),
-                                                                            std::make_pair("round_i", "round"),
-                                                                            std::make_pair("subtract_i", "subtract"),
-                                                                            std::make_pair("register_inputs_i", "register_inputs")};
+                                                                            std::make_pair("subtract_i", "subtract")};
+    // For QL_DSP2 expand with configuration ports
+    const std::vector<std::pair<std::string, std::string>> m_DspCfgPorts_expand = {
+      std::make_pair("output_select_i", "output_select"), std::make_pair("saturate_enable_i", "saturate_enable"),
+      std::make_pair("shift_right_i", "shift_right"), std::make_pair("round_i", "round"), std::make_pair("register_inputs_i", "register_inputs")};
+
+    // For QL_DSP3 use parameters instead
+    const std::vector<std::string> m_DspParams2Mode = {"OUTPUT_SELECT", "SATURATE_ENABLE", "SHIFT_RIGHT", "ROUND", "REGISTER_INPUTS"};
 
     // DSP data ports and how to map them to ports of the target DSP cell
     const std::vector<std::pair<std::string, std::string>> m_DspDataPorts = {
@@ -91,8 +99,12 @@
 
     // Source DSP cell type (SISD)
     const std::string m_SisdDspType = "dsp_t1_10x9x32";
-    // Target DSP cell type for the SIMD mode
-    const std::string m_SimdDspType = "QL_DSP2";
+    // Suffix for DSP cell with configuration parameters
+    const std::string m_SisdDspType_cfg_params_suffix = "_cfg_params";
+
+    // Target DSP cell types for the SIMD mode
+    const std::string m_SimdDspType_cfg_ports = "QL_DSP2";
+    const std::string m_SimdDspType_cfg_params = "QL_DSP3";
 
     /// Temporary SigBit to SigBit helper map.
     SigMap m_SigMap;
@@ -117,8 +129,8 @@
             dict<DspConfig, std::vector<RTLIL::Cell *>> groups;
             for (auto cell : module->selected_cells()) {
 
-                // Check if this is a DSP cell
-                if (cell->type != RTLIL::escape_id(m_SisdDspType)) {
+                // Check if this is a DSP cell we are looking for (type starts with m_SisdDspType)
+                if (strncmp(cell->type.c_str(), RTLIL::escape_id(m_SisdDspType).c_str(), RTLIL::escape_id(m_SisdDspType).size()) != 0) {
                     continue;
                 }
 
@@ -139,6 +151,7 @@
                 const auto &group = it.second;
                 const auto &config = it.first;
 
+                bool use_cfg_params = config.use_cfg_params;
                 // Ensure an even number
                 size_t count = group.size();
                 if (count & 1)
@@ -150,22 +163,32 @@
                     const RTLIL::Cell *dsp_b = group[i + 1];
 
                     std::string name = stringf("simd_%s_%s", RTLIL::unescape_id(dsp_a->name).c_str(), RTLIL::unescape_id(dsp_b->name).c_str());
+                    std::string SimdDspType;
+
+                    if (use_cfg_params)
+                        SimdDspType = m_SimdDspType_cfg_params;
+                    else
+                        SimdDspType = m_SimdDspType_cfg_ports;
 
                     log(" SIMD: %s (%s) + %s (%s) => %s (%s)\n", RTLIL::unescape_id(dsp_a->name).c_str(), RTLIL::unescape_id(dsp_a->type).c_str(),
                         RTLIL::unescape_id(dsp_b->name).c_str(), RTLIL::unescape_id(dsp_b->type).c_str(), RTLIL::unescape_id(name).c_str(),
-                        m_SimdDspType.c_str());
+                        SimdDspType.c_str());
 
                     // Create the new cell
-                    RTLIL::Cell *simd = module->addCell(RTLIL::escape_id(name), RTLIL::escape_id(m_SimdDspType));
+                    RTLIL::Cell *simd = module->addCell(RTLIL::escape_id(name), RTLIL::escape_id(SimdDspType));
 
                     // Check if the target cell is known (important to know
                     // its port widths)
                     if (!simd->known()) {
-                        log_error(" The target cell type '%s' is not known!", m_SimdDspType.c_str());
+                        log_error(" The target cell type '%s' is not known!", SimdDspType.c_str());
                     }
 
+                    std::vector<std::pair<std::string, std::string>> DspCfgPorts = m_DspCfgPorts;
+                    if (!use_cfg_params)
+                        DspCfgPorts.insert(DspCfgPorts.end(), m_DspCfgPorts_expand.begin(), m_DspCfgPorts_expand.end());
+
                     // Connect common ports
-                    for (const auto &it : m_DspCfgPorts) {
+                    for (const auto &it : DspCfgPorts) {
                         auto sport = RTLIL::escape_id(it.first);
                         auto dport = RTLIL::escape_id(it.second);
 
@@ -216,12 +239,27 @@
                         mode_bits.insert(mode_bits.end(), val_a.begin(), val_a.end());
                         mode_bits.insert(mode_bits.end(), val_b.begin(), val_b.end());
                     }
+                    long unsigned int mode_bits_size = MODE_BITS_BASE_SIZE;
+                    if (use_cfg_params) {
+                        // Add additional config parameters if necessary
+                        mode_bits.push_back(RTLIL::S1); // MODE_BITS[80] == F_MODE : Enable fractured mode
+                        for (const auto &it : m_DspParams2Mode) {
+                            log_assert(dsp_a->getParam(RTLIL::escape_id(it)) == dsp_b->getParam(RTLIL::escape_id(it)));
+                            auto param = dsp_a->getParam(RTLIL::escape_id(it));
+                            if (param.size() > 1) {
+                                mode_bits.insert(mode_bits.end(), param.bits.begin(), param.bits.end());
+                            } else {
+                                mode_bits.push_back(param.bits[0]);
+                            }
+                        }
+                        mode_bits_size += MODE_BITS_EXTENSION_SIZE;
+                    } else {
+                        // Enable the fractured mode by connecting the control
+                        // port.
+                        simd->setPort(RTLIL::escape_id("f_mode"), RTLIL::S1);
+                    }
                     simd->setParam(RTLIL::escape_id("MODE_BITS"), RTLIL::Const(mode_bits));
-                    log_assert(mode_bits.size() == 80);
-
-                    // Enable the fractured mode by connecting the control
-                    // port.
-                    simd->setPort(RTLIL::escape_id("f_mode"), RTLIL::S1);
+                    log_assert(mode_bits.size() == mode_bits_size);
 
                     // Mark DSP parts for removal
                     cellsToRemove.push_back(dsp_a);
@@ -270,7 +308,18 @@
     {
         DspConfig config;
 
-        for (const auto &it : m_DspCfgPorts) {
+        string cell_type = a_Cell->type.str();
+        string suffix = m_SisdDspType_cfg_params_suffix;
+
+        bool use_cfg_params = cell_type.size() >= suffix.size() && 0 == cell_type.compare(cell_type.size() - suffix.size(), suffix.size(), suffix);
+
+        std::vector<std::pair<std::string, std::string>> DspCfgPorts = m_DspCfgPorts;
+        if (!use_cfg_params)
+            DspCfgPorts.insert(DspCfgPorts.end(), m_DspCfgPorts_expand.begin(), m_DspCfgPorts_expand.end());
+
+        config.use_cfg_params = use_cfg_params;
+
+        for (const auto &it : DspCfgPorts) {
             auto port = RTLIL::escape_id(it.first);
 
             // Port unconnected
diff --git a/ql-qlf-plugin/synth_quicklogic.cc b/ql-qlf-plugin/synth_quicklogic.cc
index 303b1de..5be10ec 100644
--- a/ql-qlf-plugin/synth_quicklogic.cc
+++ b/ql-qlf-plugin/synth_quicklogic.cc
@@ -73,6 +73,10 @@
         log("        By default use DSP blocks in output netlist.\n");
         log("        do not use DSP blocks to implement multipliers and associated logic\n");
         log("\n");
+        log("    -use_dsp_cfg_params\n");
+        log("        By default use DSP blocks with configuration bits available at module ports.\n");
+        log("        Specifying this forces usage of DSP block with configuration bits available as module parameters\n");
+        log("\n");
         log("    -no_adder\n");
         log("        By default use adder cells in output netlist.\n");
         log("        Specifying this switch turns it off.\n");
@@ -95,7 +99,7 @@
         log("\n");
     }
 
-    string top_opt, edif_file, blif_file, family, currmodule, verilog_file;
+    string top_opt, edif_file, blif_file, family, currmodule, verilog_file, use_dsp_cfg_params;
     bool nodsp;
     bool inferAdder;
     bool inferBram;
@@ -119,6 +123,7 @@
         noffmap = false;
         nodsp = false;
         nosdff = false;
+        use_dsp_cfg_params = "";
     }
 
     void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -164,6 +169,10 @@
                 nodsp = true;
                 continue;
             }
+            if (args[argidx] == "-use_dsp_cfg_params") {
+                use_dsp_cfg_params = " -use_dsp_cfg_params";
+                continue;
+            }
             if (args[argidx] == "-no_adder") {
                 inferAdder = false;
                 continue;
@@ -223,8 +232,13 @@
     void script() override
     {
         if (check_label("begin")) {
+            std::string family_path = " +/quicklogic/" + family;
             std::string readVelArgs;
-            readVelArgs = " +/quicklogic/" + family + "/cells_sim.v";
+
+            // Read simulation library
+            readVelArgs = family_path + "/cells_sim.v";
+            if (family == "qlf_k6n10f")
+                readVelArgs += family_path + "/dsp_sim.v";
 
             // Use -nomem2reg here to prevent Yosys from complaining about
             // some block ram cell models. After all the only part of the cells
@@ -295,18 +309,22 @@
                 };
 
                 if (help_mode) {
-                    run("wreduce t:$mul", "                (for qlf_k6n10f if not -no_dsp)");
-                    run("ql_dsp_macc", "                   (for qlf_k6n10f if not -no_dsp)");
-                    run("techmap -map +/mul2dsp.v [...]", "(for qlf_k6n10f if not -no_dsp)");
-                    run("chtype -set $mul t:$__soft_mul", "(for qlf_k6n10f if not -no_dsp)");
+                    run("wreduce t:$mul", "                  (for qlf_k6n10f if not -no_dsp)");
+                    run("ql_dsp_macc" + use_dsp_cfg_params, "(for qlf_k6n10f if not -no_dsp)");
+                    run("techmap -map +/mul2dsp.v [...]", "  (for qlf_k6n10f if not -no_dsp)");
+                    run("chtype -set $mul t:$__soft_mul", "  (for qlf_k6n10f if not -no_dsp)");
                     run("techmap -map +/quicklogic/" + family + "/dsp_map.v", "(for qlf_k6n10f if not -no_dsp)");
+                    if (use_dsp_cfg_params == "")
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0", "(for qlf_k6n10f if not -no_dsp)");
+                    else
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=1", "(for qlf_k6n10f if not -no_dsp)");
                     run("ql_dsp_simd                   ", "(for qlf_k6n10f if not -no_dsp)");
                     run("techmap -map +/quicklogic/" + family + "/dsp_final_map.v", "(for qlf_k6n10f if not -no_dsp)");
                     run("ql_dsp_io_regs");
                 } else if (!nodsp) {
 
                     run("wreduce t:$mul");
-                    run("ql_dsp_macc");
+                    run("ql_dsp_macc" + use_dsp_cfg_params);
 
                     for (const auto &rule : dsp_rules) {
                         run(stringf("techmap -map +/mul2dsp.v "
@@ -316,7 +334,10 @@
                                     rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.type.c_str()));
                         run("chtype -set $mul t:$__soft_mul");
                     }
-                    run("techmap -map +/quicklogic/" + family + "/dsp_map.v");
+                    if (use_dsp_cfg_params == "")
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0");
+                    else
+                        run("techmap -map +/quicklogic/" + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=1");
                     run("ql_dsp_simd");
                     run("techmap -map +/quicklogic/" + family + "/dsp_final_map.v");
                     run("ql_dsp_io_regs");