rtl: Use specific cells for scanchain

- Add RAM IP block for RF/CSR storage
diff --git a/openlane/tiny_user_project/config.json b/openlane/tiny_user_project/config.json
deleted file mode 100644
index 94a3ced..0000000
--- a/openlane/tiny_user_project/config.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
-    "DESIGN_NAME": "tiny_user_project",
-    "DESIGN_IS_CORE": 0,
-    "VERILOG_FILES": [
-        "dir::../../verilog/rtl/top.v",
-        "dir::../../verilog/rtl/scanchain.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_top.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_synth_wrapper.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_mem_if.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_rf_if.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_rf_top.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_rf_ram.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_rf_ram_if.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_alu.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_ctrl.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_bufreg2.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_bufreg.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_immdec.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_decode.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_compdec.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_aligner.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_state.v",
-        "dir::../../verilog/blocks/serv/rtl/serv_csr.v",
-        "dir::../../verilog/blocks/serv/servant/servant_arbiter.v",
-        "dir::../../verilog/blocks/serv/servant/servant_mux.v",
-        "dir::../../verilog/blocks/serv/servant/servant_gpio.v",
-        "dir::../../verilog/rtl/defines.v",
-        "dir::../../verilog/rtl/tiny_user_project.v"
-    ],
-    "CLOCK_PERIOD": 24,
-    "CLOCK_PORT": "",
-    "CLOCK_NET": "",
-    "FP_SIZING": "absolute",
-    "DIE_AREA": "0 0 690 800",
-    "PL_BASIC_PLACEMENT": 0,
-    "PL_TARGET_DENSITY": 0.55,
-    "SYNTH_USE_PG_PINS_DEFINES": "USE_POWER_PINS",
-    "VDD_NETS": [
-        "vdd"
-    ],
-    "GND_NETS": [
-        "vss"
-    ],
-    "DIODE_INSERTION_STRATEGY": 4,
-    "RUN_CVC": 1,
-    "RUN_KLAYOUT_XOR": 0,
-    "RUN_KLAYOUT_DRC": 0,
-    "SYNTH_READ_BLACKBOX_LIB": 0,
-    "pdk::gf180mcuC": {
-        "STD_CELL_LIBRARY": "gf180mcu_fd_sc_mcu7t5v0",
-        "RT_MAX_LAYER": "Metal4",
-        "SYNTH_MAX_FANOUT": 4
-    }
-}
\ No newline at end of file
diff --git a/openlane/tiny_user_project/config.tcl b/openlane/tiny_user_project/config.tcl
new file mode 100644
index 0000000..f09173b
--- /dev/null
+++ b/openlane/tiny_user_project/config.tcl
@@ -0,0 +1,116 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+
+set script_dir [file dirname [file normalize [info script]/../../]]
+
+set ::env(DESIGN_NAME) tiny_user_project
+set ::env(DESIGN_IS_CORE) 0
+
+set ::env(PDK) "gf180mcuC"
+set ::env(STD_CELL_LIBRARY) "gf180mcu_fd_sc_mcu7t5v0"
+
+set ::env(RUN_KLAYOUT) 		0
+set ::env(CLOCK_TREE_SYNTH) 0
+set ::env(CLOCK_PORT) 		{io_in[8]}
+#set ::env(CLOCK_NET) ""
+set ::env(CLOCK_PERIOD) 	"45"
+
+set ::env(FP_IO_HLENGTH) 2
+set ::env(FP_IO_VLENGTH) 2
+
+## Floorplan
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 700 500"
+
+
+## Placement
+set ::env(PL_BASIC_PLACEMENT) 0
+set ::env(PL_TARGET_DENSITY) 0.55
+
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 1
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 1
+
+## Diode Insertion
+set ::env(DIODE_INSERTION_STRATEGY) 		4
+
+# connect to first digital rails
+set ::env(VDD_NETS) [list {VDD}]
+set ::env(GND_NETS) [list {VSS}]
+
+
+# save some time
+set ::env(RUN_KLAYOUT_XOR) 0
+set ::env(RUN_KLAYOUT_DRC) 0
+
+# don't put clock buffers on the outputs
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) 0
+    
+## Internal Macros
+set ::env(MACRO_PLACEMENT_CFG) $script_dir/macro.cfg
+
+set ::env(DESIGN_DIR) $script_dir/../../verilog 
+    
+    #$::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_ram.v \
+
+set ::env(VERILOG_FILES) "\
+    $::env(DESIGN_DIR)/rtl/defines.v \
+	$::env(DESIGN_DIR)/rtl/top.v \
+	$::env(DESIGN_DIR)/rtl/serv_rf_ram_gf180.v \
+    $::env(DESIGN_DIR)/rtl/scanchain_gf180.v \
+    $::env(DESIGN_DIR)/rtl/tiny_user_project.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_top.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_synth_wrapper.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_mem_if.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_if.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_top.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_rf_ram_if.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_alu.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_ctrl.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_bufreg2.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_bufreg.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_immdec.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_decode.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_compdec.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_aligner.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_state.v \
+    $::env(DESIGN_DIR)/blocks/serv/rtl/serv_csr.v \
+    $::env(DESIGN_DIR)/blocks/serv/servant/servant_arbiter.v \
+    $::env(DESIGN_DIR)/blocks/serv/servant/servant_mux.v \
+    $::env(DESIGN_DIR)/blocks/serv/servant/servant_gpio.v"
+
+set ::env(VERILOG_FILES_BLACKBOX) "\
+	$::env(DESIGN_DIR)/rtl/gf180mcu_fd_sc_mcu7t5v0_bb.v \
+	$::env(PDK_ROOT)/$::env(PDK)/libs.ref/gf180mcu_fd_ip_sram/verilog/gf180mcu_fd_ip_sram__sram256x8m8wm1.v"
+
+set ::env(EXTRA_LEFS) "\
+	$::env(PDK_ROOT)/$::env(PDK)/libs.ref/gf180mcu_fd_ip_sram/lef/gf180mcu_fd_ip_sram__sram256x8m8wm1.lef"
+set ::env(EXTRA_GDS_FILES) "\
+    $::env(PDK_ROOT)/$::env(PDK)/libs.ref/gf180mcu_fd_ip_sram/gds/gf180mcu_fd_ip_sram__sram256x8m8wm1.gds"
+set ::env(EXTRA_LIBS) "\
+    $::env(PDK_ROOT)/$::env(PDK)/libs.ref/gf180mcu_fd_ip_sram/liberty/gf180mcu_fd_ip_sram__sram256x8m8wm1__tt_025C_1v80.lib"
+
+set ::env(FP_PDN_MACRO_HOOKS) "\
+  u_cpu.rf_ram.RAM0 VDD VSS VDD VSS
+  "
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+set ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) 1
+
+## LVS
+set ::env(MAGIC_DRC_USE_GDS) 0
+set ::env(RUN_MAGIC_DRC) 0
+set ::env(QUIT_ON_MAGIC_DRC) 0
+
+set ::env(QUIT_ON_LVS_ERROR) 0
\ No newline at end of file
diff --git a/openlane/tiny_user_project/macro.cfg b/openlane/tiny_user_project/macro.cfg
new file mode 100644
index 0000000..ac06333
--- /dev/null
+++ b/openlane/tiny_user_project/macro.cfg
@@ -0,0 +1 @@
+mod.u_cpu.rf_ram.RAM0 50 50 FS
diff --git a/openlane/tiny_user_project/pdn.tcl b/openlane/tiny_user_project/pdn.tcl
new file mode 100644
index 0000000..8902373
--- /dev/null
+++ b/openlane/tiny_user_project/pdn.tcl
@@ -0,0 +1,165 @@
+# Power nets
+
+if { ! [info exists ::env(VDD_NET)] } {
+	set ::env(VDD_NET) $::env(VDD_PIN)
+}
+
+if { ! [info exists ::env(GND_NET)] } {
+	set ::env(GND_NET) $::env(GND_PIN)
+}
+
+if { [info exists ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS)] } {
+    if { $::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) == 1 } {
+        foreach power_pin $::env(STD_CELL_POWER_PINS) {
+            add_global_connection \
+                -net $::env(VDD_NET) \
+                -inst_pattern .* \
+                -pin_pattern $power_pin \
+                -power
+        }
+        foreach ground_pin $::env(STD_CELL_GROUND_PINS) {
+            add_global_connection \
+                -net $::env(GND_NET) \
+                -inst_pattern .* \
+                -pin_pattern $ground_pin \
+                -ground
+        }
+    }
+}
+
+if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 &&
+     [info exists ::env(FP_PDN_MACRO_HOOKS)]} {
+    set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","]
+    foreach pdn_hook $pdn_hooks {
+        set instance_name [lindex $pdn_hook 0]
+        set power_net [lindex $pdn_hook 1]
+        set ground_net [lindex $pdn_hook 2]
+        # This assumes the power pin and the power net have the same name.
+        # The macro hooks only give an instance name and not power pin names.
+
+        add_global_connection \
+            -net $power_net \
+            -inst_pattern $instance_name \
+            -pin_pattern $power_net \
+            -power
+
+        add_global_connection \
+            -net $ground_net \
+            -inst_pattern $instance_name \
+            -pin_pattern $ground_net \
+            -ground
+    }
+}
+
+set secondary []
+
+foreach net $::env(VDD_NETS) {
+    if { $net != $::env(VDD_NET)} {
+        lappend secondary $net
+
+        set db_net [[ord::get_db_block] findNet $net]
+        if {$db_net == "NULL"} {
+            set net [odb::dbNet_create [ord::get_db_block] $net]
+            $net setSpecial
+            $net setSigType "POWER"
+        }
+    }
+}
+
+foreach net $::env(GND_NETS) {
+    if { $net != $::env(GND_NET)} {
+        lappend secondary $net
+
+        set db_net [[ord::get_db_block] findNet $net]
+        if {$db_net == "NULL"} {
+            set net [odb::dbNet_create [ord::get_db_block] $net]
+            $net setSpecial
+            $net setSigType "GROUND"
+        }
+    }
+}
+
+set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET) \
+    -secondary_power $secondary
+
+# Assesses whether the design is the core of the chip or not based on the
+# value of $::env(DESIGN_IS_CORE) and uses the appropriate stdcell section
+if { $::env(DESIGN_IS_CORE) == 1 } {
+    # Used if the design is the core of the chip
+    define_pdn_grid \
+        -name stdcell_grid \
+        -starts_with POWER \
+        -voltage_domain CORE \
+        -pins "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)"
+
+    add_pdn_stripe \
+        -grid stdcell_grid \
+        -layer $::env(FP_PDN_LOWER_LAYER) \
+        -width $::env(FP_PDN_VWIDTH) \
+        -pitch $::env(FP_PDN_VPITCH) \
+        -offset $::env(FP_PDN_VOFFSET) \
+        -starts_with POWER -extend_to_core_ring
+
+    add_pdn_stripe \
+        -grid stdcell_grid \
+        -layer $::env(FP_PDN_UPPER_LAYER) \
+        -width $::env(FP_PDN_HWIDTH) \
+        -pitch $::env(FP_PDN_HPITCH) \
+        -offset $::env(FP_PDN_HOFFSET) \
+        -starts_with POWER -extend_to_core_ring
+
+    add_pdn_connect \
+        -grid stdcell_grid \
+        -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)"
+} else {
+    # Used if the design is a macro in the core
+    define_pdn_grid \
+        -name stdcell_grid \
+        -starts_with POWER \
+        -voltage_domain CORE \
+        -pins $::env(FP_PDN_LOWER_LAYER)
+
+    add_pdn_stripe \
+        -grid stdcell_grid \
+        -layer $::env(FP_PDN_LOWER_LAYER) \
+        -width $::env(FP_PDN_VWIDTH) \
+        -pitch $::env(FP_PDN_VPITCH) \
+        -offset $::env(FP_PDN_VOFFSET) \
+        -starts_with POWER
+}
+
+# Adds the standard cell rails if enabled.
+if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
+    add_pdn_stripe \
+        -grid stdcell_grid \
+        -layer $::env(FP_PDN_RAILS_LAYER) \
+        -width $::env(FP_PDN_RAIL_WIDTH) \
+        -followpins \
+        -starts_with POWER
+
+    add_pdn_connect \
+        -grid stdcell_grid \
+        -layers "$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)"
+} 
+
+
+# Adds the core ring if enabled.
+if { $::env(FP_PDN_CORE_RING) == 1 } {
+    add_pdn_ring \
+        -grid stdcell_grid \
+        -layers "$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)" \
+        -widths "$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)" \
+        -spacings "$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)" \
+        -core_offset "$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)"
+}
+
+define_pdn_grid \
+    -macro \
+    -default \
+    -name macro \
+    -starts_with POWER \
+    -halo "$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)"
+
+add_pdn_connect \
+    -grid macro \
+    -layers "Metal3 Metal4"
diff --git a/verilog/includes/includes.gl+sdf.caravel_user_project b/verilog/includes/includes.gl+sdf.caravel_user_project
index d68969d..79e7112 100644
--- a/verilog/includes/includes.gl+sdf.caravel_user_project
+++ b/verilog/includes/includes.gl+sdf.caravel_user_project
@@ -1,3 +1,6 @@
 // Caravel user project includes		
 $USER_PROJECT_VERILOG/gl/user_project_wrapper.v	     
 $USER_PROJECT_VERILOG/gl/user_module.v
