Added carry select adder mapping files
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index edee408..2d94f6d 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -270,7 +270,7 @@
 # standard cell libraries, so these are collected in one definition
 # here:
 OPENLANE_COMMON = config.tcl tracks.info no_synth.cells drc_exclude.cells
-OPENLANE_COMMON += tribuff_map.v latch_map.v mux2_map.v mux4_map.v fa_map.v rca_map.v
+OPENLANE_COMMON += tribuff_map.v latch_map.v mux2_map.v mux4_map.v fa_map.v rca_map.v csa_map.v
 
 # Where cpp syntax is followed, this is equivalent to cpp, but it does not
 # mangle non-C source files under the belief that they are actually C code.
diff --git a/sky130/openlane/config.tcl b/sky130/openlane/config.tcl
index f26d033..e11c34d 100755
--- a/sky130/openlane/config.tcl
+++ b/sky130/openlane/config.tcl
@@ -84,6 +84,9 @@
 # Ripple carry adder mapping
 set ::env(RIPPLE_CARRY_ADDER_MAP) "$::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/$::env(STD_CELL_LIBRARY)/rca_map.v"
 
+# Carry select adder mapping
+set ::env(CARRY_SELECT_ADDER_MAP) "$::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/$::env(STD_CELL_LIBRARY)/csa_map.v"
+
 # Default No Synth List
 set ::env(NO_SYNTH_CELL_LIST) "$::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/$::env(STD_CELL_LIBRARY)/no_synth.cells"
 
