From dcee3256d59907c474542e0dfd24df7c047e6f50 Mon Sep 17 00:00:00 2001
From: Andrew Zonenberg <azonenberg@drawersteak.com>
Date: Tue, 3 May 2016 22:53:29 -0700
Subject: [PATCH] Added tri-state I/O extraction for GreenPak

---
 techlibs/greenpak4/Makefile.inc       |  1 +
 techlibs/greenpak4/cells_extract.v    | 15 +++++++++++++++
 techlibs/greenpak4/cells_map.v        |  9 +++++++++
 techlibs/greenpak4/cells_sim.v        |  4 ++--
 techlibs/greenpak4/synth_greenpak4.cc |  2 ++
 5 files changed, 29 insertions(+), 2 deletions(-)
 create mode 100644 techlibs/greenpak4/cells_extract.v

diff --git a/techlibs/greenpak4/Makefile.inc b/techlibs/greenpak4/Makefile.inc
index 969b7c80d..4e8e9415c 100644
--- a/techlibs/greenpak4/Makefile.inc
+++ b/techlibs/greenpak4/Makefile.inc
@@ -2,6 +2,7 @@
 OBJS += techlibs/greenpak4/synth_greenpak4.o
 OBJS += techlibs/greenpak4/greenpak4_counters.o
 
+$(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_extract.v))
 $(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_map.v))
 $(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_sim.v))
 $(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/gp_dff.lib))
diff --git a/techlibs/greenpak4/cells_extract.v b/techlibs/greenpak4/cells_extract.v
new file mode 100644
index 000000000..96feb7328
--- /dev/null
+++ b/techlibs/greenpak4/cells_extract.v
@@ -0,0 +1,15 @@
+//Wrapper module to patch up output of iopadmap
+module GP_IOBUF(input IN, output OUT, input OE, inout IO);
+
+	GP_IBUF ibuf(
+		.IN(IO),
+		.OUT(OUT)
+	);
+	
+	$_TBUF_ tbuf(
+		.A(IN),
+		.E(OE),
+		.Y(OUT)
+	);
+
+endmodule
diff --git a/techlibs/greenpak4/cells_map.v b/techlibs/greenpak4/cells_map.v
index 1bc0bcda4..b7d750ae0 100644
--- a/techlibs/greenpak4/cells_map.v
+++ b/techlibs/greenpak4/cells_map.v
@@ -24,6 +24,15 @@ module GP_DFFR(input D, CLK, nRST, output reg Q);
 	);
 endmodule
 
+module GP_OBUFT(input IN, input OE, output OUT);
+	GP_IOBUF _TECHMAP_REPLACE_ (
+		.IN(IN),
+		.OE(OE),
+		.IO(OUT),
+		.OUT()
+	);
+endmodule
+
 module \$lut (A, Y);
   parameter WIDTH = 0;
   parameter LUT = 0;
diff --git a/techlibs/greenpak4/cells_sim.v b/techlibs/greenpak4/cells_sim.v
index a8bb538c4..b419302fd 100644
--- a/techlibs/greenpak4/cells_sim.v
+++ b/techlibs/greenpak4/cells_sim.v
@@ -138,9 +138,9 @@ module GP_IBUF(input IN, output OUT);
 	assign OUT = IN;
 endmodule
 
-module GP_IOBUF(input IN, input DIR, output OUT, inout IO);
+module GP_IOBUF(input IN, input OE, output OUT, inout IO);
 	assign IN = IO;
-	assign DIR = OE ? OUT : 1'bz;
+	assign IO = OE ? OUT : 1'bz;
 endmodule
 
 module GP_INV(input IN, output OUT);
diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc
index 3559e0fad..55412ea2b 100644
--- a/techlibs/greenpak4/synth_greenpak4.cc
+++ b/techlibs/greenpak4/synth_greenpak4.cc
@@ -176,6 +176,8 @@ struct SynthGreenPAK4Pass : public ScriptPass
 		if (check_label("map_cells"))
 		{
 			run("shregmap -tech greenpak4");
+			run("iopadmap -bits -inpad GP_IBUF OUT:IN -outpad GP_OBUF IN:OUT -inoutpad GP_IBUF OUT:IN");
+			run("extract -map +/greenpak4/cells_extract.v -verbose");
 			run("dfflibmap -liberty +/greenpak4/gp_dff.lib");
 			run("techmap -map +/greenpak4/cells_map.v");
 			run("dffinit -ff GP_DFF Q INIT");