coolrunner2: Also construct the XOR cell in the macrocell
authorRobert Ou <rqou@robertou.com>
Sun, 25 Jun 2017 09:20:42 +0000 (02:20 -0700)
committerRobert Ou <rqou@robertou.com>
Mon, 26 Jun 2017 06:58:28 +0000 (23:58 -0700)
techlibs/coolrunner2/cells_sim.v
techlibs/coolrunner2/coolrunner2_sop.cpp

index baeb97fa5feafc869ebd7f7df901c53f3e3bb35f..474d35a9a4f7277dad7ee9df69750337a0fa435c 100644 (file)
@@ -41,3 +41,17 @@ module ORTERM(IN, OUT);
         end
     end
 endmodule
+
+module MACROCELL_XOR(IN_PTC, IN_ORTERM, OUT);
+    parameter INVERT_PTC = 0;
+    parameter INVERT_OUT = 0;
+
+    input IN_PTC;
+    input IN_ORTERM;
+    output wire OUT;
+
+    wire xor_intermed;
+
+    assign OUT = INVERT_OUT ? ~xor_intermed : xor_intermed;
+    assign xor_intermed = INVERT_PTC ? IN_ORTERM ^ ~IN_PTC : IN_ORTERM ^ IN_PTC;
+endmodule
index 36bd77ad634f6b8e57a0c6a810383c3bfe654dc6..8ef08b43a9a2f5f874474d299451ee08126ac1c3 100644 (file)
@@ -83,21 +83,34 @@ struct Coolrunner2SopPass : public Pass {
                                                and_cell->setPort("\\IN_B", and_in_comp);
                                        }
 
-                                       // If there is only one term, don't construct an OR cell
+                                       // TODO: Find the $_NOT_ on the output
+
                                        if (sop_depth == 1)
                                        {
-                                               yosys_xtrace = 1;
-                                               module->connect(sop_output, *intermed_wires.begin());
-                                               log("one\n");
+                                               // If there is only one term, don't construct an OR cell. Directly construct the XOR gate
+                                               auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+                                               xor_cell->setParam("\\INVERT_PTC", 0);
+                                               xor_cell->setParam("\\INVERT_OUT", 0);
+                                               xor_cell->setPort("\\IN_PTC", *intermed_wires.begin());
+                                               xor_cell->setPort("\\OUT", sop_output);
                                        }
                                        else
                                        {
-                                               log("more\n");
-                                               // Construct the cell
+                                               // Wire from OR to XOR
+                                               auto or_to_xor_wire = module->addWire(NEW_ID);
+
+                                               // Construct the OR cell
                                                auto or_cell = module->addCell(NEW_ID, "\\ORTERM");
                                                or_cell->setParam("\\WIDTH", sop_depth);
                                                or_cell->setPort("\\IN", intermed_wires);
-                                               or_cell->setPort("\\OUT", sop_output);
+                                               or_cell->setPort("\\OUT", or_to_xor_wire);
+
+                                               // Construct the XOR cell
+                                               auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+                                               xor_cell->setParam("\\INVERT_PTC", 0);
+                                               xor_cell->setParam("\\INVERT_OUT", 0);
+                                               xor_cell->setPort("\\IN_ORTERM", or_to_xor_wire);
+                                               xor_cell->setPort("\\OUT", sop_output);
                                        }
 
                                        // Finally, remove the $sop cell