diff --git a/sky130/openlane/sky130_fd_sc_hd/csa_map.v b/sky130/openlane/sky130_fd_sc_hd/csa_map.v
new file mode 100644
index 0000000..f9e5107
--- /dev/null
+++ b/sky130/openlane/sky130_fd_sc_hd/csa_map.v
@@ -0,0 +1,257 @@
+`define TIE_CELL        sky130_fd_sc_hd__conb_1  
+`define FA_CELL         sky130_fd_sc_hd__fa_1  
+`define MUX2x1_CELL     sky130_fd_sc_hd__mux2_1
+
+// n-bit RCA using n FA instances
+module rca #(parameter n=32) ( 
+	input [n-1:0] 	a, b,
+	input 			ci,
+	output [n-1:0]	s,
+	output			co
+);
+	wire [n:0] c;
+	
+	assign c[0] = ci;
+	assign co = c[n];
+	
+	generate 
+		genvar i;
+		for(i=0; i<n; i=i+1) 
+			`FA_CELL FA ( .COUT(c[i+1]), .CIN(c[i]), .A(a[i]), .B(b[i]), .SUM(s[i]) );
+   	endgenerate
+
+endmodule
+
+module csa8_4(
+    input [7:0] 	a, b,
+	input 			ci,
+	output [7:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [3:0] s10, s11;
+	rca #(4) A0  (.a(a[3:0]), .b(b[3:0]), .ci(ci), .co(co0), .s(s[3:0]) );
+	rca #(4) A10  (.a(a[7:4]), .b(b[7:4]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(4) A11  (.a(a[7:4]), .b(b[7:4]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [3:0] ( .X(s[7:4]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa16_8( 
+	input [15:0] 	a, b,
+	input 			ci,
+	output [15:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [7:0] s10, s11;
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [7:0] ( .X(s[15:8]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8x4( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	csa8_4 A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	csa8_4 A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	csa8_4 A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	csa8_4 A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	csa8_4 A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	csa8_4 A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	csa8_4 A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+
+// 32-bit Carry Select Adder 2x16rca
+module csa32_16( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+
+	wire co0, co10, co11;
+	wire [15:0] s10, s11;
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [15:0] ( .X(s[31:16]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(8) A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(8) A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(8) A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(8) A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+module csa64_16( 
+	input [63:0] 	a, b,
+	input 			ci,
+	output [63:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [15:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [15:0] ( .X(s[31:16]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(16) A20  (.a(a[47:32]), .b(b[47:32]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(16) A21  (.a(a[47:32]), .b(b[47:32]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [15:0] ( .X(s[47:32]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(16) A30  (.a(a[63:48]), .b(b[63:48]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(16) A31  (.a(a[63:48]), .b(b[63:48]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [15:0] ( .X(s[63:48]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[2]), .A1(c1[2]), .S(co2) );
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module sky130_csa (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = B_buf; 
+	
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add64(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+    endgenerate
+
+endmodule
+
+(* techmap_celltype = "$sub" *)
+module sky130_csa_sub (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = ~B_buf; 
+
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b1),  .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b1),.s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add32(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+    endgenerate
+
+endmodule
diff --git a/sky130/openlane/sky130_fd_sc_hdll/csa_map.v b/sky130/openlane/sky130_fd_sc_hdll/csa_map.v
new file mode 100644
index 0000000..3f95c4e
--- /dev/null
+++ b/sky130/openlane/sky130_fd_sc_hdll/csa_map.v
@@ -0,0 +1,257 @@
+`define TIE_CELL        sky130_fd_sc_hdll__conb_1  
+`define FA_CELL         sky130_fd_sc_hdll__fa_1  
+`define MUX2x1_CELL     sky130_fd_sc_hdll__mux2_1
+
+// n-bit RCA using n FA instances
+module rca #(parameter n=32) ( 
+	input [n-1:0] 	a, b,
+	input 			ci,
+	output [n-1:0]	s,
+	output			co
+);
+	wire [n:0] c;
+	
+	assign c[0] = ci;
+	assign co = c[n];
+	
+	generate 
+		genvar i;
+		for(i=0; i<n; i=i+1) 
+			`FA_CELL FA ( .COUT(c[i+1]), .CIN(c[i]), .A(a[i]), .B(b[i]), .SUM(s[i]) );
+   	endgenerate
+
+endmodule
+
+module csa8_4(
+    input [7:0] 	a, b,
+	input 			ci,
+	output [7:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [3:0] s10, s11;
+	rca #(4) A0  (.a(a[3:0]), .b(b[3:0]), .ci(ci), .co(co0), .s(s[3:0]) );
+	rca #(4) A10  (.a(a[7:4]), .b(b[7:4]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(4) A11  (.a(a[7:4]), .b(b[7:4]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [3:0] ( .X(s[7:4]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa16_8( 
+	input [15:0] 	a, b,
+	input 			ci,
+	output [15:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [7:0] s10, s11;
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [7:0] ( .X(s[15:8]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8x4( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	csa8_4 A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	csa8_4 A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	csa8_4 A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	csa8_4 A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	csa8_4 A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	csa8_4 A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	csa8_4 A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+
+// 32-bit Carry Select Adder 2x16rca
+module csa32_16( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+
+	wire co0, co10, co11;
+	wire [15:0] s10, s11;
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [15:0] ( .X(s[31:16]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(8) A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(8) A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(8) A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(8) A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+module csa64_16( 
+	input [63:0] 	a, b,
+	input 			ci,
+	output [63:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [15:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [15:0] ( .X(s[31:16]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(16) A20  (.a(a[47:32]), .b(b[47:32]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(16) A21  (.a(a[47:32]), .b(b[47:32]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [15:0] ( .X(s[47:32]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(16) A30  (.a(a[63:48]), .b(b[63:48]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(16) A31  (.a(a[63:48]), .b(b[63:48]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [15:0] ( .X(s[63:48]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[2]), .A1(c1[2]), .S(co2) );
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module sky130_csa (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = B_buf; 
+	
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add64(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+    endgenerate
+
+endmodule
+
+(* techmap_celltype = "$sub" *)
+module sky130_csa_sub (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = ~B_buf; 
+
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b1),  .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b1),.s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add32(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+    endgenerate
+
+endmodule
diff --git a/sky130/openlane/sky130_fd_sc_hs/csa_map.v b/sky130/openlane/sky130_fd_sc_hs/csa_map.v
new file mode 100644
index 0000000..39a6e64
--- /dev/null
+++ b/sky130/openlane/sky130_fd_sc_hs/csa_map.v
@@ -0,0 +1,257 @@
+`define TIE_CELL        sky130_fd_sc_hs__conb_1  
+`define FA_CELL         sky130_fd_sc_hs__fa_1  
+`define MUX2x1_CELL     sky130_fd_sc_hs__mux2_1
+
+// n-bit RCA using n FA instances
+module rca #(parameter n=32) ( 
+	input [n-1:0] 	a, b,
+	input 			ci,
+	output [n-1:0]	s,
+	output			co
+);
+	wire [n:0] c;
+	
+	assign c[0] = ci;
+	assign co = c[n];
+	
+	generate 
+		genvar i;
+		for(i=0; i<n; i=i+1) 
+			`FA_CELL FA ( .COUT(c[i+1]), .CIN(c[i]), .A(a[i]), .B(b[i]), .SUM(s[i]) );
+   	endgenerate
+
+endmodule
+
+module csa8_4(
+    input [7:0] 	a, b,
+	input 			ci,
+	output [7:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [3:0] s10, s11;
+	rca #(4) A0  (.a(a[3:0]), .b(b[3:0]), .ci(ci), .co(co0), .s(s[3:0]) );
+	rca #(4) A10  (.a(a[7:4]), .b(b[7:4]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(4) A11  (.a(a[7:4]), .b(b[7:4]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [3:0] ( .X(s[7:4]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa16_8( 
+	input [15:0] 	a, b,
+	input 			ci,
+	output [15:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [7:0] s10, s11;
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [7:0] ( .X(s[15:8]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8x4( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	csa8_4 A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	csa8_4 A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	csa8_4 A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	csa8_4 A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	csa8_4 A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	csa8_4 A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	csa8_4 A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+
+// 32-bit Carry Select Adder 2x16rca
+module csa32_16( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+
+	wire co0, co10, co11;
+	wire [15:0] s10, s11;
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [15:0] ( .X(s[31:16]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(8) A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(8) A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(8) A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(8) A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+module csa64_16( 
+	input [63:0] 	a, b,
+	input 			ci,
+	output [63:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [15:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [15:0] ( .X(s[31:16]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(16) A20  (.a(a[47:32]), .b(b[47:32]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(16) A21  (.a(a[47:32]), .b(b[47:32]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [15:0] ( .X(s[47:32]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(16) A30  (.a(a[63:48]), .b(b[63:48]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(16) A31  (.a(a[63:48]), .b(b[63:48]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [15:0] ( .X(s[63:48]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[2]), .A1(c1[2]), .S(co2) );
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module sky130_csa (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = B_buf; 
+	
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add64(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+    endgenerate
+
+endmodule
+
+(* techmap_celltype = "$sub" *)
+module sky130_csa_sub (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = ~B_buf; 
+
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b1),  .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b1),.s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add32(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+    endgenerate
+
+endmodule
diff --git a/sky130/openlane/sky130_fd_sc_hvl/csa_map.v b/sky130/openlane/sky130_fd_sc_hvl/csa_map.v
new file mode 100644
index 0000000..1c7c098
--- /dev/null
+++ b/sky130/openlane/sky130_fd_sc_hvl/csa_map.v
@@ -0,0 +1,257 @@
+`define TIE_CELL        sky130_fd_sc_hvl__conb_1  
+`define FA_CELL         sky130_fd_sc_hvl__fa_1  
+`define MUX2x1_CELL     sky130_fd_sc_hvl__mux2_1
+
+// n-bit RCA using n FA instances
+module rca #(parameter n=32) ( 
+	input [n-1:0] 	a, b,
+	input 			ci,
+	output [n-1:0]	s,
+	output			co
+);
+	wire [n:0] c;
+	
+	assign c[0] = ci;
+	assign co = c[n];
+	
+	generate 
+		genvar i;
+		for(i=0; i<n; i=i+1) 
+			`FA_CELL FA ( .COUT(c[i+1]), .CIN(c[i]), .A(a[i]), .B(b[i]), .SUM(s[i]) );
+   	endgenerate
+
+endmodule
+
+module csa8_4(
+    input [7:0] 	a, b,
+	input 			ci,
+	output [7:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [3:0] s10, s11;
+	rca #(4) A0  (.a(a[3:0]), .b(b[3:0]), .ci(ci), .co(co0), .s(s[3:0]) );
+	rca #(4) A10  (.a(a[7:4]), .b(b[7:4]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(4) A11  (.a(a[7:4]), .b(b[7:4]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [3:0] ( .X(s[7:4]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa16_8( 
+	input [15:0] 	a, b,
+	input 			ci,
+	output [15:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [7:0] s10, s11;
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [7:0] ( .X(s[15:8]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8x4( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	csa8_4 A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	csa8_4 A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	csa8_4 A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	csa8_4 A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	csa8_4 A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	csa8_4 A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	csa8_4 A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+
+// 32-bit Carry Select Adder 2x16rca
+module csa32_16( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+
+	wire co0, co10, co11;
+	wire [15:0] s10, s11;
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [15:0] ( .X(s[31:16]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(8) A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(8) A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(8) A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(8) A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+module csa64_16( 
+	input [63:0] 	a, b,
+	input 			ci,
+	output [63:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [15:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [15:0] ( .X(s[31:16]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(16) A20  (.a(a[47:32]), .b(b[47:32]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(16) A21  (.a(a[47:32]), .b(b[47:32]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [15:0] ( .X(s[47:32]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(16) A30  (.a(a[63:48]), .b(b[63:48]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(16) A31  (.a(a[63:48]), .b(b[63:48]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [15:0] ( .X(s[63:48]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[2]), .A1(c1[2]), .S(co2) );
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module sky130_csa (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = B_buf; 
+	
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add64(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+    endgenerate
+
+endmodule
+
+(* techmap_celltype = "$sub" *)
+module sky130_csa_sub (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = ~B_buf; 
+
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b1),  .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b1),.s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add32(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+    endgenerate
+
+endmodule
diff --git a/sky130/openlane/sky130_fd_sc_ls/csa_map.v b/sky130/openlane/sky130_fd_sc_ls/csa_map.v
new file mode 100644
index 0000000..9aa90c1
--- /dev/null
+++ b/sky130/openlane/sky130_fd_sc_ls/csa_map.v
@@ -0,0 +1,257 @@
+`define TIE_CELL        sky130_fd_sc_ls__conb_1  
+`define FA_CELL         sky130_fd_sc_ls__fa_1  
+`define MUX2x1_CELL     sky130_fd_sc_ls__mux2_1
+
+// n-bit RCA using n FA instances
+module rca #(parameter n=32) ( 
+	input [n-1:0] 	a, b,
+	input 			ci,
+	output [n-1:0]	s,
+	output			co
+);
+	wire [n:0] c;
+	
+	assign c[0] = ci;
+	assign co = c[n];
+	
+	generate 
+		genvar i;
+		for(i=0; i<n; i=i+1) 
+			`FA_CELL FA ( .COUT(c[i+1]), .CIN(c[i]), .A(a[i]), .B(b[i]), .SUM(s[i]) );
+   	endgenerate
+
+endmodule
+
+module csa8_4(
+    input [7:0] 	a, b,
+	input 			ci,
+	output [7:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [3:0] s10, s11;
+	rca #(4) A0  (.a(a[3:0]), .b(b[3:0]), .ci(ci), .co(co0), .s(s[3:0]) );
+	rca #(4) A10  (.a(a[7:4]), .b(b[7:4]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(4) A11  (.a(a[7:4]), .b(b[7:4]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [3:0] ( .X(s[7:4]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa16_8( 
+	input [15:0] 	a, b,
+	input 			ci,
+	output [15:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [7:0] s10, s11;
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [7:0] ( .X(s[15:8]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8x4( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	csa8_4 A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	csa8_4 A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	csa8_4 A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	csa8_4 A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	csa8_4 A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	csa8_4 A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	csa8_4 A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+
+// 32-bit Carry Select Adder 2x16rca
+module csa32_16( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+
+	wire co0, co10, co11;
+	wire [15:0] s10, s11;
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [15:0] ( .X(s[31:16]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(8) A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(8) A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(8) A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(8) A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+module csa64_16( 
+	input [63:0] 	a, b,
+	input 			ci,
+	output [63:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [15:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [15:0] ( .X(s[31:16]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(16) A20  (.a(a[47:32]), .b(b[47:32]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(16) A21  (.a(a[47:32]), .b(b[47:32]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [15:0] ( .X(s[47:32]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(16) A30  (.a(a[63:48]), .b(b[63:48]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(16) A31  (.a(a[63:48]), .b(b[63:48]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [15:0] ( .X(s[63:48]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[2]), .A1(c1[2]), .S(co2) );
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module sky130_csa (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = B_buf; 
+	
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add64(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+    endgenerate
+
+endmodule
+
+(* techmap_celltype = "$sub" *)
+module sky130_csa_sub (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = ~B_buf; 
+
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b1),  .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b1),.s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add32(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+    endgenerate
+
+endmodule
diff --git a/sky130/openlane/sky130_fd_sc_ms/csa_map.v b/sky130/openlane/sky130_fd_sc_ms/csa_map.v
new file mode 100644
index 0000000..867a13c
--- /dev/null
+++ b/sky130/openlane/sky130_fd_sc_ms/csa_map.v
@@ -0,0 +1,257 @@
+`define TIE_CELL        sky130_fd_sc_ms__conb_1  
+`define FA_CELL         sky130_fd_sc_ms__fa_1  
+`define MUX2x1_CELL     sky130_fd_sc_ms__mux2_1
+
+// n-bit RCA using n FA instances
+module rca #(parameter n=32) ( 
+	input [n-1:0] 	a, b,
+	input 			ci,
+	output [n-1:0]	s,
+	output			co
+);
+	wire [n:0] c;
+	
+	assign c[0] = ci;
+	assign co = c[n];
+	
+	generate 
+		genvar i;
+		for(i=0; i<n; i=i+1) 
+			`FA_CELL FA ( .COUT(c[i+1]), .CIN(c[i]), .A(a[i]), .B(b[i]), .SUM(s[i]) );
+   	endgenerate
+
+endmodule
+
+module csa8_4(
+    input [7:0] 	a, b,
+	input 			ci,
+	output [7:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [3:0] s10, s11;
+	rca #(4) A0  (.a(a[3:0]), .b(b[3:0]), .ci(ci), .co(co0), .s(s[3:0]) );
+	rca #(4) A10  (.a(a[7:4]), .b(b[7:4]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(4) A11  (.a(a[7:4]), .b(b[7:4]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [3:0] ( .X(s[7:4]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa16_8( 
+	input [15:0] 	a, b,
+	input 			ci,
+	output [15:0]	s,
+	output			co
+);
+
+    wire co0, co10, co11;
+	wire [7:0] s10, s11;
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [7:0] ( .X(s[15:8]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8x4( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	csa8_4 A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	csa8_4 A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	csa8_4 A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	csa8_4 A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	csa8_4 A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	csa8_4 A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	csa8_4 A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+
+// 32-bit Carry Select Adder 2x16rca
+module csa32_16( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+
+	wire co0, co10, co11;
+	wire [15:0] s10, s11;
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(1'b0), .co(co10), .s(s10) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(1'b1), .co(co11), .s(s11) );
+	`MUX2x1_CELL SMUX [15:0] ( .X(s[31:16]), .A0(s10), .A1(s11), .S(co0) );
+	`MUX2x1_CELL CMUX ( .X(co), .A0(co10), .A1(co11), .S(co0) );
+
+endmodule
+
+module csa32_8( 
+	input [31:0] 	a, b,
+	input 			ci,
+	output [31:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [7:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(8) A0  (.a(a[7:0]), .b(b[7:0]), .ci(ci), .co(co0), .s(s[7:0]) );
+	
+	rca #(8) A10  (.a(a[15:8]), .b(b[15:8]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(8) A11  (.a(a[15:8]), .b(b[15:8]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [7:0] ( .X(s[15:8]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(8) A20  (.a(a[23:16]), .b(b[23:16]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(8) A21  (.a(a[23:16]), .b(b[23:16]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [7:0] ( .X(s[23:16]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(8) A30  (.a(a[31:24]), .b(b[31:24]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(8) A31  (.a(a[31:24]), .b(b[31:24]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [7:0] ( .X(s[31:24]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[3]), .A1(c1[3]), .S(co2) );
+endmodule
+
+module csa64_16( 
+	input [63:0] 	a, b,
+	input 			ci,
+	output [63:0]	s,
+	output			co
+);
+	wire 		co0, co1, co2, co3;
+	wire [3:1] 	c0, c1;
+	wire [15:0] 	s0[3:1], s1[3:1];
+	wire		lo, hi; 
+
+	`TIE_CELL TIE (.LO(lo), .HI(hi));
+
+	rca #(16) A0  (.a(a[15:0]), .b(b[15:0]), .ci(ci), .co(co0), .s(s[15:0]) );
+	
+	rca #(16) A10  (.a(a[31:16]), .b(b[31:16]), .ci(lo), .co(c0[1]), .s(s0[1]) );
+	rca #(16) A11  (.a(a[31:16]), .b(b[31:16]), .ci(hi), .co(c1[1]), .s(s1[1]) );
+	`MUX2x1_CELL SMUX1 [15:0] ( .X(s[31:16]), .A0(s0[1]), .A1(s1[1]), .S(co0) );
+	`MUX2x1_CELL CMUX1 ( .X(co1), .A0(c0[1]), .A1(c1[1]), .S(co0) );
+	
+	rca #(16) A20  (.a(a[47:32]), .b(b[47:32]), .ci(lo), .co(c0[2]), .s(s0[2]) );
+	rca #(16) A21  (.a(a[47:32]), .b(b[47:32]), .ci(hi), .co(c1[2]), .s(s1[2]) );
+	`MUX2x1_CELL SMUX2 [15:0] ( .X(s[47:32]), .A0(s0[2]), .A1(s1[2]), .S(co1) );
+	`MUX2x1_CELL CMUX2 ( .X(co2), .A0(c0[2]), .A1(c1[2]), .S(co1) );
+
+	rca #(16) A30  (.a(a[63:48]), .b(b[63:48]), .ci(lo), .co(c0[3]), .s(s0[3]) );
+	rca #(16) A31  (.a(a[63:48]), .b(b[63:48]), .ci(hi), .co(c1[3]), .s(s1[3]) );
+	`MUX2x1_CELL SMUX3 [15:0] ( .X(s[63:48]), .A0(s0[3]), .A1(s1[3]), .S(co2) );
+	`MUX2x1_CELL CMUX3 ( .X(co), .A0(c0[2]), .A1(c1[2]), .S(co2) );
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module sky130_csa (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = B_buf; 
+	
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add64(.a(AA), .b(BB), .ci(1'b0), .s(Y));
+    endgenerate
+
+endmodule
+
+(* techmap_celltype = "$sub" *)
+module sky130_csa_sub (A, B, Y);
+	parameter A_SIGNED = 0;
+	parameter B_SIGNED = 0;
+	parameter A_WIDTH = 1;
+	parameter B_WIDTH = 1;
+	parameter Y_WIDTH = 1;
+
+	(* force_downto *)
+	input [A_WIDTH-1:0] A;
+	(* force_downto *)
+	input [B_WIDTH-1:0] B;
+	(* force_downto *)
+	output [Y_WIDTH-1:0] Y;
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] CO;
+
+	wire _TECHMAP_FAIL_ = (Y_WIDTH != 8) & (Y_WIDTH != 16) & (Y_WIDTH != 32) & (Y_WIDTH != 64);
+ 
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] A_buf, B_buf;
+	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] AA = A_buf;
+	(* force_downto *)
+	wire [Y_WIDTH-1:0] BB = ~B_buf; 
+
+    generate 
+        if (Y_WIDTH == 8)
+            csa8_4 add8(.a(AA), .b(BB), .ci(1'b1),  .s(Y));
+        else if (Y_WIDTH == 16)
+            csa16_8 add16(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+        else  if (Y_WIDTH == 32)
+            csa32_16 add32(.a(AA), .b(BB), .ci(1'b1),.s(Y));
+		else if (Y_WIDTH == 64)
+		    csa64_16 add32(.a(AA), .b(BB), .ci(1'b1), .s(Y));
+    endgenerate
+
+endmodule