+
+$(PDK_ROOT)/$(PDK)/libs.ref/gf180mcu_fd_sc_mcu7t5v0/verilog/gf180mcu_fd_sc_mcu7t5v0.v
+$(PDK_ROOT)/$(PDK)/libs.ref/gf180mcu_fd_ip_sram/verilog/gf180mcu_fd_ip_sram__sram512x8m8wm1.v
diff --git a/verilog/includes/includes.gl.caravel_user_project b/verilog/includes/includes.gl.caravel_user_project
index 0bbcd8d..3235e89 100644
--- a/verilog/includes/includes.gl.caravel_user_project
+++ b/verilog/includes/includes.gl.caravel_user_project
@@ -1,3 +1,9 @@
 # Caravel user project includes	     
 -v $(USER_PROJECT_VERILOG)/gl/user_project_wrapper.v	     
 -v $(USER_PROJECT_VERILOG)/gl/user_module.v     
+
+# STD CELLS - they need to be below the defines.v files 
+ -v $(PDK_ROOT)/$(PDK)/libs.ref/gf180mcu_fd_sc_mcu7t5v0/verilog/gf180mcu_fd_sc_mcu7t5v0.v
+
+## STD CELLS - they need to be below the defines.v files 
+ -v $(PDK_ROOT)/$(PDK)/libs.ref/gf180mcu_fd_ip_sram/verilog/gf180mcu_fd_ip_sram__sram512x8m8wm1.v
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index 898b5cb..cc97d00 100644
--- a/verilog/includes/includes.rtl.caravel_user_project
+++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -2,4 +2,10 @@
 -v $(USER_PROJECT_VERILOG)/rtl/user_project_wrapper.v	     
 -v $(USER_PROJECT_VERILOG)/rtl/user_module.v
 
