From 4af5baab218a78c3af18269db8501031b457ed64 Mon Sep 17 00:00:00 2001
From: Robert Ou <rqou@robertou.com>
Date: Sun, 25 Jun 2017 20:16:43 -0700
Subject: coolrunner2: Initial mapping of DFFs

All DFFs map to either FDCP (matches Xilinx) or a custom FDCP_N
(negative-edge triggered)
---
 techlibs/coolrunner2/Makefile.inc          |  1 +
 techlibs/coolrunner2/cells_sim.v           | 40 ++++++++++++++++++++++++++++++
 techlibs/coolrunner2/synth_coolrunner2.cpp |  4 +++
 techlibs/coolrunner2/xc2_dff.lib           | 31 +++++++++++++++++++++++
 4 files changed, 76 insertions(+)
 create mode 100644 techlibs/coolrunner2/xc2_dff.lib

diff --git a/techlibs/coolrunner2/Makefile.inc b/techlibs/coolrunner2/Makefile.inc
index 81612ded2..d1672e782 100644
--- a/techlibs/coolrunner2/Makefile.inc
+++ b/techlibs/coolrunner2/Makefile.inc
@@ -3,3 +3,4 @@ OBJS += techlibs/coolrunner2/synth_coolrunner2.o
 OBJS += techlibs/coolrunner2/coolrunner2_sop.o
 
 $(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_sim.v))
+$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/xc2_dff.lib))
diff --git a/techlibs/coolrunner2/cells_sim.v b/techlibs/coolrunner2/cells_sim.v
index 52326fbb3..f9f990c22 100644
--- a/techlibs/coolrunner2/cells_sim.v
+++ b/techlibs/coolrunner2/cells_sim.v
@@ -54,3 +54,43 @@ module MACROCELL_XOR(IN_PTC, IN_ORTERM, OUT);
     assign OUT = INVERT_OUT ? ~xor_intermed : xor_intermed;
     assign xor_intermed = IN_ORTERM ^ IN_PTC;
 endmodule
+
+module FDCP (C, PRE, CLR, D, Q);
+    parameter INIT = 0;
+
+    input C, PRE, CLR, D;
+    output reg Q;
+
+    initial begin
+        Q <= INIT;
+    end
+
+    always @(posedge C, posedge PRE, posedge CLR) begin
+        if (CLR == 1)
+            Q <= 0;
+        else if (PRE == 1)
+            Q <= 1;
+        else
+            Q <= D;
+    end
+endmodule
+
+module FDCP_N (C, PRE, CLR, D, Q);
+    parameter INIT = 0;
+
+    input C, PRE, CLR, D;
+    output reg Q;
+
+    initial begin
+        Q <= INIT;
+    end
+
+    always @(negedge C, posedge PRE, posedge CLR) begin
+        if (CLR == 1)
+            Q <= 0;
+        else if (PRE == 1)
+            Q <= 1;
+        else
+            Q <= D;
+    end
+endmodule
diff --git a/techlibs/coolrunner2/synth_coolrunner2.cpp b/techlibs/coolrunner2/synth_coolrunner2.cpp
index 516d29ad0..c58b52cdf 100644
--- a/techlibs/coolrunner2/synth_coolrunner2.cpp
+++ b/techlibs/coolrunner2/synth_coolrunner2.cpp
@@ -145,6 +145,7 @@ struct SynthCoolrunner2Pass : public ScriptPass
 		{
 			run("opt -fast -full");
 			run("techmap");
+			run("dfflibmap -prepare -liberty +/coolrunner2/xc2_dff.lib");
 		}
 
 		if (check_label("map_pla"))
@@ -156,6 +157,9 @@ struct SynthCoolrunner2Pass : public ScriptPass
 
 		if (check_label("map_cells"))
 		{
+			run("dfflibmap -liberty +/coolrunner2/xc2_dff.lib");
+			run("dffinit -ff FDCP Q INIT");
+			run("dffinit -ff FDCP_N Q INIT");
 			run("iopadmap -bits -inpad IBUF O:I -outpad IOBUFE I:IO -inoutpad IOBUFE O:IO -toutpad IOBUFE E:I:IO -tinoutpad IOBUFE E:O:I:IO");
 		}
 
diff --git a/techlibs/coolrunner2/xc2_dff.lib b/techlibs/coolrunner2/xc2_dff.lib
new file mode 100644
index 000000000..b578493a1
--- /dev/null
+++ b/techlibs/coolrunner2/xc2_dff.lib
@@ -0,0 +1,31 @@
+library(xc2_dff) {
+  cell(FDCP) {
+    area: 1;
+    ff("IQ", "IQN") { clocked_on: C;
+                      next_state: D;
+                      clear: "CLR";
+                      preset: "PRE"; }
+    pin(C) { direction: input;
+             clock: true; }
+    pin(D) { direction: input; }
+    pin(Q) { direction: output;
+             function: "IQ"; }
+    pin(CLR) { direction: input; }
+    pin(PRE) { direction: input; }
+  }
+
+  cell(FDCP_N) {
+    area: 1;
+    ff("IQ", "IQN") { clocked_on: "!C";
+                      next_state: D;
+                      clear: "CLR";
+                      preset: "PRE"; }
+    pin(C) { direction: input;
+             clock: true; }
+    pin(D) { direction: input; }
+    pin(Q) { direction: output;
+             function: "IQ"; }
+    pin(CLR) { direction: input; }
+    pin(PRE) { direction: input; }
+  }
+}
-- 
cgit v1.2.3