Repurposing repository to hold the raw design flow used to create, extract, characterize, and test the OSU standard cells.
sky130_osu_18T_hs and sky130_osu_12T_hs are next on the list to be fully implemented, as variants of sky130_osu_18T_ms and sky130_osu_12T_ms.
diff --git a/flow/synth_snps/.gitignore b/flow/synth_snps/.gitignore
new file mode 100644
index 0000000..87dbe6d
--- /dev/null
+++ b/flow/synth_snps/.gitignore
@@ -0,0 +1,6 @@
+WORK/
+alib*/
+synth.out
+reports/
+mapped/
+unmapped/
diff --git a/flow/synth_snps/.synopsys_dc.setup b/flow/synth_snps/.synopsys_dc.setup
new file mode 100755
index 0000000..f4758b7
--- /dev/null
+++ b/flow/synth_snps/.synopsys_dc.setup
@@ -0,0 +1,80 @@
+# Standard cells 
+
+set s8lib	"../../outputs"
+
+# Search Paths
+set CURRENT_DIR  [exec pwd]
+set search_path [list "./" ]
+
+lappend search_path $s8lib
+
+# Synthetic libraries
+set synthetic_library   [list dw_foundation.sldb]
+
+# Set OKSTATE standard cell libraries
+set target_library [list]
+
+lappend target_library sky130_osu_sc_18T_ms.ccs.db
+
+# Set Link Library
+set link_library "$target_library $synthetic_library"
+
+# Set up DesignWare cache read and write directories to speed up compile.
+set cache_write  ~
+set cache_read   $cache_write
+
+# Tell DC where to look for files
+lappend search_path ./scripts
+lappend search_path ./hdl
+lappend search_path ./mapped
+
+# Set up User Information
+set company "Oklahoma State University"
+set user    "James E. Stine"
+
+# Alias
+alias ra report_area
+alias rt report_timing
+alias rc {report_constraint -all_violators}
+
+alias sf set_flatten
+alias ss set_structure
+alias rco report_compile_options
+alias cs compile -scan
+alias csi compile -scan -incr -map high
+
+alias h history
+history keep 100
+alias all_gone {remove_design -designs}
+ 
+alias page_on {set sh_enable_page_mode true}
+alias page_off {set sh_enable_page_mode false}
+
+# specify directory for intermediate files from analyze
+define_design_lib DEFAULT -path ./analyzed
+ 
+# suppress Driving cell warning
+suppress_message {UID-401}
+
+########### Source Useful Tcl Procedures ###########
+
+foreach _file [glob -nocomplain ./tcl_procs/*.tcl] {
+  source $_file
+}
+
+############# Enable line editing in 2004.12 ###########
+
+set sh_enable_line_editing true
+
+############# Setup the view utility ###########
+
+proc view {args} {
+    redirect tmpfile1212 {uplevel $args}
+    # Without redirect, exec echos the PID of the new process to the screen
+    redirect /dev/null {exec ./tcl_procs/view.tk tmpfile1212 "$args" &}
+}
+
+alias vrt {view report_timing -nosplit}
+alias vrtm {view report_timing -nosplit -delay min}
+alias vman {view man}
+
diff --git a/flow/synth_snps/Makefile b/flow/synth_snps/Makefile
new file mode 100755
index 0000000..87acded
--- /dev/null
+++ b/flow/synth_snps/Makefile
@@ -0,0 +1,34 @@
+#  
+#  Oklahoma State University
+#  Makefile for synthesis
+# 
+NAME	:= synth
+
+VARIANT:=18T_ms
+
+default:
+	@echo "Basic synthesis procedure for AFRL/OSU:"
+	@echo " adapt Makefile to your liking..."
+	@echo
+
+synth:
+	@sed -i 's/18T_ms/${VARIANT}/g' scripts/synth.tcl
+	@sed -i 's/18T_ms/${VARIANT}/g' .synopsys_dc.setup
+	@echo "DC Synthesis"
+	@mkdir -p reports
+	@mkdir -p mapped
+	dc_shell-xg-t -64bit -f scripts/$(NAME).tcl | tee $(NAME).out
+	@cp mapped/*.sdc ../../outputs/
+	@cp mapped/*.vh ../../outputs/
+	@sed -i 's/${VARIANT}/18T_ms/g' scripts/synth.tcl
+	@sed -i 's/${VARIANT}/18T_ms/g' .synopsys_dc.setup
+
+clean:
+	rm -rf  alib-52 WORK mapped unmapped reports analyzed $(NAME).out
+	mkdir mapped unmapped reports
+	rm -f default.svf
+	rm -f command.log
+	rm -f filenames*.log
+
+
+
diff --git a/flow/synth_snps/hdl/addmant.sv b/flow/synth_snps/hdl/addmant.sv
new file mode 100755
index 0000000..abca124
--- /dev/null
+++ b/flow/synth_snps/hdl/addmant.sv
@@ -0,0 +1,18 @@
+module addmant (input logic alessb,
+		input logic [23:0] manta, mantb, shmant,
+		input logic [7:0] exp_pre,
+		output logic [22:0] fract,
+		output logic [7:0] exponent);
+   
+   logic [24:0] 		  addresult;
+   logic [23:0] 		  addval;
+   
+   assign addval = alessb ? mantb : manta;
+   assign addresult = shmant + addval;
+   assign fract = addresult[24] ?
+		  addresult[23:1] :
+		  addresult[22:0];
+   assign exponent = addresult[24] ? (exp_pre + 1) :
+		     exp_pre;
+
+endmodule // addmant
diff --git a/flow/synth_snps/hdl/arm_single.sv b/flow/synth_snps/hdl/arm_single.sv
new file mode 100755
index 0000000..ac57ec9
--- /dev/null
+++ b/flow/synth_snps/hdl/arm_single.sv
@@ -0,0 +1,329 @@
+module top (input  logic        clk, reset, 

+            output logic [31:0] WriteData, DataAdr, 

+            output logic        MemWrite);

+

+   logic [31:0] 		PC, Instr, ReadData;

+   

+   // instantiate processor and memories

+   arm arm (clk, reset, PC, Instr, MemWrite, DataAdr, 

+            WriteData, ReadData);

+

+   imem imem (PC, Instr);

+   dmem dmem (ReadData, MemWrite, clk, DataAdr, WriteData);

+   

+endmodule // top

+

+module arm (input  logic        clk, reset,

+            output logic [31:0] PC,

+            input  logic [31:0] Instr,

+            output logic        MemWrite,

+            output logic [31:0] ALUResult, WriteData,

+            input  logic [31:0] ReadData);

+   

+   logic [3:0] 			ALUFlags;

+   logic 			RegWrite, 

+				ALUSrc, MemtoReg, PCSrc;

+   logic [2:0] 			RegSrc;   

+   logic [1:0] 			ImmSrc, ALUControl;

+   

+   controller c (clk, reset, Instr[31:12], ALUFlags, 

+		 RegSrc, RegWrite, ImmSrc, 

+		 ALUSrc, ALUControl,

+		 MemWrite, MemtoReg, PCSrc);

+   datapath dp (clk, reset, 

+		RegSrc, RegWrite, ImmSrc,

+		ALUSrc, ALUControl,

+		MemtoReg, PCSrc,

+		ALUFlags, PC, Instr,

+		ALUResult, WriteData, ReadData);

+   

+endmodule // arm

+

+module controller (input  logic         clk, reset,

+                   input  logic [31:12] Instr,

+                   input  logic [3:0]   ALUFlags,

+                   output logic [2:0]   RegSrc,

+                   output logic         RegWrite,

+                   output logic [1:0]   ImmSrc,

+                   output logic         ALUSrc, 

+                   output logic [1:0]   ALUControl,

+                   output logic         MemWrite, MemtoReg,

+                   output logic         PCSrc);

+   

+   logic [1:0] 				FlagW;

+   logic 				PCS, RegW, MemW;

+   

+   decoder dec (Instr[27:26], Instr[25:20], Instr[15:12],

+		FlagW, PCS, RegW, MemW,

+		MemtoReg, ALUSrc, ImmSrc, ALUControl, RegSrc);

+   condlogic cl (clk, reset, Instr[31:28], ALUFlags,

+		 FlagW, PCS, RegW, MemW,

+		 PCSrc, RegWrite, MemWrite);

+endmodule

+

+module decoder (input  logic [1:0] Op,

+		input  logic [5:0] Funct,

+		input  logic [3:0] Rd,

+		output logic [1:0] FlagW,

+		output logic       PCS, RegW, MemW,

+		output logic       MemtoReg, ALUSrc,

+		output logic [1:0] ImmSrc, ALUControl,

+		output logic [2:0] RegSrc);

+   

+   logic [10:0] 		   controls;

+   logic 			   Branch, ALUOp;

+

+   // Main Decoder

+   always_comb

+     case(Op)

+       // Data processing immediate

+       2'b00: if (Funct[5]) controls = 11'b000_0010_1001;

+       // Data processing register

+       else controls = 11'b000_0000_1001;

+       // LDR

+       2'b01: if (Funct[0]) controls = 11'b000_0111_1000;

+       // STR

+       else controls = 11'b010_0111_0100;

+       // BL

+       2'b10: if (Funct[4]) controls = 11'b101_1010_1010;

+       // B

+       else controls = 11'b001_1010_0010;

+       // Unimplemented

+       default: controls = 11'bx;

+     endcase // case (Op)

+

+   assign {RegSrc, ImmSrc, ALUSrc, MemtoReg,

+	      RegW, MemW, Branch, ALUOp} = controls;

+      

+   // ALU Decoder             

+   always_comb

+     if (ALUOp) begin                 // which DP Instr?

+	case(Funct[4:1]) 

+  	  4'b0100: ALUControl = 2'b00; // ADD

+  	  4'b0010: ALUControl = 2'b01; // SUB

+          4'b0000: ALUControl = 2'b10; // AND

+  	  4'b1100: ALUControl = 2'b11; // ORR

+  	  default: ALUControl = 2'bx;  // unimplemented

+	endcase

+	// update flags if S bit is set 

+	// (C & V only updated for arith instructions)

+	FlagW[1]      = Funct[0]; // FlagW[1] = S-bit

+	// FlagW[0] = S-bit & (ADD | SUB)

+	FlagW[0]      = Funct[0] & 

+			(ALUControl == 2'b00 | ALUControl == 2'b01); 

+     end else begin

+	ALUControl = 2'b00; // add for non-DP instructions

+	FlagW      = 2'b00; // don't update Flags

+     end

+   

+   // PC Logic

+   assign PCS  = ((Rd == 4'b1111) & RegW) | Branch;

+   

+endmodule // decoder

+

+module condlogic (input  logic       clk, reset,

+                  input  logic [3:0] Cond,

+                  input  logic [3:0] ALUFlags,

+                  input  logic [1:0] FlagW,

+                  input  logic       PCS, RegW, MemW,

+                  output logic       PCSrc, RegWrite, MemWrite);

+   

+   logic [1:0] 			     FlagWrite;

+   logic [3:0] 			     Flags;

+   logic 			     CondEx;

+

+   // Notice hard-coding of FFs to structurally model

+   flopenr #(2) flagreg1 (clk, reset, FlagWrite[1], 

+			  ALUFlags[3:2], Flags[3:2]);

+   flopenr #(2) flagreg0 (clk, reset, FlagWrite[0], 

+			  ALUFlags[1:0], Flags[1:0]);

+   

+   // write controls are conditional

+   condcheck cc (Cond, Flags, CondEx);

+   assign FlagWrite = FlagW & {2{CondEx}};

+   assign RegWrite  = RegW  & CondEx;

+   assign MemWrite  = MemW  & CondEx;

+   assign PCSrc     = PCS   & CondEx;

+   

+endmodule // condlogic

+

+module condcheck (input  logic [3:0] Cond,

+                  input  logic [3:0] Flags,

+                  output logic       CondEx);

+   

+   logic 			     neg, zero, carry, overflow, ge;

+   

+   assign {neg, zero, carry, overflow} = Flags;

+   assign ge = (neg == overflow);

+   

+   always_comb

+     case(Cond)

+       4'b0000: CondEx = zero;             // EQ

+       4'b0001: CondEx = ~zero;            // NE

+       4'b0010: CondEx = carry;            // CS

+       4'b0011: CondEx = ~carry;           // CC

+       4'b0100: CondEx = neg;              // MI

+       4'b0101: CondEx = ~neg;             // PL

+       4'b0110: CondEx = overflow;         // VS

+       4'b0111: CondEx = ~overflow;        // VC

+       4'b1000: CondEx = carry & ~zero;    // HI

+       4'b1001: CondEx = ~(carry & ~zero); // LS

+       4'b1010: CondEx = ge;               // GE

+       4'b1011: CondEx = ~ge;              // LT

+       4'b1100: CondEx = ~zero & ge;       // GT

+       4'b1101: CondEx = ~(~zero & ge);    // LE

+       4'b1110: CondEx = 1'b1;             // Always

+       default: CondEx = 1'bx;             // undefined

+     endcase // case (Cond)

+   

+endmodule // condcheck

+

+module datapath (input  logic        clk, reset,

+                 input  logic [2:0]  RegSrc,

+                 input  logic        RegWrite,

+                 input  logic [1:0]  ImmSrc,

+                 input  logic        ALUSrc,

+                 input  logic [1:0]  ALUControl,

+                 input  logic        MemtoReg,

+                 input  logic        PCSrc,

+                 output logic [3:0]  ALUFlags,

+                 output logic [31:0] PC,

+                 input  logic [31:0] Instr,

+                 output logic [31:0] ALUResult, WriteData,

+                 input  logic [31:0] ReadData);

+   

+   logic [31:0] 		     PCNext, PCPlus4, PCPlus8;

+   logic [31:0] 		     ExtImm, SrcA, SrcB, Result;

+   logic [3:0] 			     RA1, RA2, RA3;

+   logic [31:0] 		     RA4;   

+   

+   // next PC logic

+   mux2 #(32)  pcmux (PCPlus4, Result, PCSrc, PCNext);

+   flopr #(32) pcreg (clk, reset, PCNext, PC);

+   adder #(32) pcadd1 (PC, 32'b100, PCPlus4);

+   adder #(32) pcadd2 (PCPlus4, 32'b100, PCPlus8);

+

+   // register file logic

+   mux2 #(4)   ra1mux (Instr[19:16], 4'b1111, RegSrc[0], RA1);

+   mux2 #(4)   ra2mux (Instr[3:0], Instr[15:12], RegSrc[1], RA2);

+   mux2 #(4)   ra3mux (Instr[15:12], 4'hE, RegSrc[2], RA3);

+   mux2 #(32)  ra4mux (Result, PCPlus4, RegSrc[2], RA4);

+   

+   regfile     rf (clk, RegWrite, RA1, RA2,

+                   RA3, RA4, PCPlus8, 

+                   SrcA, WriteData); 

+   mux2 #(32)  resmux (ALUResult, ReadData, MemtoReg, Result);

+   extend      ext (Instr[23:0], ImmSrc, ExtImm);

+

+   // ALU logic

+   mux2 #(32)  srcbmux (WriteData, ExtImm, ALUSrc, SrcB);

+   alu         alu (SrcA, SrcB, ALUControl, 

+                    ALUResult, ALUFlags);

+endmodule // datapath

+

+module regfile (input  logic        clk, 

+		input  logic        we3, 

+		input  logic [3:0]  ra1, ra2, wa3, 

+		input  logic [31:0] wd3, r15,

+		output logic [31:0] rd1, rd2);

+   

+   logic [31:0] 		    rf[14:0];

+   

+   // three ported register file

+   // read two ports combinationally

+   // write third port on rising edge of clock

+   // register 15 reads PC+8 instead

+   

+   always_ff @(posedge clk)

+     if (we3) rf[wa3] <= wd3;	

+

+   assign rd1 = (ra1 == 4'b1111) ? r15 : rf[ra1];

+   assign rd2 = (ra2 == 4'b1111) ? r15 : rf[ra2];

+   

+endmodule // regfile

+

+module extend (input  logic [23:0] Instr,

+               input  logic [1:0]  ImmSrc,

+               output logic [31:0] ExtImm);

+   

+   always_comb

+     case(ImmSrc) 

+       // 8-bit unsigned immediate

+       2'b00:   ExtImm = {24'b0, Instr[7:0]};  

+       // 12-bit unsigned immediate 

+       2'b01:   ExtImm = {20'b0, Instr[11:0]}; 

+       // 24-bit two's complement shifted branch 

+       2'b10:   ExtImm = {{6{Instr[23]}}, Instr[23:0], 2'b00}; 

+       default: ExtImm = 32'bx; // undefined

+     endcase // case (ImmSrc)

+   

+endmodule // extend

+

+module adder #(parameter WIDTH=8)

+   (input  logic [WIDTH-1:0] a, b,

+    output logic [WIDTH-1:0] y);

+   

+   assign y = a + b;

+   

+endmodule // adder

+

+module flopenr #(parameter WIDTH = 8)

+   (input  logic             clk, reset, en,

+    input  logic [WIDTH-1:0] d, 

+    output logic [WIDTH-1:0] q);

+

+   always_ff @(posedge clk, negedge reset)

+     if (~reset)   q <= 0;

+     else if (en) q <= d;

+   

+endmodule // flopenr

+

+module flopr #(parameter WIDTH = 8)

+   (input  logic             clk, reset,

+    input  logic [WIDTH-1:0] d, 

+    output logic [WIDTH-1:0] q);

+

+   // Reset has start of .text

+   always_ff @(posedge clk, negedge reset)

+     if (~reset) q <= 0;

+     else   q <= d;

+   

+endmodule // flopr

+

+module mux2 #(parameter WIDTH = 8)

+   (input  logic [WIDTH-1:0] d0, d1, 

+    input  logic             s, 

+    output logic [WIDTH-1:0] y);

+

+   assign y = s ? d1 : d0;

+   

+endmodule // mux2

+

+module alu (input  logic [31:0] a, b,

+            input  logic [1:0]  ALUControl,

+            output logic [31:0] Result,

+            output logic [3:0]  ALUFlags);

+   

+   logic 			neg, zero, carry, overflow;

+   logic [31:0] 		condinvb;

+   logic [32:0] 		sum;

+   

+   assign condinvb = ALUControl[0] ? ~b : b;

+   assign sum = a + condinvb + ALUControl[0];

+

+   always_comb

+     casex (ALUControl[1:0])

+       2'b0?: Result = sum;

+       2'b10: Result = a & b;

+       2'b11: Result = a | b;

+     endcase

+

+   assign neg      = Result[31];

+   assign zero     = (Result == 32'b0);

+   assign carry    = (ALUControl[1] == 1'b0) & sum[32];

+   assign overflow = (ALUControl[1] == 1'b0) & 

+                     ~(a[31] ^ b[31] ^ ALUControl[0]) & 

+                     (a[31] ^ sum[31]); 

+   assign ALUFlags    = {neg, zero, carry, overflow};

+   

+endmodule // alu

diff --git a/flow/synth_snps/hdl/expcomp.sv b/flow/synth_snps/hdl/expcomp.sv
new file mode 100755
index 0000000..632da7f
--- /dev/null
+++ b/flow/synth_snps/hdl/expcomp.sv
@@ -0,0 +1,14 @@
+module expcomp (input logic [7:0] expa, expb,
+		output logic alessb,
+		output logic [7:0] exponent, shamt);
+
+   logic [7:0] 			  aminusb, bminusa;
+
+   assign aminusb = expa - expb;
+   assign bminusa = expb - expa;
+   assign alessb = aminusb[7];
+
+   assign exponent = alessb ? expb : expa;
+   assign shamt = alessb ? bminusa : aminusb;
+
+endmodule // expcomp
diff --git a/flow/synth_snps/hdl/fpadd.do b/flow/synth_snps/hdl/fpadd.do
new file mode 100755
index 0000000..1dc861f
--- /dev/null
+++ b/flow/synth_snps/hdl/fpadd.do
@@ -0,0 +1,60 @@
+# Copyright 1991-2007 Mentor Graphics Corporation
+# 
+# Modification by Oklahoma State University
+# Use with Testbench 
+# James Stine, 2008
+# Go Cowboys!!!!!!
+#
+# All Rights Reserved.
+#
+# THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION
+# WHICH IS THE PROPERTY OF MENTOR GRAPHICS CORPORATION
+# OR ITS LICENSORS AND IS SUBJECT TO LICENSE TERMS.
+
+# Use this run.do file to run this example.
+# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
+#     do run.do
+# or, to run from a shell, type the following at the shell prompt:
+#     vsim -do run.do -c
+# (omit the "-c" to see the GUI while running from the shell)
+
+onbreak {resume}
+
+# create library
+if [file exists work] {
+    vdel -all
+}
+vlib work
+
+# compile source files
+vlog addmant.sv expcomp.sv fpadd.sv shiftmant.sv tb.sv
+
+# start and run simulation
+vsim -novopt work.tb 
+
+view list
+view wave
+
+-- display input and output signals as hexidecimal values
+# Diplays All Signals recursively
+add wave -hex -r /tb/*
+
+# add list -hex -r /tb/*
+# add log -r /*
+
+-- Set Wave Output Items 
+TreeUpdate [SetDefaultTree]
+WaveRestoreZoom {0 ps} {75 ns}
+configure wave -namecolwidth 150
+configure wave -valuecolwidth 100
+configure wave -justifyvalue left
+configure wave -signalnamewidth 0
+configure wave -snapdistance 10
+configure wave -datasetprefix 0
+configure wave -rowmargin 4
+configure wave -childrowmargin 2
+
+-- Run the Simulation
+run 300ns
+
+
diff --git a/flow/synth_snps/hdl/fpadd.sv b/flow/synth_snps/hdl/fpadd.sv
new file mode 100755
index 0000000..7f8626f
--- /dev/null
+++ b/flow/synth_snps/hdl/fpadd.sv
@@ -0,0 +1,20 @@
+module fpadd (input logic [31:0] a, b,
+	      output logic [31:0] s);
+
+   logic [7:0] 			 expa, expb, exp_pre, exponent, shamt;
+   logic 			 alessb;
+   logic [23:0] 		 manta, mantb, shmant;
+   logic [22:0] 		 fract;
+
+   assign {expa, manta} = {a[30:23], 1'b1, a[22:0]};
+   assign {expb, mantb} = {b[30:23], 1'b1, b[22:0]};
+   assign s = {1'b0, exponent, fract};
+
+   expcomp expcomp1 (expa, expb, alessb, exp_pre,
+		     shamt);
+   shiftmant shiftmant1 (alessb, manta, mantb,
+			 shamt, shmant);
+   addmant addmant1 (alessb, manta, mantb,
+		     shmant, exp_pre, fract, exponent);
+
+endmodule // fpadd
diff --git a/flow/synth_snps/hdl/fpmult.sv b/flow/synth_snps/hdl/fpmult.sv
new file mode 100755
index 0000000..8d740da
--- /dev/null
+++ b/flow/synth_snps/hdl/fpmult.sv
@@ -0,0 +1,21 @@
+module fpmult (input logic [31:0] a, b,
+	       output logic [31:0] m);
+
+   logic [7:0] 			  expa, expb, exp;
+   logic [23:0] 		  manta, mantb;
+   logic [22:0] 		  fract;
+   logic [47:0] 		  result;
+
+   assign {expa, manta} = {a[30:23], 1'b1, a[22:0]};
+   assign {expb, mantb} = {b[30:23], 1'b1, b[22:0]};
+   assign m = {1'b0, exp, fract};
+
+   assign result = manta * mantb;
+   assign fract = result[47] ?
+		  result[46:24] :
+		  result[45:23];
+   assign exp = result[47] ?
+		(expa + expb - 126) :
+		(expa + expb - 127);
+
+endmodule // fpmult
diff --git a/flow/synth_snps/hdl/shiftmant.sv b/flow/synth_snps/hdl/shiftmant.sv
new file mode 100755
index 0000000..c827012
--- /dev/null
+++ b/flow/synth_snps/hdl/shiftmant.sv
@@ -0,0 +1,15 @@
+module shiftmant (input logic alessb,
+		  input logic [23:0] manta, mantb,
+		  input logic [7:0] shamt,
+		  output logic [23:0] shmant);
+   
+   logic [23:0] 		      shiftedval;
+   logic 			      ovf;   
+
+   assign shiftedval = alessb ?
+		       (manta >> shamt) : (mantb >> shamt);
+   assign ovf = (shamt[7] | shamt[6] | shamt[5] |
+		 (shamt[4] & shamt[3]));
+   assign shmant = ovf ? 24'h0 : shiftedval;
+
+endmodule // shiftmant
diff --git a/flow/synth_snps/hdl/tb.sv b/flow/synth_snps/hdl/tb.sv
new file mode 100755
index 0000000..ee74975
--- /dev/null
+++ b/flow/synth_snps/hdl/tb.sv
@@ -0,0 +1,42 @@
+module tb;
+
+   logic [31:0] a, b;   
+   logic [31:0] s;
+   
+   logic 	clk;
+   integer 	handle3;
+   integer 	desc3;
+
+   fpadd dut (a, b, s);
+   
+   initial 
+     begin	
+	clk = 1'b1;
+	forever #5 clk = ~clk;
+     end
+
+   initial
+     begin
+	handle3 = $fopen("tb.out");
+	#700 $finish;		
+     end
+
+   always 
+     begin
+	desc3 = handle3;
+	#5 $fdisplay(desc3, "%h %h | %h", a, b, s);
+     end
+
+   initial
+     begin
+	#0  a = 32'h3F75_0000;
+	#0  b = 32'h3FC0_0000;		
+     end
+
+endmodule // tb
+
+
+
+
+
+
diff --git a/flow/synth_snps/hdl/testfp b/flow/synth_snps/hdl/testfp
new file mode 100755
index 0000000..659f6b8
--- /dev/null
+++ b/flow/synth_snps/hdl/testfp
Binary files differ
diff --git a/flow/synth_snps/hdl/testfp.c b/flow/synth_snps/hdl/testfp.c
new file mode 100755
index 0000000..9722924
--- /dev/null
+++ b/flow/synth_snps/hdl/testfp.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+union f {
+  unsigned short x[2];
+  float y;
+} a, b, c;
+
+int main() {
+  
+  a.x[1] = 0x3F75;
+  a.x[0] = 0x0000;
+  b.x[1] = 0x3FC0;
+  b.x[0] = 0x0000;
+
+  c.y = a.y + b.y;
+
+  printf("%.5e %.5e = %.5e\n", a.y, b.y, c.y);
+  printf("\n");
+  printf("a = %.4x%.4x \n", a.x[1], a.x[0]);
+  printf("b = %.4x%.4x \n", b.x[1], b.x[0]);
+  printf("c = %.4x%.4x \n", c.x[1], c.x[0]);
+
+}
+
diff --git a/flow/synth_snps/scripts/multGen/array8x8.v b/flow/synth_snps/scripts/multGen/array8x8.v
new file mode 100755
index 0000000..0ceee43
--- /dev/null
+++ b/flow/synth_snps/scripts/multGen/array8x8.v
@@ -0,0 +1,176 @@
+
+// Correction constant value: 0 (0000000000000000)
+
+module mult (Z2, X, Y);
+	
+	input [7:0] Y;
+	input [7:0] X;
+	output [15:0] Z2;
+
+
+	wire [7:0] P0;
+	wire [7:0] carry1;
+	wire [7:0] sum1;
+	wire [7:0] P1;
+	wire [7:0] carry2;
+	wire [7:0] sum2;
+	wire [7:0] P2;
+	wire [7:0] carry3;
+	wire [7:0] sum3;
+	wire [7:0] P3;
+	wire [7:0] carry4;
+	wire [7:0] sum4;
+	wire [7:0] P4;
+	wire [7:0] carry5;
+	wire [7:0] sum5;
+	wire [7:0] P5;
+	wire [7:0] carry6;
+	wire [7:0] sum6;
+	wire [7:0] P6;
+	wire [7:0] carry7;
+	wire [7:0] sum7;
+	wire [7:0] P7;
+	wire [7:0] carry8;
+	wire [7:0] sum8;
+	wire [14:0] carry9;
+	wire [15:0] Z;
+
+
+	// generate the partial products.
+	and pp1(P0[7], X[7], Y[0]);
+	and pp2(P0[6], X[6], Y[0]);
+	and pp3(P0[5], X[5], Y[0]);
+	and pp4(P0[4], X[4], Y[0]);
+	and pp5(P0[3], X[3], Y[0]);
+	and pp6(P0[2], X[2], Y[0]);
+	and pp7(P0[1], X[1], Y[0]);
+	and pp8(P0[0], X[0], Y[0]);
+	and pp9(sum1[7], X[7], Y[1]);
+	and pp10(P1[6], X[6], Y[1]);
+	and pp11(P1[5], X[5], Y[1]);
+	and pp12(P1[4], X[4], Y[1]);
+	and pp13(P1[3], X[3], Y[1]);
+	and pp14(P1[2], X[2], Y[1]);
+	and pp15(P1[1], X[1], Y[1]);
+	and pp16(P1[0], X[0], Y[1]);
+	and pp17(sum2[7], X[7], Y[2]);
+	and pp18(P2[6], X[6], Y[2]);
+	and pp19(P2[5], X[5], Y[2]);
+	and pp20(P2[4], X[4], Y[2]);
+	and pp21(P2[3], X[3], Y[2]);
+	and pp22(P2[2], X[2], Y[2]);
+	and pp23(P2[1], X[1], Y[2]);
+	and pp24(P2[0], X[0], Y[2]);
+	and pp25(sum3[7], X[7], Y[3]);
+	and pp26(P3[6], X[6], Y[3]);
+	and pp27(P3[5], X[5], Y[3]);
+	and pp28(P3[4], X[4], Y[3]);
+	and pp29(P3[3], X[3], Y[3]);
+	and pp30(P3[2], X[2], Y[3]);
+	and pp31(P3[1], X[1], Y[3]);
+	and pp32(P3[0], X[0], Y[3]);
+	and pp33(sum4[7], X[7], Y[4]);
+	and pp34(P4[6], X[6], Y[4]);
+	and pp35(P4[5], X[5], Y[4]);
+	and pp36(P4[4], X[4], Y[4]);
+	and pp37(P4[3], X[3], Y[4]);
+	and pp38(P4[2], X[2], Y[4]);
+	and pp39(P4[1], X[1], Y[4]);
+	and pp40(P4[0], X[0], Y[4]);
+	and pp41(sum5[7], X[7], Y[5]);
+	and pp42(P5[6], X[6], Y[5]);
+	and pp43(P5[5], X[5], Y[5]);
+	and pp44(P5[4], X[4], Y[5]);
+	and pp45(P5[3], X[3], Y[5]);
+	and pp46(P5[2], X[2], Y[5]);
+	and pp47(P5[1], X[1], Y[5]);
+	and pp48(P5[0], X[0], Y[5]);
+	and pp49(sum6[7], X[7], Y[6]);
+	and pp50(P6[6], X[6], Y[6]);
+	and pp51(P6[5], X[5], Y[6]);
+	and pp52(P6[4], X[4], Y[6]);
+	and pp53(P6[3], X[3], Y[6]);
+	and pp54(P6[2], X[2], Y[6]);
+	and pp55(P6[1], X[1], Y[6]);
+	and pp56(P6[0], X[0], Y[6]);
+	and pp57(sum7[7], X[7], Y[7]);
+	and pp58(P7[6], X[6], Y[7]);
+	and pp59(P7[5], X[5], Y[7]);
+	and pp60(P7[4], X[4], Y[7]);
+	and pp61(P7[3], X[3], Y[7]);
+	and pp62(P7[2], X[2], Y[7]);
+	and pp63(P7[1], X[1], Y[7]);
+	and pp64(P7[0], X[0], Y[7]);
+
+// FAILED TO OPTIMIZE THE CORRECTION!
+	// Array Reduction
+	half_adder  HA1(carry1[6],sum1[6],P1[6],P0[7]);
+	half_adder  HA2(carry1[5],sum1[5],P1[5],P0[6]);
+	half_adder  HA3(carry1[4],sum1[4],P1[4],P0[5]);
+	half_adder  HA4(carry1[3],sum1[3],P1[3],P0[4]);
+	half_adder  HA5(carry1[2],sum1[2],P1[2],P0[3]);
+	half_adder  HA6(carry1[1],sum1[1],P1[1],P0[2]);
+	half_adder  HA7(carry1[0],sum1[0],P1[0],P0[1]);
+	full_adder  FA1(carry2[6],sum2[6],P2[6],sum1[7],carry1[6]);
+	full_adder  FA2(carry2[5],sum2[5],P2[5],sum1[6],carry1[5]);
+	full_adder  FA3(carry2[4],sum2[4],P2[4],sum1[5],carry1[4]);
+	full_adder  FA4(carry2[3],sum2[3],P2[3],sum1[4],carry1[3]);
+	full_adder  FA5(carry2[2],sum2[2],P2[2],sum1[3],carry1[2]);
+	full_adder  FA6(carry2[1],sum2[1],P2[1],sum1[2],carry1[1]);
+	full_adder  FA7(carry2[0],sum2[0],P2[0],sum1[1],carry1[0]);
+	full_adder  FA8(carry3[6],sum3[6],P3[6],sum2[7],carry2[6]);
+	full_adder  FA9(carry3[5],sum3[5],P3[5],sum2[6],carry2[5]);
+	full_adder  FA10(carry3[4],sum3[4],P3[4],sum2[5],carry2[4]);
+	full_adder  FA11(carry3[3],sum3[3],P3[3],sum2[4],carry2[3]);
+	full_adder  FA12(carry3[2],sum3[2],P3[2],sum2[3],carry2[2]);
+	full_adder  FA13(carry3[1],sum3[1],P3[1],sum2[2],carry2[1]);
+	full_adder  FA14(carry3[0],sum3[0],P3[0],sum2[1],carry2[0]);
+	full_adder  FA15(carry4[6],sum4[6],P4[6],sum3[7],carry3[6]);
+	full_adder  FA16(carry4[5],sum4[5],P4[5],sum3[6],carry3[5]);
+	full_adder  FA17(carry4[4],sum4[4],P4[4],sum3[5],carry3[4]);
+	full_adder  FA18(carry4[3],sum4[3],P4[3],sum3[4],carry3[3]);
+	full_adder  FA19(carry4[2],sum4[2],P4[2],sum3[3],carry3[2]);
+	full_adder  FA20(carry4[1],sum4[1],P4[1],sum3[2],carry3[1]);
+	full_adder  FA21(carry4[0],sum4[0],P4[0],sum3[1],carry3[0]);
+	full_adder  FA22(carry5[6],sum5[6],P5[6],sum4[7],carry4[6]);
+	full_adder  FA23(carry5[5],sum5[5],P5[5],sum4[6],carry4[5]);
+	full_adder  FA24(carry5[4],sum5[4],P5[4],sum4[5],carry4[4]);
+	full_adder  FA25(carry5[3],sum5[3],P5[3],sum4[4],carry4[3]);
+	full_adder  FA26(carry5[2],sum5[2],P5[2],sum4[3],carry4[2]);
+	full_adder  FA27(carry5[1],sum5[1],P5[1],sum4[2],carry4[1]);
+	full_adder  FA28(carry5[0],sum5[0],P5[0],sum4[1],carry4[0]);
+	full_adder  FA29(carry6[6],sum6[6],P6[6],sum5[7],carry5[6]);
+	full_adder  FA30(carry6[5],sum6[5],P6[5],sum5[6],carry5[5]);
+	full_adder  FA31(carry6[4],sum6[4],P6[4],sum5[5],carry5[4]);
+	full_adder  FA32(carry6[3],sum6[3],P6[3],sum5[4],carry5[3]);
+	full_adder  FA33(carry6[2],sum6[2],P6[2],sum5[3],carry5[2]);
+	full_adder  FA34(carry6[1],sum6[1],P6[1],sum5[2],carry5[1]);
+	full_adder  FA35(carry6[0],sum6[0],P6[0],sum5[1],carry5[0]);
+	full_adder  FA36(carry7[6],sum7[6],P7[6],sum6[7],carry6[6]);
+	full_adder  FA37(carry7[5],sum7[5],P7[5],sum6[6],carry6[5]);
+	full_adder  FA38(carry7[4],sum7[4],P7[4],sum6[5],carry6[4]);
+	full_adder  FA39(carry7[3],sum7[3],P7[3],sum6[4],carry6[3]);
+	full_adder  FA40(carry7[2],sum7[2],P7[2],sum6[3],carry6[2]);
+	full_adder  FA41(carry7[1],sum7[1],P7[1],sum6[2],carry6[1]);
+	full_adder  FA42(carry7[0],sum7[0],P7[0],sum6[1],carry6[0]);
+
+	// Generate lower product bits YBITS 
+	buf b1(Z2[0], P0[0]);
+	assign Z2[1] = sum1[0];
+	assign Z2[2] = sum2[0];
+	assign Z2[3] = sum3[0];
+	assign Z2[4] = sum4[0];
+	assign Z2[5] = sum5[0];
+	assign Z2[6] = sum6[0];
+	assign Z2[7] = sum7[0];
+
+	// Final Carry Propagate Addition
+	//   Generate higher product bits
+	half_adder CPA1(carry8[0],Z2[8],carry7[0],sum7[1]);
+	full_adder CPA2(carry8[1],Z2[9],carry7[1],carry8[0],sum7[2]);
+	full_adder CPA3(carry8[2],Z2[10],carry7[2],carry8[1],sum7[3]);
+	full_adder CPA4(carry8[3],Z2[11],carry7[3],carry8[2],sum7[4]);
+	full_adder CPA5(carry8[4],Z2[12],carry7[4],carry8[3],sum7[5]);
+	full_adder CPA6(carry8[5],Z2[13],carry7[5],carry8[4],sum7[6]);
+	full_adder CPA7(Z2[15],Z2[14],carry7[6],carry8[5],sum7[7]);
+endmodule
\ No newline at end of file
diff --git a/flow/synth_snps/scripts/multGen/array_v_CCT.pl b/flow/synth_snps/scripts/multGen/array_v_CCT.pl
new file mode 100755
index 0000000..d51bb2b
--- /dev/null
+++ b/flow/synth_snps/scripts/multGen/array_v_CCT.pl
@@ -0,0 +1,535 @@
+eval 'exec /usr/bin/perl $0 ${1+"${@}"}'
+    if 0;
+  
+# Perl script to generate truncated array multiplier (Constant Correction)
+# Last update: 08/23/02
+   
+use Getopt::Std;
+    
+# options are
+#       -x <bits> the number of x bits
+#       -y <bits> the number of y bits
+#       -z <bits> the number of output bits
+#       -k <int> number of columns to keep
+#       -m <string> module name
+     
+getopts('x:y:z:k:m:');
+
+$XBITS=$opt_x;
+$YBITS=$opt_y;
+$ZBITS=$opt_z;
+$K=$opt_k;
+$MODULE=$opt_m;
+
+if($XBITS<=0 || $YBITS<=0 || $ZBITS<=0 || $K<0){
+    print("Input parameters:\n");
+    print("    -x <bits> the number of x bits\n");
+    print("    -y <bits> the number of y bits\n");
+    print("    -z <bits> the number of output bits\n");
+    print("    -k <int> number of columns to keep\n");
+    print("    -m <string> module name (optional)\n");
+    exit(1);
+}
+
+if($ZBITS+$K>$XBITS+$YBITS) {    
+    print("Error: z+k must be smaller than or equal to x+y\n\n");
+    exit(1);
+}
+
+$pp_label=1;
+$ha_label=1;
+$fa_label=1;
+$cpa_label=1;
+       
+$instcnt=1;
+
+# Calculation of the correction constant
+# --------------------------------------
+$err_red = 0;
+for($q = $ZBITS+$K+1; $q <= $XBITS+$YBITS; $q++) {
+    $err_red += ($XBITS+$YBITS+1-$q)/&pow2($q);  # reduction error
+#    printf("%s  %s  %s  %s\n",$q,&pow2($q),$err_red,$XBITS+$YBITS+1-$q);
+}
+$err_rnd = 1/pow2($ZBITS)*(1 - 1/&pow2($K));  # rounding error
+$err_tot = 0.25*$err_red + 0.5*$err_rnd;
+printf("\n// Correction constant value: %s (",$err_tot);
+
+# Rounding of that constant
+$err_tot_rnd = $err_tot * &pow2($ZBITS+$K);
+$err_tot_rnd = &round_near($err_tot_rnd);
+$err_tot_rnd = $err_tot_rnd / &pow2($ZBITS+$K);
+
+# Conversion into binary format
+@carray;
+$rem = $err_tot_rnd;
+for($j=1;$j<=$ZBITS+$K;$j++){
+    $mod = $rem *  &pow2($j);
+    if($mod>=1){
+        $rem = $rem - 1/&pow2($j);
+        @carray[$XBITS+$YBITS-$j] = 1;
+    }
+    else{
+        @carray[$XBITS+$YBITS-$j] = 0;
+    }
+}
+
+# Display the value of the constant correction
+for($j=$XBITS+$YBITS-1;$j>=$XBITS+$YBITS-$ZBITS-$K;$j--){
+    printf("%s",@carray[$j]);
+}
+printf(")\n\n");
+
+# Calculation of the number of bits required for the constant correction
+# ----------------------------------------------------------------------
+$nbitscon=0;
+for($j=$XBITS+$YBITS-$ZBITS-$K;$j<$XBITS+$YBITS;$j++){
+    $nbitscon += @carray[$j]*&pow2($j-($XBITS+$YBITS-$ZBITS-$K));
+}
+
+# calculation of which partial products have to be generated
+# ----------------------------------------------------------
+if($XBITS<$ZBITS+$K){
+    $x_pp_size=$XBITS;
+    $h_pp_size=$K+$ZBITS-$XBITS;
+}
+else{
+    $x_pp_size=$ZBITS+$K;
+    $h_pp_size=0;
+}
+if($YBITS<=$ZBITS+$K){
+    $y_pp_size=$YBITS;
+}
+else{
+    $y_pp_size=$ZBITS+$K-1;
+}
+
+# Calculation of the number of bits available for correction
+# (number of HA located on the diagonal and on the second line)
+# -------------------------------------------------------------
+$nha=0;
+$nhadiag=0;
+for($y=$YBITS-$y_pp_size; $y < $YBITS ; $y++) {
+    for($x=$XBITS-2; $x >= $XBITS-$x_pp_size; $x--) {
+        if($x+$y>=$XBITS+$YBITS-$ZBITS-$K){
+            if($y==$YBITS-$y_pp_size+1){
+                $nha++;
+            }
+        }
+        if($x+$y==$XBITS+$YBITS-$ZBITS-$K && $y>$YBITS-$y_pp_size+1){
+            $nhadiag++;
+        }
+    }
+}
+
+# Check if the constant correction can be done
+# --------------------------------------------
+$sum_max=$nhadiag;
+for($i=0;$i<$nha;$i++){
+    $sum_max += &pow2($i);   
+}
+$sum_req=$nbitscon;
+if($sum_req>$sum_max || ($XBITS+$YBITS==$ZBITS+$K && @carray[$XBITS+$YBITS-$ZBITS-$K]==1)){
+    $optimize=0;
+}
+else{
+    $optimize=1;
+}
+
+# Write the header of the verilog file (variables definition)
+# -----------------------------------------------------------
+if(length($MODULE)==0){
+    printf("module CCTarray%s_%s_%s_%s (Z2, X, Y);\n", $XBITS, $YBITS, $ZBITS, $K);
+}
+else{
+    printf("module $MODULE (Z2, X, Y);\n", $XBITS, $YBITS, $ZBITS, $K);
+}
+printf("\t\n");
+printf("\tinput [%s:0] Y;\n",$YBITS-1);
+printf("\tinput [%s:0] X;\n",$XBITS-1);
+printf("\toutput [%s:0] Z2;\n",$ZBITS-1);
+printf("\n\n");
+for($y=0; $y < $YBITS ; $y++) {
+    printf("\twire [%s:0] P%s;\n", $XBITS-1, $y);
+    printf("\twire [%s:0] carry%s;\n", $XBITS-1, $y+1);
+    printf("\twire [%s:0] sum%s;\n", $XBITS-1, $y+1);
+}
+printf("\twire [%s:0] carry%s;\n",$ZBITS+$K-2,$YBITS+1);
+printf("\twire [%s:0] Z;\n",$ZBITS+$K-1);
+print "\n\n";
+
+# Generate the partial products
+# -----------------------------
+print "\t// generate the partial products.\n";
+for($y=$YBITS-$y_pp_size; $y < $YBITS ; $y++) {
+    for($x=$XBITS-1; $x >= $XBITS-$x_pp_size; $x--) {
+        if($x+$y>=$XBITS+$YBITS-$ZBITS-$K){
+	    if($y>$YBITS-$y_pp_size && $x==$XBITS-1) {
+	        printf ("\tand pp%s(sum%s[%s], X[%s], Y[%s]);\n", $pp_label, $y, $x, $x, $y);
+	        $pp_label++;
+	    }
+	    else {
+	        printf ("\tand pp%s(P%s[%s], X[%s], Y[%s]);\n", $pp_label, $y, $x, $x, $y);
+	        $pp_label++;
+	    }
+	}
+    }
+}
+print "\n";
+
+# $optimize=0;
+if($optimize==0 || $XBITS+$YBITS==$ZBITS){
+    goto NO_OPTIMIZE;
+}
+
+# Array Reduction
+# ---------------
+$nbitsvarused=0;
+$nbitsconused=0;
+print "\t// Array Reduction\n";
+for($y=$YBITS-$y_pp_size; $y < $YBITS ; $y++) {
+    for($x=$XBITS-2; $x >= $XBITS-$x_pp_size; $x--) {
+        if($x+$y>=$XBITS+$YBITS-$ZBITS-$K){
+            if($y==$YBITS-$y_pp_size+1){
+                if($nbitsconused+&pow2($x-($XBITS+$YBITS-$ZBITS-$K-$y))<=$nbitscon){
+                    if($K>=2 && $x==0){
+                        printf("\tassign carry%s[%s] = P%s[%s] & P%s[%s];\n",$y,$x,$y,$x,$y-1,$x+1);
+                        $nbitsconused++;
+                    }
+                    else{
+                        printf("\tspecialized_half_adder  SHA%s(carry%s[%s],sum%s[%s],P%s[%s],P%s[%s]);\n",$sha_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1);
+                        $sha_label++;
+                        $nbitsconused += &pow2($x-($XBITS+$YBITS-$ZBITS-$K-$y));
+                    }
+                }
+                else{
+                    if($K>=2 && $x==0){
+                        printf("\tassign carry%s[%s] = P%s[%s] | P%s[%s];\n",$y,$x,$y,$x,$y-1,$x+1);
+                    }
+                    else{
+                        printf("\thalf_adder  HA%s(carry%s[%s],sum%s[%s],P%s[%s],P%s[%s]);\n",$ha_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1);
+                        $ha_label++;
+                    }
+                }
+            }
+            if($y>$YBITS-$y_pp_size+1){
+                if($x+$y==$XBITS+$YBITS-$ZBITS-$K){
+                    if($nbitsconused<$nbitscon){
+                        if($x==0 && $y<$YBITS-$h_pp_size+$K){
+                            printf("\tassign carry%s[%s] = P%s[%s] | sum%s[%s];\n",$y,$x,$y,$x,$y-1,$x+1);
+                            $nbitsconused++;
+                        }
+                        else{
+                            printf("\tspecialized_half_adder  SHA%s(carry%s[%s],sum%s[%s],P%s[%s],sum%s[%s]);\n",$sha_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1);
+                            $sha_label++;
+                            $nbitsconused++;
+                        }
+                    }
+                    else{
+                        if($x==0 && $y<$YBITS-$h_pp_size+$K){
+                            printf("\tassign carry%s[%s] = P%s[%s] & sum%s[%s];\n",$y,$x,$y,$x,$y-1,$x+1);
+                        }
+                        else{
+                            printf("\thalf_adder  HA%s(carry%s[%s],sum%s[%s],P%s[%s],sum%s[%s]);\n",$ha_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1);
+                            $ha_label++;
+                        }
+                    }
+                }       
+                else{
+                    if($x==0 && $y<$YBITS-$h_pp_size+$K){
+                        printf("\treduced_full_adder  RFA%s(carry%s[%s],P%s[%s],sum%s[%s],carry%s[%s]);\n",$rfa_label,$y,$x,$y,$x,$y-1,$x+1,$y-1,$x);
+                        $rfa_label++;
+                    }
+                    else{
+                        printf("\tfull_adder  FA%s(carry%s[%s],sum%s[%s],P%s[%s],sum%s[%s],carry%s[%s]);\n",$fa_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1,$y-1,$x);
+                        $fa_label++;
+                    }
+                }
+            }
+        }
+    }
+}
+print "\n";
+# Generate lower order product
+print "\t// Generate lower product bits YBITS \n";
+$Zpin=0;
+if($ZBITS>$XBITS){
+    for($y=$YBITS+$XBITS-$ZBITS; $y < $YBITS ; $y++){
+        if($y==0){
+            printf("\tbuf b1(Z2[0], P0[0]);\n");
+            $Zpin++;
+        }
+        else{
+            printf ("\tassign Z2[%s] = sum%s[0];\n",$Zpin,$y);
+            $Zpin++;
+        }
+    }
+}
+print "\n";
+# Generate higher order product
+print "\t// Final Carry Propagate Addition\n";
+print "\t//   Generate higher product bits\n";
+if($ZBITS>$XBITS){
+    $nhop=$XBITS;
+}
+else{
+    $nhop=$ZBITS;
+}
+if($ZBITS+$K>$XBITS){
+    $xstart=0;
+}
+else{
+    $xstart=$XBITS-$ZBITS-$K;;
+}
+for($x=$xstart; $x < $XBITS ; $x++) {
+    if($x==$xstart) {
+        if($x==$XBITS-$nhop){
+            if($ZBITS+$K>$XBITS){
+                printf("\thalf_adder CPA%s(carry%s[%s],Z2[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$Zpin,$YBITS-1,$x,$YBITS-1,$x+1);
+                $cpa_label++;
+            }
+            else{
+                printf("\tassign carry%s[%s] = 0;\n",$YBITS,$x);
+                printf("\tassign Z2[%s] = sum%s[%s];\n",$Zpin,$YBITS-1,$x+1);
+            }
+            $Zpin++;
+        }
+        else{
+            if($ZBITS+$K>$XBITS){
+                printf("\tassign carry%s[%s] = carry%s[%s] & sum%s[%s];\n",$YBITS,$x,$YBITS-1,$x,$YBITS-1,$x+1);
+            }
+            else{
+                printf("\tassign carry%s[%s] = 0;\n",$YBITS,$x);
+            }
+        }                 
+    }
+    else{
+        if($x==$XBITS-2) {
+            printf("\tfull_adder CPA%s(Z2[%s],Z2[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$Zpin+1,$Zpin,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+        }
+        else{
+            if($x>=$XBITS-$nhop && $x<$XBITS-2) {
+                printf("\tfull_adder CPA%s(carry%s[%s],Z2[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$Zpin,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+                $cpa_label++;
+                $Zpin++;
+            }
+            if($x<$XBITS-$nhop && $x>$xstart && $x<$XBITS-2){
+                printf("\treduced_full_adder CPA%s(carry%s[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+                $cpa_label++;      
+            } 
+        }
+    }
+}
+goto END;
+
+NO_OPTIMIZE: printf("// FAILED TO OPTIMIZE THE CORRECTION!\n");
+# Array Reduction
+# ---------------
+print "\t// Array Reduction\n";
+for($y=$YBITS-$y_pp_size; $y < $YBITS ; $y++) {
+    for($x=$XBITS-2; $x >= $XBITS-$x_pp_size; $x--) {
+        if($x+$y>=$XBITS+$YBITS-$ZBITS-$K){
+            if($y==$YBITS-$y_pp_size+1){
+	        printf("\thalf_adder  HA%s(carry%s[%s],sum%s[%s],P%s[%s],P%s[%s]);\n",$ha_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1);
+	        $ha_label++;
+	    }
+	    if($y>$YBITS-$y_pp_size+1){
+                if($x+$y==$XBITS+$YBITS-$ZBITS-$K){
+	            printf("\thalf_adder  HA%s(carry%s[%s],sum%s[%s],P%s[%s],sum%s[%s]);\n",$ha_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1);
+	            $ha_label++;
+		}	    
+	        else{
+	            printf("\tfull_adder  FA%s(carry%s[%s],sum%s[%s],P%s[%s],sum%s[%s],carry%s[%s]);\n",$fa_label,$y,$x,$y,$x,$y,$x,$y-1,$x+1,$y-1,$x);
+	            $fa_label++;
+	        }
+	    }
+	}
+    }
+}
+
+
+print "\n";
+if($XBITS+$YBITS>$ZBITS){
+    # Generate lower order product
+    print "\t// Generate lower product bits YBITS \n";
+    $Zpin=0;
+    if($ZBITS+$K>$XBITS){
+        for($y=$YBITS-$ZBITS-$K+$XBITS; $y < $YBITS ; $y++){
+            if($y==0){
+                printf("\tbuf b1(Z[0], P0[0]);\n");
+                $Zpin++;
+	    }
+            else{
+                printf ("\tassign Z[%s] = sum%s[0];\n",$Zpin,$y);
+                $Zpin++;
+            }
+        }
+    }
+    print "\n";
+    # Generate higher order product
+    print "\t// Final Carry Propagate Addition\n";
+    print "\t//   Generate higher product bits\n";
+    if($ZBITS+$K>$XBITS){
+        $nhop=$XBITS;
+    }
+    else{
+        $nhop=$ZBITS+$K;
+    }
+    for($x=$XBITS-$nhop; $x < $XBITS ; $x++) {
+        if($x==$XBITS-$nhop) {
+            if($ZBITS+$K>$XBITS){
+	        printf("\thalf_adder CPA%s(carry%s[%s],Z[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$Zpin,$YBITS-1,$x,$YBITS-1,$x+1);
+            }
+	    else{
+	        printf("\tassign carry%s[%s] = 0;\n",$YBITS,$x);
+                printf("\tassign Z[%s] = sum%s[%s];\n",$Zpin,$YBITS-1,$x+1);
+	    }
+            $cpa_label++;
+            $Zpin++;
+        }
+        if($x==$XBITS-2) {
+	    printf("\tfull_adder CPA%s(Z[%s],Z[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$Zpin+1,$Zpin,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+            $cpa_label++;
+            $Zpin++;
+        }			
+        if($x>$XBITS-$nhop && $x<$XBITS-2) {
+            printf("\tfull_adder CPA%s(carry%s[%s],Z[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$Zpin,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+            $cpa_label++;
+            $Zpin++;	
+        }
+    }
+
+
+    print "\n";
+    # Add the constant to the sum previously calculated
+    print "\t// Add the constant\n";
+    for($x=0;$x<$ZBITS+$K;$x++){
+        if($x==0) {
+            if(@carray[$XBITS+$YBITS-$ZBITS-$K+$x]==0){
+                if($K==0){
+                    printf("\tassign Z2[%s] = Z[%s];\n",$x,$x);
+                }
+                printf("\tassign carry%s[%s] = 0;\n",$YBITS+1,$x);
+	    }
+            else{
+                if($K==0){
+                    printf("\tassign Z2[%s] = !Z[%s];\n",$x,$x);
+                }
+                printf("\tassign carry%s[%s] = Z[%s];\n",$YBITS+1,$x,$x);
+            }
+        }
+        if($x==$ZBITS+$K-1) {
+            if(@carray[$XBITS+$YBITS-$ZBITS-$K+$x]==0){
+                printf("\tassign Z2[%s] = Z[%s] ^ carry%s[%s];\n",$x-$K,$x,$YBITS+1,$x-1);
+            }
+	    else{
+                printf("\tassign Z2[%s] = !Z[%s] ^ carry%s[%s];\n",$x-$K,$x,$YBITS+1,$x-1);    
+            }
+	    $cpa_label++;
+        }			
+        if($x>0 && $x<$ZBITS+$K-1) {
+            if($x>=$K){
+                if(@carray[$XBITS+$YBITS-$ZBITS-$K+$x]==0){
+                    printf("\thalf_adder CPA%s(carry%s[%s],Z2[%s],Z[%s],carry%s[%s]);\n",$cpa_label,$YBITS+1,$x,$x-$K,$x,$YBITS+1,$x-1);
+                }
+	        else{
+                    printf("\tspecialized_half_adder CPA%s(carry%s[%s],Z2[%s],Z[%s],carry%s[%s]);\n",$cpa_label,$YBITS+1,$x,$x-$K,$x,$YBITS+1,$x-1);            
+                }
+            }
+	    else{
+	        if(@carray[$XBITS+$YBITS-$ZBITS-$K+$x]==0){
+                    printf("\tand CPA%s(carry%s[%s],Z[%s],carry%s[%s]);\n",$cpa_label,$YBITS+1,$x,$x,$YBITS+1,$x-1);
+                }
+                else{
+                    printf("\tor CPA%s(carry%s[%s],Z[%s],carry%s[%s]);\n",$cpa_label,$YBITS+1,$x,$x,$YBITS+1,$x-1);
+                }
+            }
+	    $cpa_label++;
+        }
+    }
+}
+else{   # if $XBITS+$YBITS=$ZBITS
+    # Generate lower order product
+    print "\t// Generate lower product bits YBITS \n";
+    $Zpin=0;
+    if($ZBITS>$XBITS){
+        for($y=$YBITS-$ZBITS+$XBITS; $y < $YBITS ; $y++){
+            if($y==0){
+                printf("\tbuf b1(Z2[0], P0[0]);\n");
+                $Zpin++;
+	    }
+	    else{
+                printf ("\tassign Z2[%s] = sum%s[0];\n",$Zpin,$y);
+                $Zpin++;
+	    }
+        }
+    }
+    print "\n";
+    # Generate higher order product
+    print "\t// Final Carry Propagate Addition\n";
+    print "\t//   Generate higher product bits\n";
+    if($ZBITS>$XBITS){
+        $nhop=$XBITS;
+    }
+    else{
+        $nhop=$ZBITS;
+    }
+    if($XBITS-$ZBITS-$K>0){
+        $xstart=$XBITS-$ZBITS-$K;
+    }
+    else{
+        $xstart=0;
+    }
+    for($x=$xstart; $x < $XBITS ; $x++) {
+        if($x==$xstart) {
+            if($x==$XBITS-$nhop){
+                printf("\thalf_adder CPA%s(carry%s[%s],Z2[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$Zpin,$YBITS-1,$x,$YBITS-1,$x+1);
+	        $cpa_label++;
+                $Zpin++;
+            }
+            else{
+                printf("\tassign carry%s[%s] = carry%s[%s] & sum%s[%s];\n",$YBITS,$x,$YBITS-1,$x,$YBITS-1,$x+1);
+            }
+        }
+        else{
+            if($x==$XBITS-2) {
+                printf("\tfull_adder CPA%s(Z2[%s],Z2[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$Zpin+1,$Zpin,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+                $cpa_label++;
+                $Zpin++;
+            }
+            else{		
+                if($x>=$XBITS-$nhop && $x<$XBITS-2) {
+                    printf("\tfull_adder CPA%s(carry%s[%s],Z2[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$Zpin,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+                    $cpa_label++;
+                    $Zpin++;
+                }
+                if($x<$XBITS-$nhop && $x>$xstart && $x<$XBITS-2){
+                    printf("\treduced_full_adder CPA%s(carry%s[%s],carry%s[%s],carry%s[%s],sum%s[%s]);\n",$cpa_label,$YBITS,$x,$YBITS-1,$x,$YBITS,$x-1,$YBITS-1,$x+1);
+	            $cpa_label++;      
+                }
+            }
+        }
+    }
+}
+
+END: print "endmodule";
+
+sub pow2 {
+    ($p) = @_;
+    $res = 1;
+    for($i=1;$i<=$p;$i++){
+        $res = $res * 2;
+    }
+    return($res);
+}
+
+sub round_near {
+    ($num) = @_;
+    $rnd = 0;
+    while($num>$rnd+0.5){
+        $rnd = $rnd + 1;
+    }
+    return($rnd);
+}
+
+
+
diff --git a/flow/synth_snps/scripts/synth.tcl b/flow/synth_snps/scripts/synth.tcl
new file mode 100755
index 0000000..4a0bebb
--- /dev/null
+++ b/flow/synth_snps/scripts/synth.tcl
@@ -0,0 +1,178 @@
+#
+# OKSTATE Main Synopsys Flow
+# Updated Sep 27, 2015 jes
+#
+
+# Verilog files
+set my_verilog_files [list arm_single.sv]
+
+# VHDL files
+# set my_vhdl_files [list top.vhd]
+
+# Set toplevel
+set my_toplevel arm
+
+# Set number of significant digits
+set report_default_significant_digits 6
+
+# V(HDL) Unconnectoed Pins Output
+set verilogout_show_unconnected_pins "true"
+set vhdlout_show_unconnected_pins "true"
+
+#
+# Due to parameterized Verilog must use analyze/elaborate and not 
+# read_verilog/vhdl (change to pull in Verilog and/or VHDL)
+#
+define_design_lib WORK -path ./WORK
+analyze -f sverilog -lib WORK $my_verilog_files
+
+#
+# Added if you had any VHDL
+# analyze -f vhdl -lib WORK $my_vhdl_files
+#
+elaborate $my_toplevel -lib WORK 
+
+# Set the current_design 
+current_design $my_toplevel
+link
+
+# Reset all constraints 
+reset_design
+
+# Set Frequency in [MHz] or [ps]
+set my_clock_pin clk
+set my_uncertainty 0.2
+set my_clk_freq_MHz 250
+set my_period [expr 1000 / $my_clk_freq_MHz]
+
+# Create clock object 
+set find_clock [ find port [list $my_clock_pin] ]
+if {  $find_clock != [list] } {
+    echo "Found clock!"
+    set my_clk $my_clock_pin
+    create_clock -period $my_period $my_clk
+    set_clock_uncertainty $my_uncertainty [get_clocks $my_clk]
+} else {
+    echo "Did not find clock! Design is probably combinational!"
+    set my_clk vclk
+    create_clock -period $my_period -name $my_clk
+}
+
+# Partitioning - flatten or hierarchically synthesize
+#ungroup -flatten -simple_names { dp* }
+#ungroup -flatten -simple_names { c* }
+ungroup -all -flatten -simple_names
+
+# Set input pins except clock
+set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]]
+
+# Specifies delays be propagated through the clock network
+set_propagated_clock [get_clocks $my_clk]
+
+# Setting constraints on input ports 
+set_driving_cell  -lib_cell DFFX1 -pin Q $all_in_ex_clk
+
+# Set input/output delay
+set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk
+set_output_delay 0.0 -max -clock $my_clk [all_outputs]
+
+# Setting load constraint on output ports 
+set_load [expr [load_of sky130_osu_sc_18T_ms.ccs/DFFX1/D] * 1] [all_outputs]
+
+# Set the wire load model 
+set_wire_load_mode "top"
+
+# Attempt Area Recovery - if looking for minimal area
+# set_max_area 2000
+
+# Set fanout
+set_max_fanout 6 $all_in_ex_clk
+
+# Fix hold time violations
+set_fix_hold [all_clocks]
+
+# Deal with constants and buffers to isolate ports
+set_fix_multiple_port_nets -all -buffer_constants
+
+# setting up the group paths to find out the required timings
+#group_path -name OUTPUTS -to [all_outputs]
+#group_path -name INPUTS -from [all_inputs] 
+#group_path -name COMBO -from [all_inputs] -to [all_outputs]
+
+# Save Unmapped Design
+set filename [format "%s%s%s"  "unmapped/" $my_toplevel ".ddc"]
+write_file -format ddc -hierarchy -o $filename
+
+# Compile statements - either compile or compile_ultra
+# compile -scan -incr -map_effort high
+compile_ultra -no_seq_output_inversion -no_boundary_optimization
+
+# Eliminate need for assign statements (yuck!)
+set verilogout_no_tri true
+set verilogout_equation false
+
+# setting to generate output files
+set write_v    1        ;# generates structual netlist
+set write_sdc  1	;# generates synopsys design constraint file for p&r
+set write_ddc  1	;# compiler file in ddc format
+set write_sdf  1	;# sdf file for backannotated timing sim
+set write_pow  1 	;# genrates estimated power report
+set write_rep  1	;# generates estimated area and timing report
+set write_cst  1        ;# generate report of constraints
+set write_hier 1        ;# generate hierarchy report
+
+# Report Constraint Violators
+set filename [format "%s%s%s"  "reports/" $my_toplevel "_constraint_all_violators.rpt"]
+redirect $filename {report_constraint -all_violators}
+
+# Check design
+redirect reports/check_design.rpt { check_design }
+
+# Report Final Netlist (Hierarchical)
+set filename [format "%s%s%s"  "mapped/" $my_toplevel ".vh"]
+write_file -f verilog -hierarchy -output $filename
+
+set filename [format "%s%s%s"  "mapped/" $my_toplevel ".sdc"]
+write_sdc $filename
+
+set filename [format "%s%s%s"  "mapped/" $my_toplevel ".ddc"]
+write_file -format ddc -hierarchy -o $filename
+
+set filename [format "%s%s%s"  "mapped/" $my_toplevel ".sdf"]
+write_sdf $filename
+
+# QoR
+set filename [format "%s%s%s"  "reports/" $my_toplevel "_qor.rep"]
+redirect $filename { report_qor }
+
+# Report Timing
+set filename [format "%s%s%s"  "reports/" $my_toplevel "_reportpath.rep"]
+redirect $filename { report_path_group }
+
+set filename [format "%s%s%s"  "reports/" $my_toplevel "_report_clock.rep"]
+redirect $filename { report_clock }
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_timing.rep"]
+redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 }
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_min_timing.rep"]
+redirect $filename { report_timing -delay min }
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_area.rep"]
+redirect $filename { report_area -hierarchy -nosplit -physical -designware}
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_cell.rep"]
+redirect $filename { report_cell [get_cells -hier *] }
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_power.rep"]
+redirect $filename { report_power }
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_constraint.rep"]
+redirect $filename { report_constraint }
+
+set filename [format "%s%s%s" "reports/" $my_toplevel "_hier.rep"]
+redirect $filename { report_hierarchy }
+
+# Quit
+quit
+
diff --git a/flow/synth_snps/sourceme b/flow/synth_snps/sourceme
new file mode 100644
index 0000000..6af8da1
--- /dev/null
+++ b/flow/synth_snps/sourceme
@@ -0,0 +1 @@
+source ../../scripts/synopsys_x64.cshrc