- 
\ No newline at end of file
+ 
+# STD CELLS - they need to be below the defines.v files 
+ -v $(PDK_ROOT)/$(PDK)/libs.ref/gf180mcu_fd_sc_mcu7t5v0/verilog/gf180mcu_fd_sc_mcu7t5v0.v
+
+## STD CELLS - they need to be below the defines.v files 
+ -v $(PDK_ROOT)/$(PDK)/libs.ref/gf180mcu_fd_ip_sram/verilog/gf180mcu_fd_ip_sram__sram512x8m8wm1.v
+
diff --git a/verilog/rtl/gf180mcu_fd_sc_mcu7t5v0_bb.v b/verilog/rtl/gf180mcu_fd_sc_mcu7t5v0_bb.v
new file mode 100644
index 0000000..2a0fbda
--- /dev/null
+++ b/verilog/rtl/gf180mcu_fd_sc_mcu7t5v0_bb.v
@@ -0,0 +1,47 @@
+
+// Copyright 2022 GlobalFoundries PDK Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+module gf180mcu_fd_sc_mcu7t5v0__sdffq_1( SE, SI, D, CLK, Q, VDD, VSS );
+input CLK, D, SE, SI;
+inout VDD, VSS;
+output Q;
+reg notifier;
+endmodule
+
+module gf180mcu_fd_sc_mcu7t5v0__buf_1( I, Z, VDD, VSS );
+input I;
+inout VDD, VSS;
+output Z;
+endmodule
+
+module gf180mcu_fd_sc_mcu7t5v0__buf_2( I, Z, VDD, VSS );
+input I;
+inout VDD, VSS;
+output Z;
+endmodule
+
+module gf180mcu_fd_sc_mcu7t5v0__buf_4( I, Z, VDD, VSS );
+input I;
+inout VDD, VSS;
+output Z;
+endmodule
+
+module gf180mcu_fd_sc_mcu7t5v0__dffnq_1( CLKN, D, Q, VDD, VSS );
+input CLKN, D;
+inout VDD, VSS;
+output Q;
+reg notifier;
+endmodule
diff --git a/verilog/rtl/serv_rf_ram_gf180.v b/verilog/rtl/serv_rf_ram_gf180.v
new file mode 100644
index 0000000..653eaa2
--- /dev/null
+++ b/verilog/rtl/serv_rf_ram_gf180.v
@@ -0,0 +1,51 @@
+module serv_rf_ram
+  #(parameter width=0,
+    parameter csr_regs=4,
+    parameter depth=32*(32+csr_regs)/width)
+   (input wire i_clk,
+    input wire [$clog2(depth)-1:0] i_waddr,
+    input wire [width-1:0] 	   i_wdata,
+    input wire 			   i_wen,
+    input wire [$clog2(depth)-1:0] i_raddr,
+    output wire [width-1:0] 	   o_rdata);
+
+//   reg [width-1:0] 		   memory [0:depth-1];
+
+   wire [width-1:0] 		 data ;
+   reg [width-1:0] 		   rdata ;
+
+
+gf180mcu_fd_ip_sram__sram256x8m8wm1 RAM0 (
+	.CLK(i_clk),
+	.CEN(1'b0), // Active LOW chip enable
+	.GWEN(~i_wen), // Active LOW Write enable
+	.WEN({8{~i_wen}}), // Active LOW
+	.A(i_wen ? i_waddr : i_raddr),
+	.D(i_wdata),
+	.Q(data),
+	.VDD(1'b1),
+	.VSS(1'b0)
+);
+
+   /* Reads from reg x0 needs to return 0
+    Check that the part of the read address corresponding to the register
+    is zero and gate the output
+    width LSB of reg index $clog2(width)
+    2     4                1
+    4     3                2
+    8     2                3
+    16    1                4
+    32    0                5
+    */
+   reg regzero;
+
+   always @(posedge i_clk)
+     regzero <= !(|i_raddr[$clog2(depth)-1:5-$clog2(width)]);
+
+   always @(posedge i_clk)
+     if(~i_wen)
+       rdata <= data;
+
+   assign o_rdata = (i_wen ? rdata : data) & ~{width{regzero}};
+
+endmodule
diff --git a/verilog/rtl/top.v b/verilog/rtl/top.v
index 0095ec5..b3d84fd 100644
--- a/verilog/rtl/top.v
+++ b/verilog/rtl/top.v
@@ -69,7 +69,7 @@
     .PRE_REGISTER(1),
     .RESET_STRATEGY("MINI"),
     .WITH_CSR(1),
-    .RF_WIDTH(2))
+    .RF_WIDTH(8))
   u_cpu
   (
     .clk          (serv_clk),