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_snpsRISCV/.gitignore b/flow/synth_snpsRISCV/.gitignore
new file mode 100644
index 0000000..87dbe6d
--- /dev/null
+++ b/flow/synth_snpsRISCV/.gitignore
@@ -0,0 +1,6 @@
+WORK/
+alib*/
+synth.out
+reports/
+mapped/
+unmapped/
diff --git a/flow/synth_snpsRISCV/.synopsys_dc.setup b/flow/synth_snpsRISCV/.synopsys_dc.setup
new file mode 100755
index 0000000..9b21716
--- /dev/null
+++ b/flow/synth_snpsRISCV/.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_TT_1P8_25C.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_snpsRISCV/Makefile b/flow/synth_snpsRISCV/Makefile
new file mode 100755
index 0000000..87acded
--- /dev/null
+++ b/flow/synth_snpsRISCV/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_snpsRISCV/hdl/adder.sv b/flow/synth_snpsRISCV/hdl/adder.sv
new file mode 100755
index 0000000..1488ebd
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/adder.sv
@@ -0,0 +1,6 @@
+module adder (input [31:0] a, b,
+ output [31:0] y);
+
+ assign y = a + b;
+
+endmodule // adder
diff --git a/flow/synth_snpsRISCV/hdl/alu.sv b/flow/synth_snpsRISCV/hdl/alu.sv
new file mode 100755
index 0000000..07f9e2f
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/alu.sv
@@ -0,0 +1,25 @@
+module alu (input [31:0] a, b,
+ input [3:0] alucont,
+ input sltunsigned,
+ output reg [31:0] result);
+
+ wire [32:0] a2, b2, sum;
+ wire [31:0] slt;
+
+ assign a2 = {sltunsigned ? 1'b0 : a[31], a};
+ assign b2 = alucont[2] ? ~{sltunsigned ? 1'b0 : b[31], b} :
+ {sltunsigned ? 1'b0 : b[31], b};
+ assign sum = a2 + b2 + alucont[2];
+ assign slt = sum[32];
+
+ always@(*)
+ case({alucont[3], alucont[1:0]})
+ 3'b000: result <= a2 & b2;
+ 3'b001: result <= a2 | b2;
+ 3'b010: result <= sum[31:0];
+ 3'b011: result <= slt;
+ 3'b100: result <= a2 ^ b2;
+ default: result <= 32'h0;
+ endcase
+
+endmodule // alu
diff --git a/flow/synth_snpsRISCV/hdl/aludec.sv b/flow/synth_snpsRISCV/hdl/aludec.sv
new file mode 100755
index 0000000..c79bb99
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/aludec.sv
@@ -0,0 +1,199 @@
+module aludec (input logic funct7b,
+ input logic [2:0] funct3,
+ input logic [2:0] aluop,
+ output logic [3:0] alucontrol,
+ output logic [1:0] shtype,
+ output logic alu2src,
+ output logic sltunsigned);
+
+
+ always_comb
+ case(aluop)
+ 3'b000:
+ begin
+ casex({funct7b, funct3})
+ // slli
+ 4'b0001:
+ begin
+ alucontrol <= 4'b0010;
+ shtype <= 2'b00;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // srli
+ 4'b0101:
+ begin
+ alucontrol <= 4'b0010;
+ shtype <= 2'b01;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // andi
+ 4'b?111:
+ begin
+ alucontrol <= 4'b0000;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // xori
+ 4'b?100:
+ begin
+ alucontrol <= 4'b1000;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // ori
+ 4'b?110:
+ begin
+ alucontrol <= 4'b0001;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ //slti
+ 4'b?010:
+ begin
+ alucontrol <= 4'b0111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // srai
+ 4'b1101:
+ begin
+ alucontrol <= 4'b0010;
+ shtype <= 2'b10;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // sltiu
+ 4'b?011:
+ begin
+ alucontrol <= 4'b0111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b1;
+ end
+ // Handle other immediates
+ default:
+ begin
+ alucontrol <= 4'b0010;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ endcase // casex ({funct7b, funct3})
+ end
+ // lw/sw
+ 3'b100:
+ begin
+ alucontrol <= 4'b0010;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // R-type
+ 3'b010:
+ case({funct7b, funct3})
+ // add
+ 4'b0000:
+ begin
+ alucontrol <= 4'b0010;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sll
+ 4'b0001:
+ begin
+ alucontrol <= 4'b0010;
+ alu2src <= 1'b1;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // xor
+ 4'b0100:
+ begin
+ alucontrol <= 4'b1000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // srl
+ 4'b0101:
+ begin
+ alucontrol <= 4'b0010;
+ alu2src <= 1'b1;
+ shtype <= 2'b01;
+ sltunsigned <= 1'b0;
+ end
+ // sra
+ 4'b1101:
+ begin
+ alucontrol <= 4'b0010;
+ alu2src <= 1'b1;
+ shtype <= 2'b10;
+ sltunsigned <= 1'b0;
+ end
+ // sub
+ 4'b1000:
+ begin
+ alucontrol <= 4'b0110;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // and
+ 4'b0111:
+ begin
+ alucontrol <= 4'b0000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // or
+ 4'b0110:
+ begin
+ alucontrol <= 4'b0001;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // slt
+ 4'b0010:
+ begin
+ alucontrol <= 4'b0111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sltu
+ 4'b0011:
+ begin
+ alucontrol <= 4'b0111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b1;
+ end
+ // ???
+ default:
+ begin
+ alucontrol <= 4'b0000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ endcase // case ({funct7b, funct3})
+ // ???
+ default:
+ begin
+ alucontrol <= 4'b0000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ endcase // case (aluop)
+
+endmodule // aludec
diff --git a/flow/synth_snpsRISCV/hdl/aludec_new.sv b/flow/synth_snpsRISCV/hdl/aludec_new.sv
new file mode 100755
index 0000000..c2caaeb
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/aludec_new.sv
@@ -0,0 +1,182 @@
+module aludec (input logic funct7b,
+ input logic [2:0] funct3,
+ input logic [2:0] aluop,
+ output logic [2:0] alucontrol,
+ output logic [1:0] shtype,
+ output logic alu2src,
+ output logic sltunsigned);
+
+
+ always_comb
+ case(aluop)
+ 3'b000:
+ begin
+ casex({funct7b, funct3})
+ // slli
+ 4'b0001:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b00;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // srli
+ 4'b0101:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b01;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // ANDI
+ 4'b?111:
+ begin
+ alucontrol <= 3'b000;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // ORI
+ 4'b?110:
+ begin
+ alucontrol <= 3'b001;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ //slti
+ 4'b?010:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // srai
+ 4'b1101:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b10;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // sltiu
+ 4'b?011:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b1;
+ end
+ default:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ endcase // casex ({funct7b, funct3})
+ end
+ // lw/sw
+ 3'b100:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // R-type
+ 3'b010:
+ case({funct7b, funct3})
+ // add
+ 4'b0000:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sll
+ 4'b0001:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b1;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // srl
+ 4'b0101:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b1;
+ shtype <= 2'b01;
+ sltunsigned <= 1'b0;
+ end
+ // sra
+ 4'b1101:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b1;
+ shtype <= 2'b10;
+ sltunsigned <= 1'b0;
+ end
+ // sub
+ 4'b1000:
+ begin
+ alucontrol <= 3'b110;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // and
+ 4'b0111:
+ begin
+ alucontrol <= 3'b000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // or
+ 4'b0110:
+ begin
+ alucontrol <= 3'b001;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // slt
+ 4'b0010:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sltu
+ 4'b0011:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b1;
+ end
+ // ???
+ default:
+ begin
+ alucontrol <= 3'b000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ endcase // case ({funct7b, funct3})
+ // ???
+ default:
+ begin
+ alucontrol <= 3'b000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ endcase // case (aluop)
+
+endmodule // aludec
diff --git a/flow/synth_snpsRISCV/hdl/aludec_orig.sv b/flow/synth_snpsRISCV/hdl/aludec_orig.sv
new file mode 100755
index 0000000..8984a2b
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/aludec_orig.sv
@@ -0,0 +1,193 @@
+module aludec (input funct7b,
+ input [2:0] funct3,
+ input [2:0] aluop,
+ output reg [2:0] alucontrol,
+ output reg [1:0] shtype,
+ output reg alu2src,
+ output reg sltunsigned);
+
+ wire [3:0] aluop2;
+
+ // Logic works because we don't have XORI
+ assign aluop2 = {(funct3[2]|funct3[0])&!funct3[1],aluop};
+
+ always @(*)
+ case(aluop2)
+ 4'b1000:
+ // slli / srli / srai
+ begin
+ case({funct7b, funct3})
+ // slli
+ 4'b0001:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b00;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // srli
+ 4'b0101:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b01;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ // srai
+ 4'b1101:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b10;
+ alu2src <= 1'b1;
+ sltunsigned <= 1'b0;
+ end
+ default:
+ begin
+ alucontrol <= 3'b000;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ endcase
+ end // case: 4'b1000
+ // lw/sw
+ 4'b0100:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // immediate
+ 4'b0000:
+ begin
+ case(funct3)
+ // ANDI
+ 3'b111:
+ begin
+ alucontrol <= 3'b000;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ // ORI
+ 3'b110:
+ begin
+ alucontrol <= 3'b001;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ //slti
+ 3'b010:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sltiu
+ 3'b011:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b1;
+ end
+ // Handle other immediates
+ default:
+ begin
+ alucontrol <= 3'b010;
+ shtype <= 2'b00;
+ alu2src <= 1'b0;
+ sltunsigned <= 1'b0;
+ end
+ endcase
+ end
+ default:
+ // R-type
+ case({funct7b, funct3})
+ // add
+ 4'b0000:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sll
+ 4'b0001:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b1;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // srl
+ 4'b0101:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b1;
+ shtype <= 2'b01;
+ sltunsigned <= 1'b0;
+ end
+ // sra
+ 4'b1101:
+ begin
+ alucontrol <= 3'b010;
+ alu2src <= 1'b1;
+ shtype <= 2'b10;
+ sltunsigned <= 1'b0;
+ end
+ // sub
+ 4'b1000:
+ begin
+ alucontrol <= 3'b110;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // and
+ 4'b0111:
+ begin
+ alucontrol <= 3'b000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // or
+ 4'b0110:
+ begin
+ alucontrol <= 3'b001;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // slt
+ 4'b0010:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ // sltu
+ 4'b0011:
+ begin
+ alucontrol <= 3'b111;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b1;
+ end
+ // ???
+ default:
+ begin
+ alucontrol <= 3'b000;
+ alu2src <= 1'b0;
+ shtype <= 2'b00;
+ sltunsigned <= 1'b0;
+ end
+ endcase
+ endcase // case (aluop)
+
+endmodule // aludec
diff --git a/flow/synth_snpsRISCV/hdl/arrs.sv b/flow/synth_snpsRISCV/hdl/arrs.sv
new file mode 100755
index 0000000..a9229a4
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/arrs.sv
@@ -0,0 +1,38 @@
+// Ross Thompson
+// September 24, 2019
+// Oklahoma State University
+// Original work by Kurt Rooks Nov 14, 2011.
+// Translated to verilog by Ross Thompson
+
+// theory of operation
+// Areset is an asynchronous reset which needs to be synced to a clock clk.
+// But areset needs to be able to reset any downstream flip flops with an
+// asynchronous reset without a clock. This works by resetting both registers.
+// Because they are both asynchronous reset registers the output reset_out is
+// immediately pulled high. When areset is pulled low, the first flip flop
+// may go metastable but is synched by ff_2. Then after another clock period
+// reset_out will go low.
+
+module arrs (output reset_out,
+ input areset,
+ input clk);
+
+ logic n1, n2;
+
+ flopenr #(1) ff_1(.clk(clk),
+ .reset(areset),
+ .en(1'b1),
+ .d(1'b1),
+ .q(n1));
+
+ flopenr #(1) ff_2(.clk(clk),
+ .reset(areset),
+ .en(1'b1),
+ .d(n1),
+ .q(n2));
+
+ assign reset_out = ~n2;
+
+endmodule // arrs
+
+
diff --git a/flow/synth_snpsRISCV/hdl/controller.sv b/flow/synth_snpsRISCV/hdl/controller.sv
new file mode 100755
index 0000000..fee56a8
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/controller.sv
@@ -0,0 +1,59 @@
+module controller (input [6:0] op, funct7,
+ input [2:0] funct3,
+ output memtoreg, memwrite,
+ output pcsrc, alusrc,
+ output regwrite,
+ output branch,
+ output storepc,
+ output pcadd,
+ output pcext,
+ output unsign,
+ output [2:0] imm,
+ output [3:0] alucontrol,
+ output [1:0] shtype,
+ output alu2src,
+ input gt, lt, eq,
+ output suspend,
+ output sltunsigned,
+ output memread);
+
+ wire [2:0] aluop;
+ wire alu2src_fake;
+ wire [3:0] alucontrol_fake;
+ wire storepc_local;
+ wire auipc_cntrl;
+
+ maindec md (.op(op),
+ .memtoreg(memtoreg),
+ .memwrite(memwrite),
+ .branch(branch),
+ .alusrc(alusrc),
+ .regwrite(regwrite),
+ .pcext(pcext), .pcadd(pcadd),
+ .storepc(storepc_local), .imm(imm), .aluop(aluop),
+ .auipc_cntrl(auipc_cntrl),
+ .gt(gt), .lt(lt), .eq(eq),
+ .suspend(suspend),
+ .memread(memread));
+ aludec ad (.funct7b(funct7[5]),
+ .funct3(funct3),
+ .aluop(aluop),
+ .alucontrol(alucontrol_fake),
+ .alu2src(alu2src_fake),
+ .shtype(shtype),
+ .sltunsigned(sltunsigned));
+
+ mux2 #(1) mx1(.d0(alu2src_fake),.d1(1'b0),.s(imm[2]),.y(alu2src));
+ mux2 #(4) mx2(.d0(alucontrol_fake),.d1(4'b0010),.s(imm[2] | branch),.y(alucontrol));
+
+ assign pcsrc = (branch & ~funct3[2] & ~funct3[1] & ~funct3[0] & eq) |
+ (branch & funct3[2] & ~funct3[1] & funct3[0] & ~lt) |
+ (branch & funct3[2] & ~funct3[1] & ~funct3[0] & lt) |
+ (branch & ~funct3[2] & ~funct3[1] & funct3[0] & ~eq) |
+ (branch & funct3[2] & funct3[1] & ~funct3[0] & lt) |
+ (branch & funct3[2] & funct3[1] & funct3[0] & (gt | eq)) |
+ (storepc_local);
+ assign unsign = branch & funct3[1];
+ assign storepc = storepc_local | auipc_cntrl;
+
+endmodule // controller
diff --git a/flow/synth_snpsRISCV/hdl/counter.sv b/flow/synth_snpsRISCV/hdl/counter.sv
new file mode 100755
index 0000000..b4dfe08
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/counter.sv
@@ -0,0 +1,36 @@
+// Ross Thompson
+// September 20, 2019
+// Oklahoma State University
+
+// Counter.sv
+// General purpuse up counter
+// Specify the number of bits, automatically wraps around
+// to zero.
+
+module counter
+ #(parameter WIDTH = 32)
+ (input clk,
+ input areset,
+ input enable,
+ input load,
+ input [WIDTH-1:0] count_in,
+ output [WIDTH-1:0] count_out);
+
+ wire [WIDTH-1:0] count_d;
+ wire [WIDTH-1:0] count_p1;
+ wire en;
+
+
+ flopenr #(WIDTH) register(.clk(clk),
+ .reset(areset),
+ .en(en),
+ .d(count_d),
+ .q(count_out));
+
+ assign count_p1 = count_out + 1'b1;
+ assign count_d = load ? count_in : count_p1;
+ assign en = enable | load;
+
+endmodule
+
+
diff --git a/flow/synth_snpsRISCV/hdl/datapath.sv b/flow/synth_snpsRISCV/hdl/datapath.sv
new file mode 100755
index 0000000..d772fd9
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/datapath.sv
@@ -0,0 +1,107 @@
+module datapath(input clk, reset,
+ input [31:0] instr,
+ input [2:0] imm,
+ output [31:0] pc,
+ output [31:0] pcnext,
+ input pcsrc, pcadd, pcext,
+ input ISRsel,
+ input [31:0] ISR,
+ input unsign,
+ output gt, lt, eq,
+ input [3:0] alucontrol,
+ input alusrc, storepc, sltunsigned,
+ input [1:0] shtype,
+ input alu2src,
+ input memtoreg, regwrite,
+ output [31:0] aluout, writedata,
+ input [31:0] readdata,
+ input suspend);
+
+ wire [31:0] pcsum, pcimm_sum, pcjalr, pctoreg;
+ wire [31:0] signimm, signimm2;
+ wire [31:0] srca, srca2, srcb;
+ wire [31:0] result, result2;
+ wire [31:0] shoutput, aluout2;
+ wire [4:0] rs1;
+ wire compA,compB;
+ wire [31:0] pcISRin, pcext_imm;
+ wire [31:0] SEPC;
+
+ // SEPC
+ flopenr #(32) epc(.clk(clk), .reset(reset), .en(suspend),
+ .d(pc), .q(SEPC));
+ // next PC logic
+ flopr #(32) pcreg(.clk(clk), .reset(reset),
+ .d(pcnext), .q(pc));
+ // PC Next Adder PC+4
+ adder pcadder(.a(pc), .b(32'b100), .y(pcsum));
+
+ // need to read a zero on rs1 for lui to work.
+ // this is in the decoder, not in the bit-sliced datapath
+ mux2 #(5) rs1mux(.d0(instr[19:15]), .d1(5'b00000),
+ .s(imm[2]), .y(rs1));
+ // register file logic
+ regfile rf (.clk(clk), .we3(regwrite),
+ .ra1(rs1), .ra2(instr[24:20]),
+ .wa3(instr[11:7]), .wd3(result),
+ .rd1(srca2), .rd2(writedata));
+
+ // Sign Extension (Immediate)
+ signext se(.a(instr[31:0]), .sel(imm[1:0]), .y(signimm));
+ // Sign Extension (lui)
+ mux2 #(32) semux(.d0(signimm), .d1({instr[31:12], 12'b0}),
+ .s(imm[2]), .y(signimm2));
+ // Shifting immediate for PC
+ mux2 #(32) pcextmux(.d0(signimm2), .d1({signimm2[30:0],1'b0}),
+ .s(pcext), .y(pcext_imm));
+
+ // Branch Mux
+ mux2 #(32) pcmux(.d0(pcsum), .d1(pcimm_sum),
+ .s(pcsrc), .y(pcISRin));
+ mux2 #(32) pcmux2(.d0(pcimm_sum), .d1(pcsum),
+ .s(pcsrc), .y(pctoreg));
+
+ // PC imm Adder PC + imm
+ adder pcimm(.a(pcjalr), .b(pcext_imm), .y(pcimm_sum));
+ // ISR mux
+ mux2 #(32) ISRmux(.d0(pcISRin), .d1(ISR),
+ .s(ISRsel), .y(pcnext));
+ // ALU PC/imm mux
+ mux2 #(32) pcsrcmux(.d0(srca2), .d1(pc),
+ .s(pcadd), .y(pcjalr));
+
+ // ALU mem/imm mux
+ mux2 #(32) memsrcmux(.d0(writedata), .d1(pcext_imm),
+ .s(alusrc), .y(srcb));
+
+ // Choose whether to invert the sign bit of the comparator
+ // or not for unsigned logic change these
+ // This can be 33rd bit logic
+ assign compA = srca2[31] ^ ~unsign;
+ assign compB = writedata[31] ^ ~unsign;
+
+ // Comparator (for beq, bge, blt, beq)
+ magcompare32 compare (.GT(gt), .LT(lt), .EQ(eq),
+ .A({compA, srca2[30:0]}),
+ .B({compB, writedata[30:0]}));
+ // ALU
+ alu alu (.a(srca2), .b(srcb),
+ .alucont(alucontrol),
+ .sltunsigned(sltunsigned),
+ .result(aluout2));
+
+ // Shifter
+ shifter shift (.a(srca2), .shamt(srcb[4:0]),
+ .shtype(shtype), .y(shoutput));
+
+ // Choose ALU or Shifter output
+ mux2 #(32) srccmux(.d0(aluout2), .d1(shoutput),
+ .s(alu2src), .y(aluout));
+
+ // Memory Output
+ mux2 #(32) resmux(.d0(aluout), .d1(readdata),
+ .s(memtoreg), .y(result2));
+ mux2 #(32) storepcmux(.d0(result2), .d1(pctoreg),
+ .s(storepc), .y(result));
+
+endmodule // datapath
diff --git a/flow/synth_snpsRISCV/hdl/flopenr.sv b/flow/synth_snpsRISCV/hdl/flopenr.sv
new file mode 100755
index 0000000..2c00434
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/flopenr.sv
@@ -0,0 +1,12 @@
+`timescale 1ns/1ns
+module flopenr #(parameter WIDTH = 8)
+ (input clk, reset,
+ input en,
+ input [WIDTH-1:0] d,
+ output reg [WIDTH-1:0] q);
+
+ always @(posedge clk, posedge reset)
+ if (reset) q <= #1 0;
+ else if (en) q <= #1 d;
+
+endmodule // flopenr
diff --git a/flow/synth_snpsRISCV/hdl/flopens.sv b/flow/synth_snpsRISCV/hdl/flopens.sv
new file mode 100644
index 0000000..afa7adc
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/flopens.sv
@@ -0,0 +1,12 @@
+`timescale 1ns/1ns
+module flopens #(parameter WIDTH = 8)
+ (input clk, set,
+ input en,
+ input [WIDTH-1:0] d,
+ output reg [WIDTH-1:0] q);
+
+ always @(posedge clk, posedge set)
+ if (set) q <= #1 1;
+ else if (en) q <= #1 d;
+
+endmodule // flopens
diff --git a/flow/synth_snpsRISCV/hdl/flopr.sv b/flow/synth_snpsRISCV/hdl/flopr.sv
new file mode 100755
index 0000000..04d8bc4
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/flopr.sv
@@ -0,0 +1,11 @@
+`timescale 1ns/1ns
+module flopr #(parameter WIDTH = 8)
+ (input clk, reset,
+ input [WIDTH-1:0] d,
+ output reg [WIDTH-1:0] q);
+
+ always @(posedge clk, posedge reset)
+ if (reset) q <= #1 0;
+ else q <= #1 d;
+
+endmodule // flopr
diff --git a/flow/synth_snpsRISCV/hdl/magcompare2b.sv b/flow/synth_snpsRISCV/hdl/magcompare2b.sv
new file mode 100755
index 0000000..9e23bf3
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/magcompare2b.sv
@@ -0,0 +1,19 @@
+// 2-bit magnitude comparator
+// This module compares two 2-bit values A and B. LT is '1' if A < B
+// and GT is '1'if A > B. LT and GT are both '0' if A = B.
+
+module magcompare2b (LT, GT, A, B);
+
+ input [1:0] A;
+ input [1:0] B;
+
+ output LT;
+ output GT;
+
+ // Determine if A < B using a minimized sum-of-products expression
+ assign LT = ~A[1]&B[1] | ~A[1]&~A[0]&B[0] | ~A[0]&B[1]&B[0];
+
+ // Determine if A > B using a minimized sum-of-products expression
+ assign GT = A[1]&~B[1] | A[1]&A[0]&~B[0] | A[0]&~B[1]&~B[0];
+
+endmodule // magcompare2b
diff --git a/flow/synth_snpsRISCV/hdl/magcompare2c.sv b/flow/synth_snpsRISCV/hdl/magcompare2c.sv
new file mode 100755
index 0000000..52caff8
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/magcompare2c.sv
@@ -0,0 +1,19 @@
+// 2-bit magnitude comparator
+// This module compares two 2-bit values A and B. LT is '1' if A < B
+// and GT is '1'if A > B. LT and GT are both '0' if A = B.
+
+module magcompare2c (LT, GT, GT_in, LT_in);
+
+ input [1:0] LT_in;
+ input [1:0] GT_in;
+
+ output LT;
+ output GT;
+
+ // Determine if A < B using a minimized sum-of-products expression
+ assign GT = GT_in[1] | ~LT_in[1]>_in[0];
+
+ // Determine if A > B using a minimized sum-of-products expression
+ assign LT = LT_in[1] | !GT_in[1]<_in[0];
+
+endmodule // magcompare2c
\ No newline at end of file
diff --git a/flow/synth_snpsRISCV/hdl/magcompare32.sv b/flow/synth_snpsRISCV/hdl/magcompare32.sv
new file mode 100755
index 0000000..d0a6c42
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/magcompare32.sv
@@ -0,0 +1,65 @@
+// This module compares two 32-bit values A and B. LT is '1' if A < B
+// and EQ is '1'if A = B. LT and GT are both '0' if A > B.
+//
+// J. E. Stine and M. J. Schulte, "A combined two's complement and
+// floating-point comparator," 2005 IEEE International Symposium on
+// Circuits and Systems, Kobe, 2005, pp. 89-92 Vol. 1.
+// doi: 10.1109/ISCAS.2005.1464531
+
+module magcompare32 (GT, LT, EQ, A, B);
+
+ input [31:0] A;
+ input [31:0] B;
+
+ output LT;
+ output EQ;
+ output GT;
+
+ wire [15:0] s;
+ wire [15:0] t;
+ wire [7:0] u;
+ wire [7:0] v;
+ wire [3:0] w;
+ wire [3:0] x;
+ wire [1:0] y;
+ wire [1:0] z;
+
+ magcompare2b mag1(s[0], t[0], A[1:0], B[1:0]);
+ magcompare2b mag2(s[1], t[1], A[3:2], B[3:2]);
+ magcompare2b mag3(s[2], t[2], A[5:4], B[5:4]);
+ magcompare2b mag4(s[3], t[3], A[7:6], B[7:6]);
+ magcompare2b mag5(s[4], t[4], A[9:8], B[9:8]);
+ magcompare2b mag6(s[5], t[5], A[11:10], B[11:10]);
+ magcompare2b mag7(s[6], t[6], A[13:12], B[13:12]);
+ magcompare2b mag8(s[7], t[7], A[15:14], B[15:14]);
+ magcompare2b mag9(s[8], t[8], A[17:16], B[17:16]);
+ magcompare2b magA(s[9], t[9], A[19:18], B[19:18]);
+ magcompare2b magB(s[10], t[10], A[21:20], B[21:20]);
+ magcompare2b magC(s[11], t[11], A[23:22], B[23:22]);
+ magcompare2b magD(s[12], t[12], A[25:24], B[25:24]);
+ magcompare2b magE(s[13], t[13], A[27:26], B[27:26]);
+ magcompare2b magF(s[14], t[14], A[29:28], B[29:28]);
+ magcompare2b mag10(s[15], t[15], A[31:30], B[31:30]);
+
+ magcompare2c mag21(u[0], v[0], t[1:0], s[1:0]);
+ magcompare2c mag22(u[1], v[1], t[3:2], s[3:2]);
+ magcompare2c mag23(u[2], v[2], t[5:4], s[5:4]);
+ magcompare2c mag24(u[3], v[3], t[7:6], s[7:6]);
+ magcompare2c mag25(u[4], v[4], t[9:8], s[9:8]);
+ magcompare2c mag26(u[5], v[5], t[11:10], s[11:10]);
+ magcompare2c mag27(u[6], v[6], t[13:12], s[13:12]);
+ magcompare2c mag28(u[7], v[7], t[15:14], s[15:14]);
+
+ magcompare2c mag31(w[0], x[0], v[1:0], u[1:0]);
+ magcompare2c mag32(w[1], x[1], v[3:2], u[3:2]);
+ magcompare2c mag33(w[2], x[2], v[5:4], u[5:4]);
+ magcompare2c mag34(w[3], x[3], v[7:6], u[7:6]);
+
+ magcompare2c mag39(y[0], z[0], x[1:0], w[1:0]);
+ magcompare2c mag3A(y[1], z[1], x[3:2], w[3:2]);
+
+ magcompare2c mag3F(LT, GT, z[1:0], y[1:0]);
+
+ assign EQ = ~(LT | GT);
+
+endmodule // magcompare32
\ No newline at end of file
diff --git a/flow/synth_snpsRISCV/hdl/maindec.sv b/flow/synth_snpsRISCV/hdl/maindec.sv
new file mode 100755
index 0000000..22d50c7
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/maindec.sv
@@ -0,0 +1,36 @@
+module maindec (input [6:0] op,
+ output memtoreg, memwrite,
+ output branch, alusrc,
+ output regwrite,
+ output storepc,
+ output pcadd,
+ output pcext,
+ output [2:0] imm,
+ output [2:0] aluop,
+ output auipc_cntrl,
+ output memread,
+ input gt, lt, eq,
+ output suspend);
+
+ reg [16:0] controls;
+
+ assign {memread, auipc_cntrl, pcadd, pcext, suspend, regwrite, alusrc,
+ branch, memwrite,
+ memtoreg, storepc, aluop, imm} = controls;
+
+ always @(*)
+ case(op)
+ 7'b011_0011: controls <= 17'b00000100_000_010_000; // R
+ 7'b000_0011: controls <= 17'b10000110_010_100_000; // LW
+ 7'b010_0011: controls <= 17'b00000010_100_100_001; // SW
+ 7'b110_0011: controls <= 17'b00110011_000_000_010; // BXX
+ 7'b110_1111: controls <= 17'b00110110_001_000_011; // JAL/J
+ 7'b001_0011: controls <= 17'b00000110_000_000_000; // ADDI/ORI
+ 7'b011_0111: controls <= 17'b00000110_000_000_100; // LUI
+ 7'b111_0011: controls <= 17'b00001000_000_000_000; // ecall/ebreak
+ 7'b110_0111: controls <= 17'b00000110_001_000_000; // JALR/JR
+ 7'b001_0111: controls <= 17'b01100110_000_000_100; // AUIPC
+ default: controls <= 17'b00000000_000_000_000; // default
+ endcase // case (op)
+
+endmodule // maindec
diff --git a/flow/synth_snpsRISCV/hdl/mux2.sv b/flow/synth_snpsRISCV/hdl/mux2.sv
new file mode 100755
index 0000000..aaeba78
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/mux2.sv
@@ -0,0 +1,8 @@
+module mux2 #(parameter WIDTH = 8)
+ (input [WIDTH-1:0] d0, d1,
+ input s,
+ output [WIDTH-1:0] y);
+
+ assign y = s ? d1 : d0;
+
+endmodule // mux2
diff --git a/flow/synth_snpsRISCV/hdl/mux3.sv b/flow/synth_snpsRISCV/hdl/mux3.sv
new file mode 100755
index 0000000..b8c7606
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/mux3.sv
@@ -0,0 +1,8 @@
+module mux3 #(parameter WIDTH = 8)
+ (input logic [WIDTH-1:0] d0, d1, d2,
+ input logic [1:0] s,
+ output logic [WIDTH-1:0] y);
+
+ assign y = s[1] ? d2 : (s[0] ? d1 : d0);
+
+endmodule // mux3
diff --git a/flow/synth_snpsRISCV/hdl/mux4.sv b/flow/synth_snpsRISCV/hdl/mux4.sv
new file mode 100755
index 0000000..a0248e9
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/mux4.sv
@@ -0,0 +1,8 @@
+module mux4 #(parameter WIDTH = 8)
+ (input logic [WIDTH-1:0] d0, d1, d2, d3,
+ input logic [1:0] s,
+ output logic [WIDTH-1:0] y);
+
+ assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0);
+
+endmodule // mux4
diff --git a/flow/synth_snpsRISCV/hdl/mux5.sv b/flow/synth_snpsRISCV/hdl/mux5.sv
new file mode 100755
index 0000000..9efde72
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/mux5.sv
@@ -0,0 +1,7 @@
+module mux5 #(parameter WIDTH = 8)
+ (input logic [WIDTH-1:0] d0, d1, d2, d3, d4,
+ input logic [2:0] s,
+ output logic [WIDTH-1:0] y);
+
+ assign y = s[2] ? d4 : (s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0));
+endmodule
diff --git a/flow/synth_snpsRISCV/hdl/regfile.sv b/flow/synth_snpsRISCV/hdl/regfile.sv
new file mode 100755
index 0000000..5c128bb
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/regfile.sv
@@ -0,0 +1,20 @@
+module regfile (input clk,
+ input we3,
+ input [4:0] ra1, ra2, wa3,
+ input [31:0] wd3,
+ output [31:0] rd1, rd2);
+
+ reg [31:0] rf[31:0];
+
+ // three ported register file
+ // read two ports combinationally
+ // write third port on rising edge of clock
+ // register 0 hardwired to 0
+
+ always @(posedge clk)
+ if (we3 && wa3!=0) rf[wa3] <= wd3;
+
+ assign rd1 = (ra1 != 0) ? rf[ra1] : 0;
+ assign rd2 = (ra2 != 0) ? rf[ra2] : 0;
+
+endmodule // regfile
diff --git a/flow/synth_snpsRISCV/hdl/riscv.sv b/flow/synth_snpsRISCV/hdl/riscv.sv
new file mode 100755
index 0000000..92d51b6
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/riscv.sv
@@ -0,0 +1,71 @@
+module riscv (input clk, reset,
+ output [31:0] pc,
+ output [31:0] pcnext,
+ input [31:0] instr,
+ output memwrite,
+ output [31:0] aluout, writedata,
+ input [31:0] readdata,
+ output memread,
+ output suspend);
+
+ wire memtoreg, pcsrc, branch, unsign,
+ jump, alusrc, alu2src, regwrite, sltunsigned;
+ wire [3:0] alucontrol;
+ wire [2:0] imm;
+ wire lt, gt, eq;
+ wire [1:0] shtype;
+ wire [31:0] signimm;
+
+ wire [31:0] ISR;
+ wire ISRsel;
+ wire storepc;
+ wire pcadd;
+ wire pcext;
+
+ // in progress
+ assign ISRsel = 1'b0;
+ assign ISR = 32'b0;
+
+ controller c (.op(instr[6:0]), .funct7(instr[31:25]),
+ .funct3(instr[14:12]),
+ .memtoreg(memtoreg),
+ .memwrite(memwrite),
+ .pcsrc(pcsrc),
+ .alusrc(alusrc),
+ .regwrite(regwrite),
+ .branch(branch),
+ .storepc(storepc),
+ .pcadd(pcadd),
+ .pcext(pcext),
+ .unsign(unsign),
+ .imm(imm),
+ .alucontrol(alucontrol),
+ .shtype(shtype),
+ .alu2src(alu2src),
+ .gt(gt), .lt(lt), .eq(eq),
+ .suspend(suspend),
+ .sltunsigned(sltunsigned),
+ .memread(memread));
+ datapath dp (.clk(clk), .reset(reset),
+ .memtoreg(memtoreg), .pcsrc(pcsrc),
+ .alusrc(alusrc), .regwrite(regwrite),
+ .alucontrol(alucontrol),
+ .storepc(storepc),
+ .pcadd(pcadd),
+ .pcext(pcext),
+ .unsign(unsign),
+ .imm(imm),
+ .alu2src(alu2src),
+ .shtype(shtype),
+ .pc(pc),
+ .pcnext(pcnext),
+ .instr(instr),
+ .aluout(aluout),
+ .writedata(writedata),
+ .readdata(readdata),
+ .gt(gt), .lt(lt), .eq(eq),
+ .sltunsigned(sltunsigned),
+ .ISR(ISR), .ISRsel(ISRsel),
+ .suspend(suspend));
+
+endmodule // riscv
diff --git a/flow/synth_snpsRISCV/hdl/shifter.sv b/flow/synth_snpsRISCV/hdl/shifter.sv
new file mode 100755
index 0000000..1983e66
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/shifter.sv
@@ -0,0 +1,26 @@
+module shifter (input logic signed [31:0] a,
+ input logic [ 4:0] shamt,
+ input logic [ 1:0] shtype,
+ output logic [31:0] y);
+
+ always_comb
+ case (shtype)
+ 2'b00:
+ begin
+ y = a << shamt;
+ end
+ 2'b01:
+ begin
+ y = a >> shamt;
+ end
+ 2'b10:
+ begin
+ y = a >>> shamt;
+ end
+ default:
+ begin
+ y = a;
+ end
+ endcase // case (shtype)
+
+endmodule // shifter
diff --git a/flow/synth_snpsRISCV/hdl/signext.sv b/flow/synth_snpsRISCV/hdl/signext.sv
new file mode 100755
index 0000000..fdb3789
--- /dev/null
+++ b/flow/synth_snpsRISCV/hdl/signext.sv
@@ -0,0 +1,16 @@
+module signext (input [31:0] a,
+ input [1:0] sel,
+ output [31:0] y);
+
+ // 0 = normal (I) immediate
+ // 1 = sw (S) immediate
+ // 2 = branch (SB) immediate
+ // 3 = jal (UJ) immediate
+ mux4 #(32) m1 (.d0({{21{a[31]}}, a[30:20]}),
+ .d1({{21{a[31]}}, a[30:25], a[11:7]}),
+ .d2({{21{a[31]}}, a[7], a[30:25], a[11:8]}),
+ .d3({{13{a[31]}}, a[19:12], a[20], a[30:21]}),
+ .s(sel),
+ .y(y));
+
+endmodule // signext
diff --git a/flow/synth_snpsRISCV/scripts/multGen/array8x8.v b/flow/synth_snpsRISCV/scripts/multGen/array8x8.v
new file mode 100755
index 0000000..0ceee43
--- /dev/null
+++ b/flow/synth_snpsRISCV/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_snpsRISCV/scripts/multGen/array_v_CCT.pl b/flow/synth_snpsRISCV/scripts/multGen/array_v_CCT.pl
new file mode 100755
index 0000000..d51bb2b
--- /dev/null
+++ b/flow/synth_snpsRISCV/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_snpsRISCV/scripts/synth.tcl b/flow/synth_snpsRISCV/scripts/synth.tcl
new file mode 100755
index 0000000..bc31cf7
--- /dev/null
+++ b/flow/synth_snpsRISCV/scripts/synth.tcl
@@ -0,0 +1,178 @@
+#
+# OKSTATE Main Synopsys Flow
+# Updated Sep 27, 2015 jes
+#
+
+# Verilog files
+set my_verilog_files [list mux2.sv mux3.sv mux4.sv mux5.sv flopr.sv flopens.sv flopenr.sv counter.sv adder.sv magcompare2b.sv magcompare2c.sv magcompare32.sv regfile.sv signext.sv shifter.sv alu.sv aludec.sv maindec.sv controller.sv datapath.sv riscv.sv]
+
+# VHDL files
+# set my_vhdl_files [list top.vhd]
+
+# Set toplevel
+set my_toplevel riscv
+
+# 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 400
+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_TT_1P8_25C.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_snpsRISCV/sourceme b/flow/synth_snpsRISCV/sourceme
new file mode 100644
index 0000000..6af8da1
--- /dev/null
+++ b/flow/synth_snpsRISCV/sourceme
@@ -0,0 +1 @@
+source ../../scripts/synopsys_x64.cshrc