Add files via upload
diff --git a/deps/timing-scripts/Dockerfile b/deps/timing-scripts/Dockerfile
new file mode 100644
index 0000000..4696aff
--- /dev/null
+++ b/deps/timing-scripts/Dockerfile
@@ -0,0 +1,6 @@
+from fedora:36
+
+RUN yum install -y yosys python3-pip && \
+ pip3 install click pyverilog && \
+ yum clean all && \
+ rm -rf /var/cache/yum
diff --git a/deps/timing-scripts/README.md b/deps/timing-scripts/README.md
new file mode 100644
index 0000000..2b39888
--- /dev/null
+++ b/deps/timing-scripts/README.md
@@ -0,0 +1,85 @@
+# Timing scripts
+
+A set of scripts for rcx and sta for caravel top level
+
+## Dependencies
+- Docker
+
+In case of not using the docker image:
+- `yosys`
+- Python modules:
+ - `click`
+
+
+## Prerequisites
+
+A set of exports are needed:
+```bash
+export CARAVEL_ROOT=${HOME}/caravel/
+export MCW_ROOT=${HOME}/caravel_mgmt_soc_litex/
+export CUP_ROOT=${HOME}/caravel_user_project/
+export TIMING_ROOT=${HOME}/timing-scripts/
+export PDK_ROOT=${HOME}/pdk/
+export PDK=sky130A
+export OPENLANE_IMAGE_NAME=efabless/openlane:4476a58407d670d251aa0be6a55e5391bb181c4e-amd64
+```
+
+## Usage
+
+### caravel_user_project
+
+1. After exporting the prerequisites, run:
+
+ ```
+ make -f timing.mk list-rcx
+ ```
+ You should get `rcx-user_project_wrapper` amongst others such as:
+
+ ```
+ rcx-buff_flash_clkrst
+ rcx-caravel
+ rcx-caravel_clocking
+ rcx-constant_block
+ rcx-digital_pll
+ rcx-gpio_control_block
+ rcx-gpio_defaults_block
+ rcx-gpio_logic_high
+ rcx-gpio_signal_buffering
+ rcx-gpio_signal_buffering_alt
+ rcx-housekeeping
+ rcx-mgmt_protect
+ rcx-mprj2_logic_high
+ rcx-mprj_logic_high
+ rcx-spare_logic_block
+ rcx-RAM256
+ rcx-mgmt_core_wrapper
+ rcx-user_proj_example
+ rcx-user_project_wrapper
+ ```
+
+2. extract multicorner spefs for `user_project_wrapper` and any other blocks inside:
+
+ ```
+ make -f timing.mk rcx-user_project_wrapper
+ make -f timing.mk rcx-user_proj_example
+ ```
+3. generate spef mapping file for caravel_user_project:
+
+ ```
+ python3 ./scripts/generate_spef_mapping -i ${CUP_ROOT}/verilog/gl/user_project_wrapper.v -o ${CUP_ROOT}/env/spef-mapping.tcl --project-root '$::env(CUP_ROOT)' --pdk-root ${PDK_ROOT} --pdk ${PDK}
+ ```
+
+4. run sta:
+
+ ```
+ make -f timing.mk caravel-timing-typ
+ make -f timing.mk caravel-timing-slow
+ make -f timing.mk caravel-timing-fast
+ ```
+
+## Limitations
+
+- Makefile
+- Makefile
+- Assumes a fixed folder structure for the exported directories
+- Probably a lot of corner cases that weren't considered
diff --git a/deps/timing-scripts/env/caravel_spef_mapping-mpw2-calibre.tcl b/deps/timing-scripts/env/caravel_spef_mapping-mpw2-calibre.tcl
new file mode 100644
index 0000000..87eeb62
--- /dev/null
+++ b/deps/timing-scripts/env/caravel_spef_mapping-mpw2-calibre.tcl
@@ -0,0 +1,101 @@
+set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/xres_buf.spef
+set spef_mapping(mgmt_buffers/powergood_check) $::env(CARAVEL_ROOT)/spef/mgmt_protect_hv.spef
+set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/chip_io.spef
+set spef_mapping(mgmt_buffers/mprj2_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj2_logic_high.spef
+set spef_mapping(mgmt_buffers/mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj_logic_high.spef
+
+#set spef_mapping(por) $::env(CARAVEL_ROOT)/spef/simple_por.spef
+
+# error in rcx extraction for the section/paragraph below
+# [ERROR ODB-0299] Via via3_320_320 has only 2 shapes and must have at least three.
+
+set spef_mapping(gpio_defaults_block_0) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_1) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_2) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_3) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_4) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+
+set spef_mapping(gpio_defaults_block_10) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_11) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_12) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_13) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_14) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_15) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_16) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_17) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_18) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_19) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_20) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_21) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_22) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_23) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_24) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_25) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_26) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_27) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_28) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_29) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_30) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_31) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_32) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_33) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_34) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_35) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_36) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_37) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_5) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_6) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_7) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_8) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_9) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_control_bidir_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[11]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[12]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[13]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[14]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[15]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(housekeeping) $::env(CARAVEL_ROOT)/spef/housekeeping.spef
+set spef_mapping(mgmt_buffers) $::env(CARAVEL_ROOT)/spef/mgmt_protect.spef
+set spef_mapping(pll) $::env(CARAVEL_ROOT)/spef/digital_pll.spef
+set spef_mapping(spare_logic[0]) $::env(CARAVEL_ROOT)/spef/spare_logic_block.spef
+set spef_mapping(spare_logic[1]) $::env(CARAVEL_ROOT)/spef/spare_logic_block.spef
+set spef_mapping(spare_logic[2]) $::env(CARAVEL_ROOT)/spef/spare_logic_block.spef
+set spef_mapping(spare_logic[3]) $::env(CARAVEL_ROOT)/spef/spare_logic_block.spef
+
+set spef_mapping(clocking) $::env(CARAVEL_ROOT)/spef/caravel_clocking.spef
+
+set spef_mapping(soc) $::env(MCW_ROOT)/spef/mgmt_core_wrapper.spef
+set spef_mapping(soc/DFFRAM_0) $::env(MCW_ROOT)/spef/DFFRAM.spef
+set spef_mapping(soc/core) $::env(MCW_ROOT)/spef/mgmt_core.spef
diff --git a/deps/timing-scripts/env/caravel_spef_mapping-mpw2.tcl b/deps/timing-scripts/env/caravel_spef_mapping-mpw2.tcl
new file mode 100644
index 0000000..fade71c
--- /dev/null
+++ b/deps/timing-scripts/env/caravel_spef_mapping-mpw2.tcl
@@ -0,0 +1,99 @@
+set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/xres_buf.spef
+set spef_mapping(mgmt_buffers/powergood_check) $::env(CARAVEL_ROOT)/spef/mgmt_protect_hv.spef
+set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/chip_io.spef
+set spef_mapping(mgmt_buffers/mprj2_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj2_logic_high.spef
+set spef_mapping(mgmt_buffers/mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj_logic_high.spef
+
+#set spef_mapping(por) $::env(CARAVEL_ROOT)/spef/simple_por.spef
+
+# error in rcx extraction for the section/paragraph below
+# [ERROR ODB-0299] Via via3_320_320 has only 2 shapes and must have at least three.
+
+set spef_mapping(gpio_defaults_block_0) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_1) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_2) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_3) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_4) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+
+set spef_mapping(gpio_defaults_block_10) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_11) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_12) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_13) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_14) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_15) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_16) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_17) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_18) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_19) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_20) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_21) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_22) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_23) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_24) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_25) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_26) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_27) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_28) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_29) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_30) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_31) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_32) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_33) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_34) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_35) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_36) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_37) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_5) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_6) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_7) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_8) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_9) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[11]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[12]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[13]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[14]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[15]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(housekeeping) $::env(CARAVEL_ROOT)/spef/housekeeping_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(mgmt_buffers) $::env(CARAVEL_ROOT)/spef/mgmt_protect_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(pll) $::env(CARAVEL_ROOT)/spef/digital_pll_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(spare_logic[0]) $::env(CARAVEL_ROOT)/spef/spare_logic_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(spare_logic[1]) $::env(CARAVEL_ROOT)/spef/spare_logic_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(spare_logic[2]) $::env(CARAVEL_ROOT)/spef/spare_logic_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(spare_logic[3]) $::env(CARAVEL_ROOT)/spef/spare_logic_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+
+set spef_mapping(soc) $::env(MCW_ROOT)/spef/mgmt_core_wrapper_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(soc/DFFRAM_0) $::env(MCW_ROOT)/spef/DFFRAM_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(soc/core) $::env(MCW_ROOT)/spef/mgmt_core_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
diff --git a/deps/timing-scripts/env/caravel_spef_mapping-mpw5-calibre.tcl b/deps/timing-scripts/env/caravel_spef_mapping-mpw5-calibre.tcl
new file mode 100644
index 0000000..c6c8a54
--- /dev/null
+++ b/deps/timing-scripts/env/caravel_spef_mapping-mpw5-calibre.tcl
@@ -0,0 +1,90 @@
+set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/xres_buf.spef
+set spef_mapping(mgmt_buffers/powergood_check) $::env(CARAVEL_ROOT)/spef/mgmt_protect_hv.spef
+set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/chip_io.spef
+
+# should double check this
+set spef_mapping(gpio_defaults_block_0[0]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_0[1]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+
+set spef_mapping(soc/DFFRAM_0) $::env(MCW_ROOT)/spef/DFFRAM.spef
+set spef_mapping(soc/core) $::env(MCW_ROOT)/spef/mgmt_core.spef
+set spef_mapping(soc) $::env(MCW_ROOT)/spef/mgmt_core_wrapper.spef
+set spef_mapping(pll) $::env(CARAVEL_ROOT)/spef/digital_pll.spef
+set spef_mapping(housekeeping) $::env(CARAVEL_ROOT)/spef/housekeeping.spef
+set spef_mapping(mgmt_buffers/mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj_logic_high.spef
+set spef_mapping(mgmt_buffers/mprj2_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj2_logic_high.spef
+set spef_mapping(mgmt_buffers) $::env(CARAVEL_ROOT)/spef/mgmt_protect.spef
+set spef_mapping(gpio_control_bidir_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_bidir_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_1a[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[11]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[12]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[13]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[14]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[15]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_control_in_2[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+set spef_mapping(gpio_defaults_block_5) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_6) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_7) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_8) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_9) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_10) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_11) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_12) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_13) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_14) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_15) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_16) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_17) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_18) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_19) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_20) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_21) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_22) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_23) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_24) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_25) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_26) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_27) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_28) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_29) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_30) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_31) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_32) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_33) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_34) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_35) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_36) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+set spef_mapping(gpio_defaults_block_37) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef
+
diff --git a/deps/timing-scripts/env/caravel_spef_mapping-mpw7.tcl b/deps/timing-scripts/env/caravel_spef_mapping-mpw7.tcl
new file mode 100644
index 0000000..e12e189
--- /dev/null
+++ b/deps/timing-scripts/env/caravel_spef_mapping-mpw7.tcl
@@ -0,0 +1,136 @@
+set SPEF_MAPPING_POSTFIX ".$::env(RCX_CORNER).spef"
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/gpio_control_block/openlane-signoff/spef/"
+set spef_mapping(\gpio_control_bidir_1[0]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_bidir_1[1]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_bidir_2[0]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_bidir_2[1]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_bidir_2[2]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[0]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[10]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[1]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[2]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[3]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[4]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[5]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[6]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[7]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[8]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1[9]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1a[0]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1a[1]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1a[2]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1a[3]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1a[4]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_1a[5]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[0]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[10]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[11]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[12]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[13]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[14]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[15]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[1]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[2]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[3]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[4]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[5]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[6]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[7]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[8]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\gpio_control_in_2[9]) ${SPEF_MAPPING_PREFIX}gpio_control_block${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/spare_logic_block/openlane-signoff/spef/"
+set spef_mapping(\spare_logic[0]) ${SPEF_MAPPING_PREFIX}spare_logic_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\spare_logic[1]) ${SPEF_MAPPING_PREFIX}spare_logic_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\spare_logic[2]) ${SPEF_MAPPING_PREFIX}spare_logic_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(\spare_logic[3]) ${SPEF_MAPPING_PREFIX}spare_logic_block${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/caravel_clocking/openlane-signoff/spef/"
+set spef_mapping(clock_ctrl) ${SPEF_MAPPING_PREFIX}caravel_clocking${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/buff_flash_clkrst/openlane-signoff/spef/"
+set spef_mapping(flash_clkrst_buffers) ${SPEF_MAPPING_PREFIX}buff_flash_clkrst${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/gpio_defaults_block/openlane-signoff/spef/"
+set spef_mapping(gpio_defaults_block_0) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_1) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_2) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_3) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_4) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_5) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_6) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_7) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_8) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_9) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_10) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_11) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_12) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_13) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_14) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_15) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_16) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_17) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_18) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_19) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_20) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_21) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_22) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_23) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_24) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_25) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_26) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_27) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_28) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_29) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_30) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_31) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_32) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_33) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_34) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_35) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_36) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(gpio_defaults_block_37) ${SPEF_MAPPING_PREFIX}gpio_defaults_block${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/housekeeping/openlane-signoff/spef/"
+set spef_mapping(housekeeping) ${SPEF_MAPPING_PREFIX}housekeeping${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/mgmt_protect/openlane-signoff/spef/"
+set spef_mapping(mgmt_buffers) ${SPEF_MAPPING_PREFIX}mgmt_protect${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CUP_ROOT)/signoff/user_project_wrapper/openlane-signoff/spef/"
+set spef_mapping(mprj) ${SPEF_MAPPING_PREFIX}user_project_wrapper${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/chip_io/openlane-signoff/spef/"
+set spef_mapping(padframe) ${SPEF_MAPPING_PREFIX}chip_io${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/digital_pll/openlane-signoff/spef/"
+set spef_mapping(pll) ${SPEF_MAPPING_PREFIX}digital_pll${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/simple_por/openlane-signoff/spef/"
+set spef_mapping(por) ${SPEF_MAPPING_PREFIX}simple_por${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/xres_buf/openlane-signoff/spef/"
+set spef_mapping(rstb_level) ${SPEF_MAPPING_PREFIX}xres_buf${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/gpio_signal_buffering/openlane-signoff/spef/"
+set spef_mapping(sigbuf) ${SPEF_MAPPING_PREFIX}gpio_signal_buffering${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/user_id_programming/openlane-signoff/spef/"
+set spef_mapping(user_id_value) ${SPEF_MAPPING_PREFIX}user_id_programming${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(MCW_ROOT)/signoff/mgmt_core_wrapper/openlane-signoff/spef/"
+set spef_mapping(soc) ${SPEF_MAPPING_PREFIX}mgmt_core_wrapper${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(CARAVEL_ROOT)/signoff/constant_block/openlane-signoff/spef/"
+set spef_mapping(padframe/\constant_value_inst[0]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(padframe/\constant_value_inst[1]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(padframe/\constant_value_inst[2]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(padframe/\constant_value_inst[3]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(padframe/\constant_value_inst[4]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(padframe/\constant_value_inst[5]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+set spef_mapping(padframe/\constant_value_inst[6]) ${SPEF_MAPPING_PREFIX}constant_block${SPEF_MAPPING_POSTFIX}
+
+set SPEF_MAPPING_PREFIX "$::env(MCW_ROOT)/signoff/RAM256/openlane-signoff/spef/"
+set spef_mapping(soc/\core.RAM256) ${SPEF_MAPPING_PREFIX}RAM256${SPEF_MAPPING_POSTFIX}
+set SPEF_MAPPING_PREFIX "$::env(MCW_ROOT)/signoff/RAM128/openlane-signoff/spef/"
+set spef_mapping(soc/\core.RAM128) ${SPEF_MAPPING_PREFIX}RAM128${SPEF_MAPPING_POSTFIX}
diff --git a/deps/timing-scripts/env/caravel_spef_mapping.tcl b/deps/timing-scripts/env/caravel_spef_mapping.tcl
new file mode 100644
index 0000000..f287952
--- /dev/null
+++ b/deps/timing-scripts/env/caravel_spef_mapping.tcl
@@ -0,0 +1,90 @@
+set spef_mapping(rstb_level) $::env(CARAVEL_ROOT)/spef/xres_buf.spef
+set spef_mapping(mgmt_buffers/powergood_check) $::env(CARAVEL_ROOT)/spef/mgmt_protect_hv.spef
+set spef_mapping(padframe) $::env(CARAVEL_ROOT)/spef/chip_io.spef
+
+# should double check this
+set spef_mapping(gpio_defaults_block_0[0]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_0[1]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef
+set spef_mapping(gpio_defaults_block_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+set spef_mapping(gpio_defaults_block_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef
+
+set spef_mapping(soc/DFFRAM_0) $::env(MCW_ROOT)/spef/DFFRAM_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(soc/core) $::env(MCW_ROOT)/spef/mgmt_core_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(soc) $::env(MCW_ROOT)/spef/mgmt_core_wrapper_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(pll) $::env(CARAVEL_ROOT)/spef/digital_pll_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(housekeeping) $::env(CARAVEL_ROOT)/spef/housekeeping_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(mgmt_buffers/mprj_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj_logic_high_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(mgmt_buffers/mprj2_logic_high_inst) $::env(CARAVEL_ROOT)/spef/mprj2_logic_high_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(mgmt_buffers) $::env(CARAVEL_ROOT)/spef/mgmt_protect_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_bidir_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_1a[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[0]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[10]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[11]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[12]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[13]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[14]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[15]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[1]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[2]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[3]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[4]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[5]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[6]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[7]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[8]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_control_in_2[9]) $::env(CARAVEL_ROOT)/spef/gpio_control_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_5) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_6) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_7) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_8) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_9) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_10) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_11) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_12) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_13) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_14) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_15) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_16) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_17) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_18) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_19) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_20) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_21) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_22) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_23) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_24) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_25) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_26) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_27) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_28) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_29) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_30) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_31) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_32) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_33) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_34) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_35) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_36) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+set spef_mapping(gpio_defaults_block_37) $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_$::env(RCX_CORNER)_$::env(LIB_CORNER).spef
+
diff --git a/deps/timing-scripts/env/common.tcl b/deps/timing-scripts/env/common.tcl
new file mode 100644
index 0000000..b06a6f7
--- /dev/null
+++ b/deps/timing-scripts/env/common.tcl
@@ -0,0 +1,134 @@
+set std_cell_library "sky130_fd_sc_hd"
+set special_voltage_library "sky130_fd_sc_hvl"
+set io_library "sky130_fd_io"
+set primitives_library "sky130_fd_pr"
+set ef_io_library "sky130_ef_io"
+set ef_cell_library "sky130_ef_sc_hd"
+
+set signal_layer "met2"
+set clock_layer "met5"
+
+set extra_lefs "
+[glob $::env(CARAVEL_ROOT)/lef/*.lef]
+[glob $::env(MCW_ROOT)/lef/*.lef]
+[glob $::env(CUP_ROOT)/lef/*.lef]"
+
+set tech_lef $::env(PDK_REF_PATH)/$std_cell_library/techlef/${std_cell_library}__$::env(RCX_CORNER).tlef
+set cells_lef $::env(PDK_REF_PATH)/$std_cell_library/lef/$std_cell_library.lef
+set io_lef $::env(PDK_REF_PATH)/$io_library/lef/$io_library.lef
+set ef_io_lef $::env(PDK_REF_PATH)/$io_library/lef/$ef_io_library.lef
+set ef_cells_lef $::env(PDK_REF_PATH)/$std_cell_library/lef/$ef_cell_library.lef
+
+set lefs [list \
+ $tech_lef \
+ $cells_lef \
+ $io_lef \
+ $ef_cells_lef \
+ $ef_io_lef
+]
+# search order:
+# cup -> mcw -> caravel
+
+# file mkdir $::env(CUP_ROOT)/spef/
+# file mkdir $::env(CARAVEL_ROOT)/spef/
+# file mkdir $::env(MCW_ROOT)/spef/
+
+set def $::env(CUP_ROOT)/def/$::env(BLOCK).def
+set spef $::env(CUP_ROOT)/signoff/$::env(BLOCK)/openlane-signoff/spef/$::env(BLOCK).$::env(RCX_CORNER).spef
+set sdc $::env(CUP_ROOT)/sdc/$::env(BLOCK).sdc
+set sdf $::env(CUP_ROOT)/signoff/$::env(BLOCK)/openlane-signoff/sdf/$::env(RCX_CORNER)/$::env(BLOCK).$::env(LIB_CORNER)$::env(LIB_CORNER).$::env(RCX_CORNER).sdf
+if { ![file exists $def] } {
+ set def $::env(MCW_ROOT)/def/$::env(BLOCK).def
+ set spef $::env(MCW_ROOT)/signoff/$::env(BLOCK)/openlane-signoff/spef/$::env(BLOCK).$::env(RCX_CORNER).spef
+ set sdc $::env(MCW_ROOT)/sdc/$::env(BLOCK).sdc
+ set sdf $::env(MCW_ROOT)/signoff/$::env(BLOCK)/openlane-signoff/sdf/$::env(RCX_CORNER)/$::env(BLOCK).$::env(LIB_CORNER)$::env(LIB_CORNER).$::env(RCX_CORNER).sdf
+}
+if { ![file exists $def] } {
+ set def $::env(CARAVEL_ROOT)/def/$::env(BLOCK).def
+ set spef $::env(CARAVEL_ROOT)/signoff/$::env(BLOCK)/openlane-signoff/spef/$::env(BLOCK).$::env(RCX_CORNER).spef
+ set sdc $::env(CARAVEL_ROOT)/sdc/$::env(BLOCK).sdc
+ set sdf $::env(CARAVEL_ROOT)/signoff/$::env(BLOCK)/openlane-signoff/sdf/$::env(RCX_CORNER)/$::env(BLOCK).$::env(LIB_CORNER)$::env(LIB_CORNER).$::env(RCX_CORNER).sdf
+}
+
+file mkdir [file dirname $spef]
+file mkdir [file dirname $sdf]
+set block $::env(BLOCK)
+if { $::env(PDK) == "sky130A" } {
+ set rcx_rules_file $::env(PDK_TECH_PATH)/openlane/rules.openrcx.$::env(PDK).$::env(RCX_CORNER).calibre
+} elseif { $::env(PDK) == "sky130B" } {
+ set rcx_rules_file $::env(PDK_TECH_PATH)/openlane/rules.openrcx.$::env(PDK).$::env(RCX_CORNER).spef_extractor
+} else {
+ puts "no extraction rules file set for $::env(PDK) exiting.."
+ exit 1
+}
+set merged_lef $::env(CARAVEL_ROOT)/tmp/merged_lef-$::env(RCX_CORNER).lef
+
+set sram_lef $::env(PDK_REF_PATH)/sky130_sram_macros/lef/sky130_sram_2kbyte_1rw1r_32x512_8.lef
+
+# order matter
+set caravel_root "[file normalize $::env(CARAVEL_ROOT)]"
+set mcw_root "[file normalize $::env(MCW_ROOT)]"
+set cup_root "[file normalize $::env(CUP_ROOT)]"
+set verilogs "
+[glob $mcw_root/verilog/gl/*]
+[glob $caravel_root/verilog/gl/*]
+[glob $cup_root/verilog/gl/*]
+"
+
+set verilog_exceptions [list \
+ "$caravel_root/verilog/gl/__user_analog_project_wrapper.v" \
+ "$caravel_root/verilog/gl/caravel-signoff.v" \
+ "$caravel_root/verilog/gl/caravan-signoff.v" \
+ "$caravel_root/verilog/gl/__user_project_wrapper.v" \
+ ]
+
+foreach verilog_exception $verilog_exceptions {
+ puts "verilog exception: $verilog_exception"
+ set verilogs [regsub "$verilog_exception" "$verilogs" " "]
+}
+
+proc puts_list {arg} {
+ foreach element $arg {
+ puts $element
+ }
+}
+
+proc read_libs {arg} {
+ set libs [split [regexp -all -inline {\S+} $arg]]
+ foreach liberty $libs {
+ puts $liberty
+ read_liberty $liberty
+ }
+}
+
+proc read_verilogs {arg} {
+ set verilogs [split [regexp -all -inline {\S+} $arg]]
+ foreach verilog $verilogs {
+ puts $verilog
+ read_verilog $verilog
+ }
+}
+
+proc read_spefs {} {
+ global spef_mapping
+ foreach key [array names spef_mapping] {
+ puts "read_spef -path $key $spef_mapping($key)"
+ read_spef -path $key $spef_mapping($key)
+ }
+}
+
+proc run_puts {arg} {
+ puts "exec> $arg"
+ eval "{*}$arg"
+}
+
+proc run_puts_logs {arg log} {
+ set output [open "$log" w+]
+ puts $output "exec> $arg"
+ puts $output "design: $::env(BLOCK)"
+ set timestr [exec date]
+ puts $output "time: $timestr\n"
+ close $output
+ puts "exec> $arg >> $log"
+ eval "{*}$arg >> $log"
+}
diff --git a/deps/timing-scripts/env/f.tcl b/deps/timing-scripts/env/f.tcl
new file mode 100644
index 0000000..867427b
--- /dev/null
+++ b/deps/timing-scripts/env/f.tcl
@@ -0,0 +1,20 @@
+set libs "
+ $::env(PDK_REF_PATH)/${std_cell_library}/lib/${std_cell_library}__ff_n40C_1v95.lib
+ $::env(PDK_REF_PATH)/${special_voltage_library}/lib/${special_voltage_library}__ff_n40C_5v50.lib
+ $::env(PDK_REF_PATH)/${special_voltage_library}/lib/${special_voltage_library}__ff_n40C_4v40_lv1v95.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_gpiov2_ff_ff_n40C_1v95_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_ground_hvc_wpad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_ground_lvc_wpad_ff_n40C_1v95_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_power_lvc_wpad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_xres4v2_ff_ff_n40C_1v95_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__gpiov2_pad_wrapped_ff_ff_n40C_1v95_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vccd_lvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vdda_hvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssa_hvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vddio_hvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssio_hvc_clamped_pad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssd_lvc_clamped3_pad_ff_n40C_1v95_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ff_n40C_1v95_5v50_5v50.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssd_lvc_clamped_pad_ff_n40C_1v95_5v50.lib
+ $::env(PDK_REF_PATH)/sky130_sram_macros/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
+"
diff --git a/deps/timing-scripts/env/s.tcl b/deps/timing-scripts/env/s.tcl
new file mode 100644
index 0000000..9b61eeb
--- /dev/null
+++ b/deps/timing-scripts/env/s.tcl
@@ -0,0 +1,21 @@
+set libs "
+ $::env(PDK_REF_PATH)/${std_cell_library}/lib/${std_cell_library}__ss_100C_1v60.lib
+ $::env(PDK_REF_PATH)/${special_voltage_library}/lib/${special_voltage_library}__ss_100C_1v65.lib
+ $::env(PDK_REF_PATH)/${special_voltage_library}/lib/${special_voltage_library}__ss_100C_1v65_lv1v60.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_gpiov2_ss_ss_100C_1v60_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_ground_hvc_wpad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_ground_lvc_wpad_ss_100C_1v60_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_power_lvc_wpad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_xres4v2_ss_ss_100C_1v60_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__gpiov2_pad_wrapped_ss_ss_100C_1v60_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vccd_lvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vdda_hvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssa_hvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vddio_hvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssio_hvc_clamped_pad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssd_lvc_clamped3_pad_ss_100C_1v60_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vccd_lvc_clamped3_pad_ss_100C_1v60_3v00_3v00.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssd_lvc_clamped_pad_ss_100C_1v60_3v00.lib
+ $::env(PDK_REF_PATH)/sky130_sram_macros/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
+"
+
diff --git a/deps/timing-scripts/env/t.tcl b/deps/timing-scripts/env/t.tcl
new file mode 100644
index 0000000..c9eea15
--- /dev/null
+++ b/deps/timing-scripts/env/t.tcl
@@ -0,0 +1,21 @@
+set libs "
+ $::env(PDK_REF_PATH)/${std_cell_library}/lib/${std_cell_library}__tt_025C_1v80.lib
+ $::env(PDK_REF_PATH)/${special_voltage_library}/lib/${special_voltage_library}__tt_025C_3v30.lib
+ $::env(PDK_REF_PATH)/${special_voltage_library}/lib/${special_voltage_library}__tt_025C_3v30_lv1v80.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_gpiov2_tt_tt_025C_1v80_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_ground_hvc_wpad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_ground_lvc_wpad_tt_025C_1v80_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_power_lvc_wpad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_fd_io__top_xres4v2_tt_tt_025C_1v80_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__gpiov2_pad_tt_tt_025C_1v80_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vccd_lvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vdda_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssa_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vddio_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssio_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssd_lvc_clamped3_pad_tt_025C_1v80_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vccd_lvc_clamped3_pad_tt_025C_1v80_3v30_3v30.lib
+ $::env(PDK_REF_PATH)/${io_library}/lib/sky130_ef_io__vssd_lvc_clamped_pad_tt_025C_1v80_3v30.lib
+ $::env(PDK_REF_PATH)/sky130_sram_macros/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
+"
+
diff --git a/deps/timing-scripts/requirements.txt b/deps/timing-scripts/requirements.txt
new file mode 100644
index 0000000..dca9a90
--- /dev/null
+++ b/deps/timing-scripts/requirements.txt
@@ -0,0 +1 @@
+click
diff --git a/deps/timing-scripts/scripts/compare_reports.py b/deps/timing-scripts/scripts/compare_reports.py
new file mode 100644
index 0000000..1276473
--- /dev/null
+++ b/deps/timing-scripts/scripts/compare_reports.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+import click
+
+from report import Report
+
+
+@click.command(
+ help="""
+ attempts to compare two sta reports
+ """
+)
+@click.option("--first", "-f", required=True, type=str)
+@click.option("--first-label", default="first", type=str)
+@click.option("--second-label", default="second", type=str)
+@click.option("--second", "-s", required=True, type=str)
+@click.option("--output", "-o", required=True, type=str)
+def main(first, second, output, first_label, second_label):
+ first_report = Report(first)
+ second_report = Report(second)
+
+ print(f"{first_label} {len(first_report.paths)}")
+ print(f"{second_label} {len(second_report.paths)}")
+ f_output = open(output, "w+")
+ f_first_diff = open(f"{first}.diff", "w+")
+ f_second_diff = open(f"{second}.diff", "w+")
+ header = (
+ f"start,end,group,type,{first_label},{second_label},"
+ f"required_first,required_second,first-second,percent"
+ )
+ f_output.write(f"{header}\n")
+
+ matches_count = 0
+ b = 0
+ c = 0
+
+ for first_path in first_report.paths:
+ if first_path in second_report.paths:
+ matches = [
+ element for element in second_report.paths if first_path == element
+ ]
+ if len(matches) == 1:
+ matches_count += 1
+ second_path = matches[0]
+ delta = first_path.slack - second_path.slack
+ percent = delta / first_path.slack * 100.0
+ path_summary = (
+ f"{first_path.start_point},{first_path.end_point},"
+ f"{first_path.path_group},"
+ f"{first_path.path_type},"
+ f"{first_path.slack:.4f},"
+ f"{second_path.slack:.4f},"
+ f"{first_path.required_time:.4f},"
+ f"{second_path.required_time:.4f},"
+ f"{delta:.4f},{percent:.2f}%"
+ )
+ f_output.write(f"{path_summary}\n")
+
+ f_first_diff.write(f"{first_path.start_point}\n")
+ f_first_diff.write(f"{first_path.end_point}\n")
+ f_first_diff.write(f"{first_path.path}\n")
+ f_second_diff.write(f"------------\n")
+
+ f_second_diff.write(f"{second_path.start_point}\n")
+ f_second_diff.write(f"{second_path.end_point}\n")
+ f_second_diff.write(f"{second_path.path}\n")
+ f_second_diff.write(f"------------\n")
+ elif len(matches) > 1:
+ b += 1
+ # print(
+ # f"{path.start_point},{path.end_point},{path.path_group},{path.path_type},{path.slack}"
+ # )
+ else:
+ c += 1
+
+ f_output.close()
+ f_first_diff.close()
+ f_second_diff.close()
+ print("matches:", matches_count)
+ print("non unique matches:", b)
+ print("unmatched:", c)
+ print("done")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/deps/timing-scripts/scripts/generate_spef_mapping.py b/deps/timing-scripts/scripts/generate_spef_mapping.py
new file mode 100644
index 0000000..0094c7b
--- /dev/null
+++ b/deps/timing-scripts/scripts/generate_spef_mapping.py
@@ -0,0 +1,120 @@
+from pathlib import Path
+from verilog_parser import VerilogParser
+from pdk_helpers import get_macros, get_pdk_lefs_paths
+import click
+import logging
+
+
+@click.command(
+ help="""parses a verilog gatelevel netlist and creates a
+ spef mapping file for non pdk macros. the file is used
+ along with the other scripts in the repo for proper parasitics annotation
+ during sta"""
+)
+@click.option(
+ "--input",
+ "-i",
+ required=True,
+ type=click.Path(exists=True, dir_okay=False),
+ help="input verilog netlist",
+)
+@click.option(
+ "--project-root",
+ required=True,
+ type=click.Path(exists=True, file_okay=False),
+ help="path of the project that will be used in the output spef mapping file and finding verilog modules",
+)
+@click.option(
+ "--output", "-o", required=True, type=str, help="spef mapping tcl output file"
+)
+@click.option(
+ "--pdk-path", required=True, type=click.Path(exists=True, file_okay=False)
+)
+@click.option(
+ "--macro-parent",
+ required=False,
+ type=str,
+ default="",
+ help="optional name of the parent of the macro",
+)
+@click.option("--debug", is_flag=True)
+def main(input, project_root, output, pdk_path, macro_parent, debug=False):
+ """
+ Parse a verilog netlist
+ """
+ output_path = Path(output)
+ output_path.parents[0].mkdir(parents=True, exist_ok=True)
+ logging.basicConfig(format="%(asctime)s | %(module)s | %(levelname)s | %(message)s")
+ logger = logging.getLogger()
+ if debug:
+ logger.setLevel(logging.DEBUG)
+ else:
+ logger.setLevel(logging.INFO)
+
+ logger.info(f"using project_root {project_root}")
+
+ pdk_macros = []
+ logger.info("getting pdk macros ..")
+ lef_paths = get_pdk_lefs_paths(pdk_path)
+ for lef in lef_paths:
+ pdk_macros = pdk_macros + get_macros(lef)
+ logger.debug(f"pdk has {len(pdk_macros)} macros")
+
+ with open(output_path, "w") as f:
+ for mapping in run(input, project_root, pdk_macros, logger, macro_parent):
+ logging.debug(mapping)
+ f.write(mapping)
+
+ logger.info(f"wrote to {output_path}")
+
+
+def run(input, project_root, pdk_macros, logger, macro_parent=""):
+ logger.info(f"parsing netlist {input} ..")
+ parsed = VerilogParser(input, logger)
+ logger.info("comparing macros against pdk macros ..")
+ postfix = ".$::env(RCX_CORNER).spef"
+
+ mappings = []
+ non_pdk_instance = []
+ for instance in parsed.instances:
+ macro = parsed.instances[instance]
+ if macro not in pdk_macros:
+ logging.debug(f"{macro} not found in pdk_macros")
+ non_pdk_instance.append(instance)
+
+ logging.debug(f"# of non pdk instances {len(non_pdk_instance)}")
+ # recursion will break if above is zero
+ for instance in non_pdk_instance:
+ macro = parsed.instances[instance]
+ mapping_key = instance
+ hier_separator = "/"
+ if macro_parent != "":
+ mapping_key = f"{macro_parent}{hier_separator}{instance}"
+
+ existing_netlist = list(
+ (Path(project_root) / "verilog" / "gl").rglob(f"{macro}.v")
+ )
+ if len(existing_netlist) == 1:
+ logging.info(f"found netlist {str(existing_netlist[0])} for macro {macro}")
+ mappings += run(
+ input=str(existing_netlist[0]),
+ project_root=project_root,
+ pdk_macros=pdk_macros,
+ logger=logger,
+ macro_parent=mapping_key,
+ )
+
+ spef_dir = Path(project_root) / "signoff" / "not-found"
+ for macro_spef_file in (Path(project_root) / "signoff").rglob(f"{macro}*.spef"):
+ spef_dir = macro_spef_file.parent
+ logging.debug(f"found {macro_spef_file} for {macro}")
+ spef_rel_dir = spef_dir.relative_to(project_root)
+ macro_spef = f"$::env(PROJECT_ROOT)/{spef_rel_dir}/{macro}{postfix}"
+ mappings.append(f'set spef_mapping({mapping_key}) "{macro_spef}"\n')
+
+ return mappings
+
+
+# sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+if __name__ == "__main__":
+ main()
diff --git a/deps/timing-scripts/scripts/get_macros.py b/deps/timing-scripts/scripts/get_macros.py
new file mode 100644
index 0000000..f6abdf9
--- /dev/null
+++ b/deps/timing-scripts/scripts/get_macros.py
@@ -0,0 +1,121 @@
+from __future__ import absolute_import
+from __future__ import print_function
+from pathlib import Path
+from verilog_parser import VerilogParser
+from pdk_helpers import get_pdk_lefs_paths, get_macros
+import click
+import logging
+import os
+import sys
+
+
+@click.command(
+ help="""parses a verilog gatelevel netlist and
+ prints the non scl instance names
+ """
+)
+@click.option(
+ "--input",
+ "-i",
+ required=True,
+ type=click.Path(exists=True, dir_okay=False),
+ help="input verilog netlist",
+)
+@click.option(
+ "--pdk-path", required=True, type=click.Path(exists=True, file_okay=False)
+)
+@click.option(
+ "--output",
+ "-o",
+ required=True,
+ type=str,
+ help="output file in the format each line <instance_name> <instance_type>",
+)
+@click.option(
+ "--project-root",
+ required=True,
+ type=click.Path(exists=True, file_okay=False),
+ help="path of the project that will be used in the finding verilog modules",
+)
+@click.option(
+ "--macro-parent",
+ required=False,
+ type=str,
+ default="",
+ help="optional name of the parent of the macro",
+)
+@click.option("--debug", is_flag=True)
+def main(input, output, pdk_path, project_root, macro_parent, debug=False):
+ """
+ Parse a verilog netlist
+ """
+ logging.basicConfig(format="%(asctime)s | %(module)15s | %(levelname)6s | %(message)s")
+ logger = logging.getLogger()
+ if debug:
+ logger.setLevel(logging.DEBUG)
+ else:
+ logger.setLevel(logging.INFO)
+
+ output_path = Path(output)
+ output_path.parents[0].mkdir(parents=True, exist_ok=True)
+
+ pdk_macros = []
+ logger.info("getting pdk macros..")
+ lef_paths = get_pdk_lefs_paths(pdk_path)
+ for lef in lef_paths:
+ pdk_macros = pdk_macros + get_macros(lef)
+ logger.debug(pdk_macros)
+
+
+ with open(output_path, "w") as f:
+ for macro in run(input, project_root, pdk_macros, logger, macro_parent):
+ f.write(macro)
+
+ logger.info("done.")
+
+def run(input, project_root, pdk_macros, logger, macro_parent=""):
+ logger.info(f"parsing netlist {input} ..")
+ parsed = VerilogParser(input, logger)
+ logger.info("comparing macros against pdk macros ..")
+
+ macros = []
+ non_pdk_instance = []
+ for instance in parsed.instances:
+ macro = parsed.instances[instance]
+ if macro not in pdk_macros:
+ logging.debug(f"{macro} not found in pdk_macros")
+ non_pdk_instance.append(instance)
+
+ logging.debug(f"# of non pdk instances {len(non_pdk_instance)}")
+ # recursion will break if above is zero
+ for instance in non_pdk_instance:
+ macro = parsed.instances[instance]
+ mapping_key = instance
+ hier_separator = "/"
+ if macro_parent != "":
+ mapping_key = f"{macro_parent}{hier_separator}{instance}"
+
+ search_path = (Path(project_root) / "verilog" / "gl")
+ logging.debug(f"searching for {macro} netlist in {search_path}")
+ existing_netlist = list(
+ search_path.rglob(f"{macro}.v")
+ )
+ logging.debug(f"found {len(existing_netlist)} matches.")
+ if len(existing_netlist) == 1:
+ logging.info(f"found netlist {str(existing_netlist[0])} for macro {macro}")
+ macros += run(
+ input=str(existing_netlist[0]),
+ project_root=project_root,
+ pdk_macros=pdk_macros,
+ logger=logger,
+ macro_parent=mapping_key,
+ )
+
+ macros.append(f'{instance} {macro}\n')
+
+ return macros
+
+
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+if __name__ == "__main__":
+ main()
diff --git a/deps/timing-scripts/scripts/openroad/rcx.tcl b/deps/timing-scripts/scripts/openroad/rcx.tcl
new file mode 100644
index 0000000..dfe3e9c
--- /dev/null
+++ b/deps/timing-scripts/scripts/openroad/rcx.tcl
@@ -0,0 +1,35 @@
+source $::env(TIMING_ROOT)/env/common.tcl
+source $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl
+
+set libs [split [regexp -all -inline {\S+} $libs]]
+set extra_lefs [split [regexp -all -inline {\S+} $extra_lefs]]
+
+foreach liberty $libs {
+ run_puts "read_liberty $liberty"
+}
+foreach lef $lefs {
+ run_puts "read_lef $lef"
+}
+run_puts "read_lef $sram_lef"
+
+foreach lef_file $extra_lefs {
+ run_puts "read_lef $lef_file"
+}
+
+run_puts "read_def $def"
+# don't think we need to read sdc
+
+run_puts "define_process_corner -ext_model_index 0 X"
+run_puts "extract_parasitics \
+ -ext_model_file $rcx_rules_file \
+ -lef_res"
+
+run_puts "write_spef $spef"
+run_puts "read_spef $spef"
+
+puts "spef: $spef"
+puts "def: $def"
+puts "rcx: $rcx_rules_file"
+puts "rcx-corner: $::env(RCX_CORNER)"
+puts "lib-corner: $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl"
+puts "tech_lef: $tech_lef"
diff --git a/deps/timing-scripts/scripts/openroad/sdf.tcl b/deps/timing-scripts/scripts/openroad/sdf.tcl
new file mode 100644
index 0000000..382ef89
--- /dev/null
+++ b/deps/timing-scripts/scripts/openroad/sdf.tcl
@@ -0,0 +1,60 @@
+source $::env(TIMING_ROOT)/env/common.tcl
+source $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl
+
+set libs [split [regexp -all -inline {\S+} $libs]]
+set verilogs [split [regexp -all -inline {\S+} $verilogs]]
+
+
+foreach lef $lefs {
+ if {[catch {read_lef $lef} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+ }
+}
+
+if {[catch {read_lef $sram_lef} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+}
+
+foreach lef_file $extra_lefs {
+ if {[catch {read_lef $lef_file} errmsg]} {
+ puts stderr $errmsg
+ exit 1
+ }
+}
+
+foreach liberty $libs {
+ read_liberty $liberty
+}
+
+#foreach verilog $verilogs {
+# puts "reading veriolg: $verilog"
+# read_verilog $verilog
+#}
+
+set verilog $::env(CUP_ROOT)/verilog/gl/$::env(BLOCK).v
+if { ![file exists $verilog] } {
+ set verilog $::env(MCW_ROOT)/verilog/gl/$::env(BLOCK).v
+}
+if { ![file exists $verilog] } {
+ set verilog $::env(CARAVEL_ROOT)/verilog/gl/$::env(BLOCK).v
+}
+
+read_verilog $verilog
+
+
+link_design $block
+
+puts "read_spef $spef"
+read_spef $spef
+#read_sdc $sdc
+write_sdf $sdf -divider . -include_typ
+
+puts "block: $block"
+puts "spef: $spef"
+puts "verilog: $verilog"
+puts "sdf: $sdf"
+puts "sdc: $sdc"
+puts "rcx-corner: $::env(RCX_CORNER)"
+puts "lib-corner: $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl"
diff --git a/deps/timing-scripts/scripts/openroad/sta-gpio_control_block.tcl b/deps/timing-scripts/scripts/openroad/sta-gpio_control_block.tcl
new file mode 100644
index 0000000..e224905
--- /dev/null
+++ b/deps/timing-scripts/scripts/openroad/sta-gpio_control_block.tcl
@@ -0,0 +1,42 @@
+source $::env(TIMING_ROOT)/env/common.tcl
+source $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl
+
+set libs [split [regexp -all -inline {\S+} $libs]]
+
+foreach liberty $libs {
+ read_liberty $liberty
+}
+
+
+set verilogs [list \
+ $::env(CARAVEL_ROOT)/verilog/gl/gpio_logic_high.v \
+ $::env(CARAVEL_ROOT)/verilog/gl/gpio_control_block.v \
+]
+foreach verilog $verilogs {
+ puts "read_verilog $verilog"
+ read_verilog $verilog
+}
+
+link_design $block
+
+set spef $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef
+puts "read_spef $spef"
+read_spef $spef
+
+puts "read_spef -path gpio_logic_high $::env(CARAVEL_ROOT)/spef/gpio_logic_high.spef"
+read_spef -path gpio_logic_high $::env(CARAVEL_ROOT)/spef/gpio_logic_high.spef
+
+read_sdc -echo $sdc
+
+report_checks -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 50
+
+report_worst_slack -max
+report_worst_slack -min
+
+puts "block: $block"
+puts "spef: $spef"
+puts "verilog: $verilog"
+puts "sdf: $sdf"
+puts "sdc: $sdc"
+puts "rcx-corner: $::env(RCX_CORNER)"
+puts "lib-corner: $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl"
diff --git a/deps/timing-scripts/scripts/openroad/timing_top.tcl b/deps/timing-scripts/scripts/openroad/timing_top.tcl
new file mode 100644
index 0000000..02390ed
--- /dev/null
+++ b/deps/timing-scripts/scripts/openroad/timing_top.tcl
@@ -0,0 +1,289 @@
+source $::env(TIMING_ROOT)/env/common.tcl
+source $::env(TIMING_ROOT)/env/caravel_spef_mapping-mpw7.tcl
+
+if { [file exists $::env(CUP_ROOT)/env/spef-mapping.tcl] } {
+ source $::env(CUP_ROOT)/env/spef-mapping.tcl
+} else {
+ puts "WARNING no user project spef mapping file found"
+}
+
+source $::env(TIMING_ROOT)/env/$::env(LIB_CORNER).tcl
+
+set libs [split [regexp -all -inline {\S+} $libs]]
+set verilogs [split [regexp -all -inline {\S+} $verilogs]]
+
+
+foreach liberty $libs {
+}
+
+foreach liberty $libs {
+ run_puts "read_liberty $liberty"
+}
+
+foreach verilog $verilogs {
+ run_puts "read_verilog $verilog"
+}
+
+run_puts "link_design caravel"
+
+if { $::env(SPEF_OVERWRITE) ne "" } {
+ puts "overwriting spef from "
+ puts "$spef to"
+ puts "$::env(SPEF_OVERWRITE)"
+ eval set spef $::env(SPEF_OVERWRITE)
+}
+
+set missing_spefs 0
+set missing_spefs_list ""
+run_puts "read_spef $spef"
+foreach key [array names spef_mapping] {
+ set spef_file $spef_mapping($key)
+ if { [file exists $spef_file] } {
+ run_puts "read_spef -path $key $spef_mapping($key)"
+ } else {
+ set missing_spefs 1
+ set missing_spefs_list "$missing_spefs_list $key"
+ puts "$spef_file not found"
+ if { $::env(ALLOW_MISSING_SPEF) } {
+ puts "WARNING ALLOW_MISSING_SPEF set to 1. continuing"
+ } else {
+ exit 1
+ }
+ }
+}
+
+set sdc $::env(CARAVEL_ROOT)/signoff/caravel/caravel.sdc
+run_puts "read_sdc -echo $sdc"
+
+set logs_path "$::env(PROJECT_ROOT)/signoff/caravel/openlane-signoff/timing/$::env(RCX_CORNER)/$::env(LIB_CORNER)"
+file mkdir [file dirname $logs_path]
+
+
+run_puts_logs "report_check_types \\
+ -max_delay \\
+ -min_delay \\
+ -max_slew \\
+ -max_capacitance \\
+ -clock_gating_setup \\
+ -clock_gating_hold \\
+ -format end \\
+ -violators" \
+ "${logs_path}-summary.rpt"
+
+
+set max_delay_result "met"
+set min_delay_result "met"
+set max_slew_result "met"
+set max_cap_result "met"
+set missing_spefs_result "incomplete"
+
+set report ${logs_path}-summary.rpt
+
+set max_cap_value "[exec bash -c "grep 'max cap' $report -A 4 | tail -n1 | awk -F ' *' '{print \$4}'"]"
+set worst_hold "[exec bash -c "grep 'min_delay\/hold' $report -A 10 | grep VIOLATED | head -n1 | awk -F ' *' '{print \$5}'"]"
+set worst_setup "[exec bash -c "grep 'max_delay\/setup' $report -A 10 | grep VIOLATED | head -n1 | awk -F ' *' '{print \$5}'"]"
+set max_slew_value "[exec bash -c "grep 'max slew' $report -A 4 | tail -n1 | awk -F ' *' '{print \$4}'"]"
+
+set table_format "%7s| %15s |%15s |%15s |%15s |%15s"
+set header [format "$table_format" "corner" "max cap" "max slew" "min delay" "max delay" "spefs"]
+if {![catch {exec grep -q {max cap} $report} err]} {
+ set max_cap_result "vio($max_cap_value)"
+}
+
+if {![catch {exec grep -q {max slew} $report} err]} {
+ set max_slew_result "vio($max_slew_value)"
+}
+
+if {![catch {exec grep -q {min_delay\/hold} $report} err]} {
+ set min_delay_result "vio($worst_hold)"
+}
+
+if {![catch {exec grep -q {max_delay\/setup} $report} err]} {
+ set max_delay_result "vio($worst_setup)"
+}
+
+if { !$missing_spefs } {
+ set missing_spefs_result "complete"
+}
+
+set summary [format "$table_format" "$::env(LIB_CORNER)-$::env(RCX_CORNER)"\
+ "$max_cap_result" \
+ "$max_slew_result" \
+ "$min_delay_result"\
+ "$max_delay_result"\
+ "$missing_spefs_result"]
+
+exec echo "$header" >> "${logs_path}-summary.rpt"
+exec echo "$summary" >> "${logs_path}-summary.rpt"
+
+
+run_puts_logs "report_checks \\
+ -path_delay min \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -group_count 10000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -endpoint_count 10 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-min.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay max \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -group_count 10000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -endpoint_count 10 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-max.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay min \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -path_group hk_serial_clk \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-hk_serial_clk-min.rpt"
+
+
+run_puts_logs "report_checks \\
+ -path_delay max \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -path_group hk_serial_clk \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-hk_serial_clk-max.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay max \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -path_group hkspi_clk \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-hkspi_clk-max.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay min \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -path_group hkspi_clk \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-hkspi_clk-min.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay min \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -path_group clk \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-clk-min.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay max \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -path_group clk \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-clk-max.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay min \\
+ -through [get_cells soc] \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-soc-min.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay max \\
+ -through [get_cells soc] \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -group_count 1000 \\
+ -slack_max 10 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-soc-max.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay min \\
+ -through [get_cells mprj] \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -group_count 1000 \\
+ -slack_max 40 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-mprj-min.rpt"
+
+run_puts_logs "report_checks \\
+ -path_delay max \\
+ -through [get_cells mprj] \\
+ -format full_clock_expanded \\
+ -fields {slew cap input_pins nets fanout} \\
+ -no_line_splits \\
+ -group_count 1000 \\
+ -slack_max 40 \\
+ -digits 4 \\
+ -unique_paths_to_endpoint \\
+ "\
+ "${logs_path}-mprj-max.rpt"
+
+run_puts "report_parasitic_annotation -report_unannotated > ${logs_path}-unannotated.log"
+if { $missing_spefs } {
+ puts "there are missing spefs. check the log for ALLOW_MISSING_SPEF"
+ puts "the following macros don't have spefs"
+ foreach spef $missing_spefs_list {
+ puts "$spef"
+ }
+}
+report_parasitic_annotation
+
+
+puts "you may want to edit sdc: $sdc to change i/o constraints"
+puts "check $logs_path"
diff --git a/deps/timing-scripts/scripts/pdk_helpers.py b/deps/timing-scripts/scripts/pdk_helpers.py
new file mode 100644
index 0000000..6536e9b
--- /dev/null
+++ b/deps/timing-scripts/scripts/pdk_helpers.py
@@ -0,0 +1,21 @@
+from typing import List
+import os
+
+def get_pdk_lefs_paths(pdk_path: str) -> List[str]:
+ lef_paths = []
+ for root, dirs, files in os.walk(pdk_path):
+ for file in files:
+ filename, file_extension = os.path.splitext(f"{file}")
+ if file_extension == ".lef":
+ lef_paths.append(f"{root}/{file}")
+ return lef_paths
+
+
+def get_macros(lef_file: str) -> List[str]:
+ macros = []
+ with open(lef_file) as f:
+ for line in f.readlines():
+ if "MACRO" in line:
+ macro_name = line.split()[1]
+ macros.append(macro_name)
+ return macros
diff --git a/deps/timing-scripts/scripts/report.py b/deps/timing-scripts/scripts/report.py
new file mode 100644
index 0000000..1b96505
--- /dev/null
+++ b/deps/timing-scripts/scripts/report.py
@@ -0,0 +1,83 @@
+from timing_path import TimingPath
+
+
+class Report:
+ def __init__(self, report_file):
+ self.report_file = report_file
+ self.paths = []
+ self.input_output_paths = []
+ self.input_flipflop_paths = []
+ self.flipflop_flipflop_paths = []
+ self.flipflop_output_paths = []
+ self.build_db()
+ self.classify_paths()
+
+ def classify_paths(self):
+ for path in self.paths:
+ path_category = path.category
+ if path_category == "input-output":
+ self.input_output_paths.append(path)
+ elif path_category == "input-flipflop":
+ self.input_flipflop_paths.append(path)
+ elif path_category == "flipflop-flipflop":
+ self.flipflop_flipflop_paths.append(path)
+ elif path_category == "flipflop-output":
+ self.flipflop_output_paths.append(path)
+
+ def build_db(self):
+ file = open(self.report_file)
+ start_point = end_point = path_group = path_values = ""
+
+ line = file.readline()
+ while line != "":
+ line = line.strip()
+ if "Startpoint" in line:
+ x = file.tell()
+ start_point = " ".join(line.split(" ")[1:])
+ line2 = file.readline()
+ if "Endpoint" not in line2:
+ start_point += line2
+ else:
+ file.seek(x)
+ elif "Endpoint" in line:
+ x = file.tell()
+ end_point = " ".join(line.split(" ")[1:])
+ line2 = file.readline()
+ if "Path Group" not in line2:
+ end_point += line2
+ else:
+ file.seek(x)
+ elif "Path Group" in line:
+ path_group = line.split(" ")[2]
+ elif "Path Type" in line:
+ path_type = line.split(" ")[2]
+
+ path_line = file.readline()
+ while path_line != "":
+ if "Startpoint" in path_line:
+ path_object = TimingPath(
+ start_point=start_point.rstrip(),
+ end_point=end_point.rstrip(),
+ path_group=path_group.rstrip(),
+ path_type=path_type,
+ path=path_values,
+ )
+ self.paths.append(path_object)
+
+ path_line = path_line.strip()
+ start_point = " ".join(path_line.split(" ")[1:])
+ x = file.tell()
+ line2 = file.readline()
+ if "Endpoint" not in line2:
+ start_point += line2
+ else:
+ file.seek(x)
+
+ path_values = ""
+ break
+ else:
+ path_values += path_line
+ path_line = file.readline()
+ line = file.readline()
+
+ file.close()
diff --git a/deps/timing-scripts/scripts/summarize_report.py b/deps/timing-scripts/scripts/summarize_report.py
new file mode 100644
index 0000000..efc0317
--- /dev/null
+++ b/deps/timing-scripts/scripts/summarize_report.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+
+import argparse
+from report import Report
+from timing_path import TimingPath
+
+parser = argparse.ArgumentParser(
+ description="summarizes sta reports. tested on pt and opensta"
+)
+parser.add_argument("--input", "-i", required=True)
+parser.add_argument("--output", "-o", required=True)
+
+args = parser.parse_args()
+report_file = args.input
+output_file = args.output
+
+report = Report(report_file)
+
+output_files_stream = open(f"{output_file}", "w")
+
+output_files_stream.write(
+ f"--------------input-flipflop_paths#{len(report.input_flipflop_paths)}-------------------\n"
+)
+output_files_stream.write(TimingPath.get_header())
+for path in report.input_flipflop_paths:
+ output_files_stream.write(path.summarize())
+output_files_stream.write(
+ f"--------------input-output_paths#{len(report.input_output_paths)}---------------------\n"
+)
+output_files_stream.write(TimingPath.get_header())
+for path in report.input_output_paths:
+ output_files_stream.write(path.summarize())
+output_files_stream.write(
+ f"--------------flipflop-flipflop_paths#{len(report.flipflop_flipflop_paths)}----------------\n"
+)
+output_files_stream.write(TimingPath.get_header())
+for path in report.flipflop_flipflop_paths:
+ output_files_stream.write(path.summarize())
+output_files_stream.write(
+ f"--------------flipflop-output_paths#{len(report.flipflop_output_paths)}------------------\n"
+)
+output_files_stream.write(TimingPath.get_header())
+for path in report.flipflop_output_paths:
+ output_files_stream.write(path.summarize())
diff --git a/deps/timing-scripts/scripts/timing_path.py b/deps/timing-scripts/scripts/timing_path.py
new file mode 100644
index 0000000..c77a624
--- /dev/null
+++ b/deps/timing-scripts/scripts/timing_path.py
@@ -0,0 +1,112 @@
+import textwrap
+import re
+
+
+class TimingPath:
+ def __init__(self, start_point, end_point, path_group, path_type, path):
+ self.start_point = start_point
+ self.end_point = end_point
+ self.path_group = path_group
+ self.path_type = path_type
+ self.path = path
+ self.category = ""
+ self.slack = None
+ self.edges = ""
+ self.required_time = None
+ self.arrival_time = None
+ self.find_category()
+ self.simplify_points()
+ self.find_slack()
+ self.find_required()
+ self.find_arrival()
+ self.id = self.start_point + self.end_point + self.path_group + self.path_type
+
+ def find_required(self):
+ for line in self.path.split("\n"):
+ if "required time" in line:
+ self.required_time = float(re.findall(
+ r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", line
+ )[0].strip())
+ break
+
+ def find_arrival(self):
+ for line in self.path:
+ if "arrival time" in line:
+ self.arrival_time = float(re.findall(
+ r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", line
+ )[0].strip())
+ break
+
+ def find_edges(self):
+ split_path = self.path.split("\n")
+ edge = "f"
+ for line in split_path:
+ if "^" in line or " r" in line:
+ edge = "r"
+ self.edges = self.edges + edge
+ elif "v" in line or " f" in line:
+ edge = "f"
+ self.edges = self.edges + edge
+ elif "data arrival time" in line:
+ break
+
+ def simplify_points(self):
+ if len(self.start_point.split()) > 1:
+ self.start_point = self.start_point.split()[0]
+ if len(self.end_point.split()) > 1:
+ self.end_point = self.end_point.split()[0]
+
+ @classmethod
+ def get_header(cls):
+ start_point = "start_point"
+ end_point = "end_point"
+ group = "group"
+ type = "type"
+ slack = "slack"
+ return f"{start_point},{end_point},{group},{type},{slack}\n"
+
+ def find_slack(self):
+ slack = ""
+ for line in self.path.splitlines():
+ if "slack" in line:
+ slack = textwrap.dedent(line)
+ break
+ self.slack = re.findall(
+ r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", slack
+ )[0].strip()
+ self.slack = float(self.slack)
+
+ def summarize(self):
+ slack_value = self.slack
+ group = self.path_group
+ type = self.path_type
+ start_point = self.start_point
+ end_point = self.end_point
+ return f"{start_point},{end_point},{group},{type},{slack_value:.4f}\n"
+
+ def find_category(self):
+ start = ""
+ end = ""
+ if "input" in self.start_point:
+ start = "input"
+ else:
+ start = "flipflop"
+ if "output" in self.end_point:
+ end = "output"
+ else:
+ end = "flipflop"
+
+ self.category = f"{start}-{end}"
+
+ def __eq__(self, other):
+ return self.id == other.id
+
+ def __str__(self):
+ return f"""
+Startpoint: {self.start_point}
+Endpoint: {self.end_point}
+Path group: {self.path_group}
+Path type: {self.path_type}
+Path:
+{self.path}
+"""
diff --git a/deps/timing-scripts/scripts/verilog_parser.py b/deps/timing-scripts/scripts/verilog_parser.py
new file mode 100644
index 0000000..3bb15fd
--- /dev/null
+++ b/deps/timing-scripts/scripts/verilog_parser.py
@@ -0,0 +1,40 @@
+import subprocess
+import os
+import json
+
+
+class VerilogParser:
+ def __init__(self, verilog_netlist, logger):
+ self.verilog_netlist = verilog_netlist
+ self.instances = {}
+ self.logger = logger
+ self.yosys_to_json()
+
+ # self.instances[instance.name] = instance.module
+
+ def yosys_to_json(self):
+ yosys_env = os.environ.copy()
+ script_path = os.path.dirname(os.path.abspath(__file__))
+ yosys_env["YOSYS_VERILOG_IN"] = self.verilog_netlist
+ yosys_env["YOSYS_JSON_OUT"] = "./tmp.json"
+ self.logger.debug("running yosys ..")
+ process = subprocess.run(
+ f"yosys -c {script_path}/yosys/to-json.tcl".split(),
+ env=yosys_env,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
+ if process.returncode:
+ self.logger.error(process.stdout.decode("utf-8"))
+
+ self.logger.debug("reading json ..")
+ f = open("./tmp.json")
+ data = json.load(f)
+ f.close()
+ os.remove("./tmp.json")
+ module_name = os.path.basename(self.verilog_netlist)
+ module_name = os.path.splitext(module_name)[0]
+ self.logger.debug("parsing json ..")
+ full_cells = data["modules"][module_name]["cells"]
+ for cell in full_cells:
+ self.instances[cell] = full_cells[cell]["type"]
diff --git a/deps/timing-scripts/scripts/yosys/to-json.tcl b/deps/timing-scripts/scripts/yosys/to-json.tcl
new file mode 100644
index 0000000..47c1529
--- /dev/null
+++ b/deps/timing-scripts/scripts/yosys/to-json.tcl
@@ -0,0 +1,4 @@
+yosys -import
+
+read_verilog $::env(YOSYS_VERILOG_IN)
+json -o $::env(YOSYS_JSON_OUT)
diff --git a/deps/timing-scripts/timing.mk b/deps/timing-scripts/timing.mk
new file mode 100644
index 0000000..148b384
--- /dev/null
+++ b/deps/timing-scripts/timing.mk
@@ -0,0 +1,307 @@
+OPENLANE_TAG ?= 2022.02.23_02.50.41
+OPENLANE_IMAGE_NAME ?= efabless/openlane:$(OPENLANE_TAG)
+export PDK ?= sky130A
+export RCX_CORNER ?= nom
+export LIB_CORNER ?= t
+export ALLOW_MISSING_SPEF ?= 1
+export PDK_REF_PATH = $(PDK_ROOT)/$(PDK)/libs.ref/
+export PDK_TECH_PATH = $(PDK_ROOT)/$(PDK)/libs.tech/
+export PROJECT_ROOT ?= $(CARAVEL_ROOT)
+
+logs-dir = $(PROJECT_ROOT)/logs
+logs = $(logs-dir)/rcx $(logs-dir)/sdf $(logs-dir)/top $(logs-dir)/sta
+$(logs):
+ mkdir -p $@
+
+SPEF_OVERWRITE ?= ""
+define docker_run_base
+ docker run \
+ --rm \
+ -e PROJECT_ROOT=$(PROJECT_ROOT) \
+ -e BLOCK=$1 \
+ -e PDK=$(PDK) \
+ -e LIB_CORNER=$(LIB_CORNER) \
+ -e RCX_CORNER=$(RCX_CORNER) \
+ -e MCW_ROOT=$(MCW_ROOT) \
+ -e SPEF_OVERWRITE=$(SPEF_OVERWRITE) \
+ -e CUP_ROOT=$(CUP_ROOT) \
+ -e CARAVEL_ROOT=$(CARAVEL_ROOT) \
+ -e TIMING_ROOT=$(TIMING_ROOT) \
+ -e PDK_REF_PATH=$(PDK_ROOT)/$(PDK)/libs.ref/ \
+ -e PDK_TECH_PATH=$(PDK_ROOT)/$(PDK)/libs.tech/ \
+ -e ALLOW_MISSING_SPEF=$(ALLOW_MISSING_SPEF) \
+ -v $(PDK_ROOT):$(PDK_ROOT) \
+ -v $(CUP_ROOT):$(CUP_ROOT) \
+ -v $(MCW_ROOT):$(MCW_ROOT) \
+ -v $(TIMING_ROOT):$(TIMING_ROOT) \
+ -v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
+ -v $(HOME):$(HOME) \
+ -u $(shell id -u $(USER)):$(shell id -g $(USER)) \
+ $(OPENLANE_IMAGE_NAME)
+endef
+
+
+define docker_run_sta
+ $(call docker_run_base,$1) \
+ bash -c "set -eo pipefail && sta -exit $(TIMING_ROOT)/scripts/openroad/sta-$*.tcl \
+ |& tee $(logs-dir)/sta/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
+ @echo "logged to $(logs-dir)/sta/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
+endef
+
+define docker_run_sdf
+ $(call docker_run_base,$1) \
+ bash -c "set -eo pipefail && openroad -exit $(TIMING_ROOT)/scripts/openroad/sdf.tcl \
+ |& tee $(logs-dir)/sdf/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
+ @echo "logged to $(logs-dir)/sdf/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
+endef
+
+define docker_run_rcx
+ $(call docker_run_base,$1) \
+ bash -c "set -eo pipefail && openroad -exit $(TIMING_ROOT)/scripts/openroad/rcx.tcl \
+ |& tee $(logs-dir)/rcx/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
+ @echo "logged to $(logs-dir)/rcx/$*-$(RCX_CORNER)-$(LIB_CORNER).log"
+endef
+
+blocks = $(shell cd $(CARAVEL_ROOT)/openlane && find * -maxdepth 0 -type d)
+blocks := $(subst user_project_wrapper,,$(blocks))
+ifneq ($(CARAVEL_ROOT),$(MCW_ROOT))
+blocks += $(shell cd $(MCW_ROOT)/openlane && find * -maxdepth 0 -type d)
+endif
+ifneq ($(CARAVEL_ROOT),$(CUP_ROOT))
+blocks += $(shell cd $(CUP_ROOT)/openlane && find * -maxdepth 0 -type d)
+endif
+
+# we don't have user_id_programming.def)
+# mgmt_protect_hvl use hvl library which we don't handle yet
+blocks := $(subst mgmt_protect_hvl,,$(blocks))
+blocks := $(subst chip_io_alt,,$(blocks))
+blocks := $(subst user_id_programming,,$(blocks))
+blocks := $(subst user_analog_project_wrapper,,$(blocks))
+blocks := $(subst caravan,,$(blocks))
+
+defs = $(shell cd $(CARAVEL_ROOT)/def && find *.def -maxdepth 0 -type f ! -name 'user_project_wrapper.def')
+ifneq ($(CARAVEL_ROOT),$(MCW_ROOT))
+defs += $(shell cd $(MCW_ROOT)/def && find *.def -maxdepth 0 -type f)
+endif
+ifneq ($(CARAVEL_ROOT),$(CUP_ROOT))
+defs += $(shell cd $(CUP_ROOT)/def && find *.def -maxdepth 0 -type f)
+endif
+
+rcx-blocks = $(defs:%.def=rcx-%)
+rcx-blocks-nom = $(blocks:%=rcx-%-nom)
+rcx-blocks-max = $(blocks:%=rcx-%-max)
+rcx-blocks-min = $(blocks:%=rcx-%-min)
+rcx-blocks-t = $(blocks:%=rcx-%-t)
+rcx-blocks-f = $(blocks:%=rcx-%-f)
+rcx-blocks-s = $(blocks:%=rcx-%-s)
+
+sdf-blocks = $(blocks:%=sdf-%)
+sdf-blocks-t = $(blocks:%=sdf-%-t)
+sdf-blocks-f = $(blocks:%=sdf-%-f)
+sdf-blocks-s = $(blocks:%=sdf-%-s)
+sdf-blocks-nom = $(blocks:%=sdf-%-nom)
+sdf-blocks-min = $(blocks:%=sdf-%-min)
+sdf-blocks-max = $(blocks:%=sdf-%-max)
+
+$(sdf-blocks): sdf-%:
+ $(MAKE) -f timing.mk sdf-$*-nom
+ $(MAKE) -f timing.mk sdf-$*-min
+ $(MAKE) -f timing.mk sdf-$*-max
+
+$(sdf-blocks-nom): export RCX_CORNER = nom
+$(sdf-blocks-min): export RCX_CORNER = min
+$(sdf-blocks-max): export RCX_CORNER = max
+$(sdf-blocks-nom): sdf-%-nom: sdf-%-t sdf-%-f sdf-%-s
+$(sdf-blocks-min): sdf-%-min: sdf-%-t sdf-%-f sdf-%-s
+$(sdf-blocks-max): sdf-%-max: sdf-%-t sdf-%-f sdf-%-s
+
+$(sdf-blocks-t): export LIB_CORNER = t
+$(sdf-blocks-s): export LIB_CORNER = s
+$(sdf-blocks-f): export LIB_CORNER = f
+$(sdf-blocks-t): sdf-%-t:
+ $(call docker_run_sdf,$*)
+$(sdf-blocks-s): sdf-%-s:
+ $(call docker_run_sdf,$*)
+$(sdf-blocks-f): sdf-%-f:
+ $(call docker_run_sdf,$*)
+
+
+sta-blocks = $(blocks:%=sta-%)
+sta-blocks-t = $(blocks:%=sta-%-t)
+sta-blocks-f = $(blocks:%=sta-%-f)
+sta-blocks-s = $(blocks:%=sta-%-s)
+sta-blocks-nom = $(blocks:%=sta-%-nom)
+sta-blocks-min = $(blocks:%=sta-%-min)
+sta-blocks-max = $(blocks:%=sta-%-max)
+
+$(sta-blocks): sta-%:
+ $(MAKE) -f timing.mk sta-$*-nom
+ $(MAKE) -f timing.mk sta-$*-min
+ $(MAKE) -f timing.mk sta-$*-max
+
+$(sta-blocks-nom): export RCX_CORNER = nom
+$(sta-blocks-min): export RCX_CORNER = min
+$(sta-blocks-max): export RCX_CORNER = max
+$(sta-blocks-nom): sta-%-nom: sta-%-t sta-%-f sta-%-s
+$(sta-blocks-min): sta-%-min: sta-%-t sta-%-f sta-%-s
+$(sta-blocks-max): sta-%-max: sta-%-t sta-%-f sta-%-s
+
+$(sta-blocks-t): export LIB_CORNER = t
+$(sta-blocks-s): export LIB_CORNER = s
+$(sta-blocks-f): export LIB_CORNER = f
+$(sta-blocks-t): sta-%-t: $(logs-dir)/sta
+ $(call docker_run_sta,$*)
+$(sta-blocks-s): sta-%-s:
+ $(call docker_run_sta,$*)
+$(sta-blocks-f): sta-%-f:
+ $(call docker_run_sta,$*)
+
+
+$(rcx-blocks): rcx-%: $(rcx-requirements)
+ $(MAKE) -f timing.mk rcx-$*-nom &
+ $(MAKE) -f timing.mk rcx-$*-min &
+ $(MAKE) -f timing.mk rcx-$*-max
+
+$(rcx-blocks-nom): export RCX_CORNER = nom
+$(rcx-blocks-min): export RCX_CORNER = min
+$(rcx-blocks-max): export RCX_CORNER = max
+$(rcx-blocks-nom): rcx-%-nom: rcx-%-t
+$(rcx-blocks-min): rcx-%-min: rcx-%-t
+$(rcx-blocks-max): rcx-%-max: rcx-%-t
+
+$(rcx-blocks-t): export LIB_CORNER = t
+$(rcx-blocks-s): export LIB_CORNER = s
+$(rcx-blocks-f): export LIB_CORNER = f
+$(rcx-blocks-t): rcx-%-t: $(logs-dir)/rcx
+ $(call docker_run_rcx,$*)
+$(rcx-blocks-s): rcx-%-s:
+ $(call docker_run_rcx,$*)
+$(rcx-blocks-f): rcx-%-f:
+ $(call docker_run_rcx,$*)
+
+
+define docker_run_caravel_timing
+ $(call docker_run_base,caravel) \
+ bash -c "set -eo pipefail && sta -no_splash -exit $(TIMING_ROOT)/scripts/openroad/timing_top.tcl |& tee \
+ $(logs-dir)/top/caravel-timing-$$(basename $(LIB_CORNER))-$(RCX_CORNER).log"
+ @echo "logged to $(logs-dir)/top/caravel-timing-$$(basename $(LIB_CORNER))-$(RCX_CORNER).log"
+endef
+
+
+caravel-timing-typ-targets = caravel-timing-typ-nom
+caravel-timing-typ-targets += caravel-timing-typ-min
+caravel-timing-typ-targets += caravel-timing-typ-max
+
+caravel-timing-slow-targets = caravel-timing-slow-nom
+caravel-timing-slow-targets += caravel-timing-slow-min
+caravel-timing-slow-targets += caravel-timing-slow-max
+
+caravel-timing-fast-targets = caravel-timing-fast-nom
+caravel-timing-fast-targets += caravel-timing-fast-min
+caravel-timing-fast-targets += caravel-timing-fast-max
+
+caravel-timing-targets = $(caravel-timing-slow-targets)
+caravel-timing-targets += $(caravel-timing-fast-targets)
+caravel-timing-targets += $(caravel-timing-typ-targets)
+
+.PHONY: caravel-timing-typ
+$(caravel-timing-typ-targets): export LIB_CORNER = t
+caravel-timing-typ: caravel-timing-typ-nom caravel-timing-typ-min caravel-timing-typ-max
+
+.PHONY: caravel-timing-typ-nom
+.PHONY: caravel-timing-typ-min
+.PHONY: caravel-timing-typ-max
+caravel-timing-typ-nom: export RCX_CORNER = nom
+caravel-timing-typ-min: export RCX_CORNER = min
+caravel-timing-typ-max: export RCX_CORNER = max
+
+.PHONY: caravel-timing-slow
+$(caravel-timing-slow-targets): export LIB_CORNER = s
+caravel-timing-slow: caravel-timing-slow-nom caravel-timing-slow-min caravel-timing-slow-max
+
+.PHONY: caravel-timing-slow-nom
+.PHONY: caravel-timing-slow-min
+.PHONY: caravel-timing-slow-max
+caravel-timing-slow-nom: export RCX_CORNER = nom
+caravel-timing-slow-min: export RCX_CORNER = min
+caravel-timing-slow-max: export RCX_CORNER = max
+
+.PHONY: caravel-timing-fast
+$(caravel-timing-fast-targets): export LIB_CORNER = f
+caravel-timing-fast: caravel-timing-fast-nom caravel-timing-fast-min caravel-timing-fast-max
+
+.PHONY: caravel-timing-fast-nom
+.PHONY: caravel-timing-fast-min
+.PHONY: caravel-timing-fast-max
+caravel-timing-fast-nom: export RCX_CORNER = nom
+caravel-timing-fast-min: export RCX_CORNER = min
+caravel-timing-fast-max: export RCX_CORNER = max
+
+$(caravel-timing-targets): $(logs-dir)/top
+ $(call docker_run_caravel_timing)
+
+
+# some useful dev double checking
+#
+rcx-requirements = $(CARAVEL_ROOT)/def/%.def
+rcx-requirements += $(CARAVEL_ROOT)/lef/%.lef
+rcx-requirements += $(CARAVEL_ROOT)/sdc/%.sdc
+rcx-requirements += $(CARAVEL_ROOT)/verilog/gl/%.v
+
+exceptions = $(MCW_ROOT)/lef/caravel.lef
+exceptions += $(MCW_ROOT)/lef/caravan.lef
+# lets ignore these for now
+exceptions += $(MCW_ROOT)/sdc/user_analog_project_wrapper.sdc
+exceptions += $(MCW_ROOT)/sdc/user_project_wrapper.sdc
+exceptions += $(MCW_ROOT)/verilog/gl/user_analog_project_wrapper.v
+exceptions += $(MCW_ROOT)/verilog/gl/user_project_wrapper.v
+
+.PHONY: list-rcx
+.PHONY: list-sdf
+.PHONY: rcx-all
+list-rcx:
+ @blocks="$(rcx-blocks)";\
+ for block in $${blocks}; do echo "$$block"; done
+list-sdf:
+ @echo $(sdf-blocks)
+list-sta:
+ @echo $(sta-blocks)
+rcx-all: $(rcx-blocks)
+
+$(exceptions):
+ $(warning we don't need lefs for $@ but take note anyway)
+
+$(CARAVEL_ROOT)/def/%.def: $(MCW_ROOT)/def/%.def ;
+$(MCW_ROOT)/def/%.def: $(CUP_ROOT)/def/%.def ;
+$(CUP_ROOT)/def/%.def:
+ $(error error if you are here it probably means that $@.def is mising from mcw and caravel)
+
+$(CARAVEL_ROOT)/lef/%.lef: $(MCW_ROOT)/lef/%.lef ;
+$(MCW_ROOT)/lef/%.lef: $(CUP_ROOT)/lef/%.lef ;
+$(CUP_ROOT)/lef/%.lef:
+ $(error error if you are here it probably means that $@.lef is mising from mcw and caravel)
+
+$(CARAVEL_ROOT)/sdc/%.sdc: $(MCW_ROOT)/sdc/%.sdc ;
+$(MCW_ROOT)/sdc/%.sdc: $(CUP_ROOT)/sdc/%.sdc ;
+$(CUP_ROOT)/sdc/%.sdc:
+ $(error error if you are here it probably means that $@.sdc is mising from mcw and caravel)
+
+$(CARAVEL_ROOT)/verilog/gl/%.v: $(MCW_ROOT)/verilog/gl/%.v ;
+$(MCW_ROOT)/verilog/gl/%.v: $(CUP_ROOT)/verilog/gl/%.v ;
+$(CUP_ROOT)/verilog/gl/%.v:
+ $(error error if you are here it probably means that gl/$@.v is mising from mcw and caravel)
+
+check_defined = \
+ $(strip $(foreach 1,$1, \
+ $(call __check_defined,$1,$(strip $(value 2)))))
+__check_defined = \
+ $(if $(value $1),, \
+ $(error Undefined $1$(if $2, ($2))))
+
+$(call check_defined, \
+ MCW_ROOT \
+ CUP_ROOT \
+ PDK_ROOT \
+ CARAVEL_ROOT \
+ TIMING_ROOT \
+)
diff --git a/gds/cntr_example.gds b/gds/cntr_example.gds
index 257e2c6..250edc3 100644
--- a/gds/cntr_example.gds
+++ b/gds/cntr_example.gds
Binary files differ
diff --git a/gds/user_project_wrapper.gds b/gds/user_project_wrapper.gds
index ce74deb..5e23b04 100644
--- a/gds/user_project_wrapper.gds
+++ b/gds/user_project_wrapper.gds
Binary files differ
diff --git a/mag/cntr_example.mag b/mag/cntr_example.mag
index 83702b7..56d920f 100644
--- a/mag/cntr_example.mag
+++ b/mag/cntr_example.mag
@@ -1,7 +1,7 @@
magic
tech gf180mcuC
magscale 1 10
-timestamp 1670103083
+timestamp 1670116064
<< metal1 >>
rect 1344 296378 298592 296412
rect 1344 296326 19838 296378
diff --git a/mag/user_project_wrapper.mag b/mag/user_project_wrapper.mag
index 7912e1d..8a99482 100644
--- a/mag/user_project_wrapper.mag
+++ b/mag/user_project_wrapper.mag
@@ -1,7 +1,7 @@
magic
tech gf180mcuC
magscale 1 10
-timestamp 1670103864
+timestamp 1670116506
<< metal1 >>
rect 215058 130286 215070 130338
rect 215122 130286 215134 130338
diff --git a/maglef/cntr_example.mag b/maglef/cntr_example.mag
index e6e349b..7eaa7e4 100644
--- a/maglef/cntr_example.mag
+++ b/maglef/cntr_example.mag
@@ -1,7 +1,7 @@
magic
tech gf180mcuC
magscale 1 5
-timestamp 1670103090
+timestamp 1670116072
<< obsm1 >>
rect 672 1538 149296 148206
<< metal2 >>
@@ -240,7 +240,7 @@
string LEFclass BLOCK
string LEFview TRUE
string GDS_END 8011482
-string GDS_FILE /home/htf6ry/gf180-demo/openlane/cntr_example/runs/22_12_03_16_29/results/signoff/cntr_example.magic.gds
+string GDS_FILE /home/htf6ry/gf180-demo/openlane/cntr_example/runs/22_12_03_20_05/results/signoff/cntr_example.magic.gds
string GDS_START 105720
<< end >>
diff --git a/maglef/user_project_wrapper.mag b/maglef/user_project_wrapper.mag
index 84d7c01..3c919fc 100644
--- a/maglef/user_project_wrapper.mag
+++ b/maglef/user_project_wrapper.mag
@@ -1,7 +1,7 @@
magic
tech gf180mcuC
magscale 1 5
-timestamp 1670103872
+timestamp 1670116514
<< obsm1 >>
rect 63172 64975 211796 213206
<< metal2 >>
@@ -2151,7 +2151,7 @@
string LEFclass BLOCK
string LEFview TRUE
string GDS_END 10806318
-string GDS_FILE /home/htf6ry/gf180-demo/openlane/user_project_wrapper/runs/22_12_03_16_43/results/signoff/user_project_wrapper.magic.gds
+string GDS_FILE /home/htf6ry/gf180-demo/openlane/user_project_wrapper/runs/22_12_03_20_14/results/signoff/user_project_wrapper.magic.gds
string GDS_START 8011542
<< end >>
diff --git a/sdc/cntr_example.sdc b/sdc/cntr_example.sdc
index 557bdf5..0109de3 100644
--- a/sdc/cntr_example.sdc
+++ b/sdc/cntr_example.sdc
@@ -1,6 +1,6 @@
###############################################################################
# Created by write_sdc
-# Sat Dec 3 21:30:38 2022
+# Sun Dec 4 01:07:00 2022
###############################################################################
current_design cntr_example
###############################################################################
diff --git a/sdc/user_project_wrapper.sdc b/sdc/user_project_wrapper.sdc
index 4611df8..cc7daed 100644
--- a/sdc/user_project_wrapper.sdc
+++ b/sdc/user_project_wrapper.sdc
@@ -1,6 +1,6 @@
###############################################################################
# Created by write_sdc
-# Sat Dec 3 21:43:59 2022
+# Sun Dec 4 01:14:40 2022
###############################################################################
current_design user_project_wrapper
###############################################################################