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