Working prototype, sets specific parameters on given IO cells.

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
diff --git a/ql-iob-plugin/ql-iob.cc b/ql-iob-plugin/ql-iob.cc
index 40aeddc..1d99283 100644
--- a/ql-iob-plugin/ql-iob.cc
+++ b/ql-iob-plugin/ql-iob.cc
@@ -50,8 +50,8 @@
         }
 
         // Get the top module of the design
-		m_topModule = a_Design->top_module();
-		if (m_topModule == nullptr) {
+		RTLIL::Module* topModule = a_Design->top_module();
+		if (topModule == nullptr) {
 			log_cmd_error("No top module detected!\n");
 		}
 
@@ -78,6 +78,14 @@
             log_cmd_error("Failed to parse the pinmap CSV file!\n");
         }
 
+        // Build a map of pad names to entries
+        std::unordered_map<std::string, const PinmapParser::Entry> pinmapMap;
+        for (auto& entry : pinmapParser.getEntries()) {
+            if (entry.count("name") != 0) {
+                pinmapMap.emplace(entry.at("name"), entry);
+            }
+        }
+
         // A map of IO cell types and their port names that should go to a pad
         std::unordered_map<std::string, std::string> ioCellTypes;
 
@@ -86,15 +94,18 @@
         ioCellTypes.insert(std::make_pair("outpad", "P"));
 
         // Check all IO cells
-        for (auto cell : m_topModule->cells()) {
+        log("\n");
+        log("    type       | instance             | pad        | loc      | cell     \n");
+        log("   ------------+----------------------+------------+----------+----------\n");
+        for (auto cell : topModule->cells()) {
             auto cellType = RTLIL::unescape_id(cell->type); 
 
-            // No an IO cell
+            // Not an IO cell
             if (ioCellTypes.count(cellType) == 0) {
                 continue;
             }
 
-            log("   %-16s %-40s ", cellType.c_str(), cell->name.c_str());
+            log("    %-10s | %-20s ", cellType.c_str(), cell->name.c_str());
 
             // Get connections to the specified port
             std::string port = RTLIL::escape_id(ioCellTypes.at(cellType));
@@ -108,14 +119,14 @@
 
             // Get the connected wire
             if (!sigspec.is_wire()) {
-                log(" Couldn't determine connection\n");
+                log(" Couldn't determine the connection!\n");
                 continue;
             }
             auto wire = sigspec.as_wire();
 
             // Has to be top level wire
             if (!wire->port_input && !wire->port_output) {
-                log(" No top-level port!\n");
+                log(" Not a top-level wire!\n");
                 continue;
             }
 
@@ -128,83 +139,39 @@
 
             // Get the constraint
             auto constraint = constraintMap.at(wireName);
-            log("%s\n", constraint.padName.c_str());
-        }
+            log("| %-10s ", constraint.padName.c_str());
 
-//        log("%zu connections\n", m_topModule->connections().size());
-
-//        for (auto cell : m_topModule->cells()) {
-//            log("'%s' '%s' %zu\n", cell->name.c_str(), cell->type.c_str(), cell->connections().size());
-//            for (auto c : cell->connections()) {
-//                log(" '%s'\n", c.first.c_str());
-//            }
-//        }
-
-/*        // Get top-level wires
-        for (auto wire : m_topModule->wires()) {
-
-            // Not a top-level
-		    if (!wire->port_input && !wire->port_output) {
+            // Check if there is an entry in the pinmap for this pad name
+            if (pinmapMap.count(constraint.padName) == 0) {
+                log("\n");
                 continue;
             }
 
-            log("'%s'\n", wire->name.c_str());
-            //getConnectedCell(wire, 0);
-        }*/
-    }
+            // Get the entry
+            auto entry = pinmapMap.at(constraint.padName);
 
-    // ..............................................................
-
-    RTLIL::Module* m_topModule = nullptr;
-
-    // ..............................................................
-
-    RTLIL::Module* getConnectedCell(RTLIL::Wire* wire, size_t bit = 0) {
-
-        RTLIL::Module* module = wire->module;
-
-        log("'%s' %d\n", wire->name.c_str(), bit);
-        for (auto connection : m_topModule->connections_) {
-            log("k");
-			auto dst_sig = connection.first;
-			auto src_sig = connection.second;
-
-            // Go down
-            if (dst_sig.is_chunk()) {
-				auto chunk = dst_sig.as_chunk();
-                if (chunk.wire) {
-                    log(" '%s'\n", chunk.wire->name.c_str());
-                }
-                log("%d\n", chunk.width);
-            }
-            
-            if (dst_sig.is_wire()) {
-                auto w = dst_sig.as_wire();
-                log(" '%s'\n",w->name.c_str());
+            // The pinmap entry does not have cell type defined, skip it.
+            if (entry.count("cell") == 0) {
+                log("\n");
+                continue;
             }
 
-/*			if (dst_sig.is_chunk()) {
-				auto chunk = dst_sig.as_chunk();
+            // Location string
+            std::string loc;
+            if (entry.count("x") && entry.count("y")) {
+                loc = stringf("X%sY%s", 
+                    entry.at("x").c_str(),
+                    entry.at("y").c_str()
+                );
+            }
 
-				if (chunk.wire) {
+            log("| %-8s | %s\n", loc.c_str(), entry.at("cell").c_str());
 
-					if (chunk.wire->name != wire->name) {
-						continue;
-					}
-					if (bit < chunk.offset || bit >= (chunk.offset + chunk.width)) {
-						continue;
-					}
-
-					auto src_wires = src_sig.to_sigbit_vector();
-					auto src_wire_sigbit = src_wires.at(bit - chunk.offset);
-					if (src_wire_sigbit.wire) {
-                        log(" '%s'\n", src_wire_sigbit.wire->name.c_str());
-                    }
-                }
-            }*/
+            // Annotate the cell by setting its parameters
+            cell->setParam(RTLIL::escape_id("IO_PAD"),  constraint.padName);
+            cell->setParam(RTLIL::escape_id("IO_LOC"),  loc);
+            cell->setParam(RTLIL::escape_id("IO_TYPE"), entry.at("cell"));
         }
-
-        return nullptr;
     }
 
 } QuicklogicIob;
diff --git a/ql-iob-plugin/tests/Makefile b/ql-iob-plugin/tests/Makefile
index e6268e6..40145a8 100644
--- a/ql-iob-plugin/tests/Makefile
+++ b/ql-iob-plugin/tests/Makefile
@@ -3,5 +3,5 @@
 all: $(TESTS)
 
 generic:
-	yosys -p "plugin -i ../ql-iob.so; read_verilog design.v; synth_quicklogic -flatten; stat; quicklogic_iob design.pcf pinmap.csv; stat"
+	yosys -p "plugin -i ../ql-iob.so; read_verilog design.v; synth_quicklogic -flatten; stat; quicklogic_iob design.pcf pinmap.csv; stat; write_blif -attr -param -cname design.eblif"
 	@echo $@ PASS