hardcode docker version to riscduino/openlane:mpw5
diff --git a/openlane/Makefile b/openlane/Makefile
index d5f37cb..ecdee61 100644
--- a/openlane/Makefile
+++ b/openlane/Makefile
@@ -19,8 +19,8 @@
 CONFIG = $(foreach block,$(BLOCKS), ./$(block)/config.tcl)
 CLEAN = $(foreach block,$(BLOCKS), clean-$(block))
 
-OPENLANE_TAG ?= mpw4
-OPENLANE_IMAGE_NAME ?= riscduino/openlane:$(OPENLANE_TAG)
+OPENLANE_TAG = mpw5
+OPENLANE_IMAGE_NAME = riscduino/openlane:$(OPENLANE_TAG)
 OPENLANE_BASIC_COMMAND = "cd /project/openlane && flow.tcl -design ./$* -save_path .. -save -tag $* -overwrite"
 OPENLANE_INTERACTIVE_COMMAND = "cd /project/openlane && flow.tcl -it -file ./$*/interactive.tcl -design ./$* -save_path .. -save -tag $* -overwrite"
 
@@ -44,20 +44,12 @@
 
 	@if [ -f ./$*/interactive.tcl ]; then\
 		docker run -it -v $(OPENLANE_ROOT):/openLANE_flow \
-		-v $(PDK_ROOT):$(PDK_ROOT) \
 		-v $(PWD)/..:/project \
-		-v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
-		-e PDK_ROOT=$(PDK_ROOT) \
-		-e CARAVEL_ROOT=$(CARAVEL_ROOT) \
 		-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
 		$(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_INTERACTIVE_COMMAND);\
 	else\
 		docker run -it -v $(OPENLANE_ROOT):/openLANE_flow \
-		-v $(PDK_ROOT):$(PDK_ROOT) \
 		-v $(PWD)/..:/project \
-		-v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
-		-e PDK_ROOT=$(PDK_ROOT) \
-		-e CARAVEL_ROOT=$(CARAVEL_ROOT) \
 		-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
 		$(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_BASIC_COMMAND);\
 	fi
diff --git a/openlane/io_place.py b/openlane/io_place.py
deleted file mode 100755
index 86ac1f2..0000000
--- a/openlane/io_place.py
+++ /dev/null
@@ -1,528 +0,0 @@
-# Copyright 2020 Efabless Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Places the IOs according to an input file. Supports regexes.
-File format:
-#N|#S|#E|#W
-pin1_regex
-pin2_regex
-...
-
-#S|#N|#E|#W
-...
-...
-"""
-import odb
-
-import os
-import re
-import sys
-import click
-import random
-
-
-@click.command()
-@click.option("-l", "--input-lef", required=True, help="Input merged tlef/lef file.")
-@click.option(
-    "-o",
-    "--output-def",
-    default="./output.def",
-    help="Output DEF file with newly placed pins",
-)
-@click.option("-c", "--config", required=False, help="Optional configuration file.")
-@click.option(
-    "-r",
-    "--reverse",
-    default="",
-    type=str,
-    help="Reverse along comma,delimited,cardinals: e.g. N,E",
-)
-@click.option("-L", "--length", default=2, type=float, help="Pin length in microns.")
-@click.option(
-    "-V",
-    "--ver-layer",
-    required=True,
-    help="Name of metal layer to place vertical pins on.",
-)
-@click.option(
-    "-H",
-    "--hor-layer",
-    required=True,
-    help="Name of metal layer to place horizontal pins on.",
-)
-@click.option(
-    "--hor-extension",
-    default=0,
-    type=float,
-    help="Extension for vertical pins in microns.",
-)
-@click.option(
-    "--ver-extension",
-    default=0,
-    type=float,
-    help="Extension for horizontal pins in microns.",
-)
-@click.option(
-    "--ver-width-mult", default=2, type=float, help="Multiplier for vertical pins."
-)
-@click.option(
-    "--hor-width-mult", default=2, type=float, help="Multiplier for horizontal pins."
-)
-@click.option(
-    "--bus-sort/--no-bus-sort",
-    default=False,
-    help="Misnomer: pins are grouped by index instead of bus, i.e. a[0] goes with b[0] instead of a[1].",
-)
-@click.argument("input_def")
-def cli(
-    input_lef,
-    output_def,
-    config,
-    ver_layer,
-    hor_layer,
-    ver_width_mult,
-    hor_width_mult,
-    length,
-    hor_extension,
-    ver_extension,
-    reverse,
-    bus_sort,
-    input_def,
-):
-    """
-    Places the IOs in an input def with an optional config file that supports regexes.
-
-    Config format:
-    #N|#S|#E|#W
-    pin1_regex (low co-ordinates to high co-ordinates; e.g., bottom to top and left to right)
-    pin2_regex
-    ...
-
-    #S|#N|#E|#W
-    """
-
-    def_file_name = input_def
-    lef_file_name = input_lef
-    output_def_file_name = output_def
-    config_file_name = config
-    bus_sort_flag = bus_sort
-
-    #1. Manual Pad Placement - Dinesh A
-    manual_place_flag = False 
-
-    h_layer_name = hor_layer
-    v_layer_name = ver_layer
-
-    h_width_mult = float(hor_width_mult)
-    v_width_mult = float(ver_width_mult)
-
-    # Initialize OpenDB
-    db_top = odb.dbDatabase.create()
-    odb.read_lef(db_top, lef_file_name)
-    odb.read_def(db_top, def_file_name)
-    block = db_top.getChip().getBlock()
-
-    micron_in_units = block.getDefUnits()
-
-    LENGTH = int(micron_in_units * length)
-
-    H_EXTENSION = int(micron_in_units * hor_extension)
-    V_EXTENSION = int(micron_in_units * ver_extension)
-
-    if H_EXTENSION < 0:
-        H_EXTENSION = 0
-
-    if V_EXTENSION < 0:
-        V_EXTENSION = 0
-
-    reverse_arr_raw = reverse.split(",")
-    reverse_arr = []
-    for element in reverse_arr_raw:
-        if element.strip() != "":
-            reverse_arr.append(f"#{element}")
-
-    def getGrid(origin, count, step):
-        tracks = []
-        pos = origin
-        for i in range(count):
-            tracks.append(pos)
-            pos += step
-        assert len(tracks) > 0
-        tracks.sort()
-
-        return tracks
-
-    def equallySpacedSeq(m, arr):
-        seq = []
-        n = len(arr)
-        # Bresenham
-        indices = [i * n // m + n // (2 * m) for i in range(m)]
-        for i in indices:
-            seq.append(arr[i])
-        return seq
-
-    # HUMAN SORTING: https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside
-    def natural_keys(enum):
-        def atof(text):
-            try:
-                retval = float(text)
-            except ValueError:
-                retval = text
-            return retval
-
-        text = enum[0]
-        text = re.sub(r"(\[|\]|\.|\$)", "", text)
-        """
-        alist.sort(key=natural_keys) sorts in human order
-        http://nedbatchelder.com/blog/200712/human_sorting.html
-        (see toothy's implementation in the comments)
-        float regex comes from https://stackoverflow.com/a/12643073/190597
-        """
-        return [
-            atof(c) for c in re.split(r"[+-]?([0-9]+(?:[.][0-9]*)?|[.][0-9]+)", text)
-        ]
-
-    def bus_keys(enum):
-        text = enum[0]
-        m = re.match(r"^.*\[(\d+)\]$", text)
-        if not m:
-            return -1
-        else:
-            return int(m.group(1))
-
-    #2. Find the Slot matching next nearest slot-DineshA
-    def findSlot(val, arr):
-        for i in arr:
-            if(i > val):
-                return i
-        print("ERROR: Next Valid Position not found :",val)
-        return -1
-
-    # read config
-
-    pin_placement_cfg = {"#N": [], "#E": [], "#S": [], "#W": []}
-    cur_side = None
-    if config_file_name is not None and config_file_name != "":
-        with open(config_file_name, "r") as config_file:
-            for line in config_file:
-                line = line.split()
-                if len(line) == 0:
-                    continue
-
-                #3. Dinesh A - Start
-                if(manual_place_flag == False):
-                    if len(line) > 1:
-                        print("Only one entry allowed per line.")
-                        sys.exit(1)
-                    token = line[0]
-                else:
-                    #During Manual Place we are allowing Four field
-                    # <Pad Name> <Offset> <Position> <Multiplier>
-                    # Causion: Make sure that you have given absolute name, else it will give issue
-                    if len(line) > 4:
-                        print("Only Four entry allowed per line.")
-                        sys.exit(1)
-                    if line[0] not in ["#N", "#E", "#S", "#W", "#NR", "#ER", "#SR", "#WR"]:
-                        token = line
-                    else:
-                        token = line[0]
-
-                if cur_side is not None and token[0] != "#":
-                    pin_placement_cfg[cur_side].append(token)
-                elif token not in [
-                    "#N",
-                    "#E",
-                    "#S",
-                    "#W",
-                    "#NR",
-                    "#ER",
-                    "#SR",
-                    "#WR",
-                    "#BUS_SORT",
-                    "#MANUAL_PLACE"
-                ]:
-                    print(
-                        "Valid directives are #N, #E, #S, or #W. Append R for reversing the default order.",
-                        "Use #BUS_SORT to group 'bus bits' by index.",
-                        "Please make sure you have set a valid side first before listing pins",
-                    )
-                    sys.exit(1)
-                elif token == "#BUS_SORT":
-                    bus_sort_flag = True
-                #4 - Dinesh A
-                elif token == "#MANUAL_PLACE":
-                    print("Input token ",token)
-                    manual_place_flag = True
-                else:
-                    if len(token) == 3:
-                        token = token[0:2]
-                        reverse_arr.append(token)
-                    cur_side = token
-
-    # build a list of pins
-
-    chip_top = db_top.getChip()
-    block_top = chip_top.getBlock()
-    top_design_name = block_top.getName()
-    tech = db_top.getTech()
-
-    H_LAYER = tech.findLayer(h_layer_name)
-    V_LAYER = tech.findLayer(v_layer_name)
-
-    H_WIDTH = int(h_width_mult * H_LAYER.getWidth())
-    V_WIDTH = int(v_width_mult * V_LAYER.getWidth())
-
-    print("Top-level design name:", top_design_name)
-
-    bterms = block_top.getBTerms()
-    bterms_enum = []
-    for bterm in bterms:
-        pin_name = bterm.getName()
-        bterms_enum.append((pin_name, bterm))
-
-    # sort them "humanly"
-    bterms_enum.sort(key=natural_keys)
-    if bus_sort_flag:
-        bterms_enum.sort(key=bus_keys)
-    bterms = [bterm[1] for bterm in bterms_enum]
-
-    pin_placement = {"#N": [], "#E": [], "#S": [], "#W": []}
-    bterm_regex_map = {}
-    #5. Dinesh A
-    if(manual_place_flag == False):
-	    for side in pin_placement_cfg:
-                for regex in pin_placement_cfg[side]:  # going through them in order
-                    regex += "$"  # anchor
-                    for bterm in bterms:
-                        # if a pin name matches multiple regexes, their order will be
-                        # arbitrary. More refinement requires more strict regexes (or just
-                        # the exact pin name).
-                        pin_name = bterm.getName()
-                        if re.match(regex, pin_name) is not None:
-                            if bterm in bterm_regex_map:
-                                print(
-		                    "Error: Multiple regexes matched",
-		                    pin_name,
-		                    ". Those are",
-		                    bterm_regex_map[bterm],
-		                    "and",
-		                    regex,
-		                )
-                                sys.exit(os.EX_DATAERR)
-                            bterm_regex_map[bterm] = regex
-                            pin_placement[side].append(bterm)  # to maintain the order
-
-	    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
-
-	    if len(unmatched_bterms) > 0:
-                print("Warning: Some pins weren't matched by the config file")
-                print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
-                if True:
-                    print("Assigning random sides to the above pins")
-                    for bterm in unmatched_bterms:
-                        random_side = random.choice(list(pin_placement.keys()))
-                        pin_placement[random_side].append(bterm)
-                else:
-                    sys.exit(1)
-
-    #6 Dinesh A
-    else:
-	    for side in pin_placement_cfg:
-                for regex in pin_placement_cfg[side]:  # going through them in order
-                    regex = regex[0]  # take first value
-                    regex += "$"  # anchor
-                    for bterm in bterms:
-		        # if a pin name matches multiple regexes, their order will be
-		        # arbitrary. More refinement requires more strict regexes (or just
-		        # the exact pin name).
-                        pin_name = bterm.getName()
-                        if re.match(regex, pin_name) is not None:
-                            print("Debug: Serching Pin match",regex)
-                            if bterm in bterm_regex_map:
-                                #print("Warning: Multiple regexes matched", pin_name)
-                                #      ". Those are", bterm_regex_map[bterm], "and", regex)
-                                sys.exit(1)
-                            bterm_regex_map[bterm] = regex
-                            pin_placement[side].append(bterm)  # to maintain the order
-	    
-	    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
-	    
-	    if len(unmatched_bterms) > 0:
-                print("Warning: Some pins weren't matched by the config file")
-                print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
-                sys.exit(1)
-
-
-    assert len(block_top.getBTerms()) == len(
-        pin_placement["#N"]
-        + pin_placement["#E"]
-        + pin_placement["#S"]
-        + pin_placement["#W"]
-    )
-
-    # generate slots
-
-    DIE_AREA = block_top.getDieArea()
-    BLOCK_LL_X = DIE_AREA.xMin()
-    BLOCK_LL_Y = DIE_AREA.yMin()
-    BLOCK_UR_X = DIE_AREA.xMax()
-    BLOCK_UR_Y = DIE_AREA.yMax()
-
-    print("Block boundaries:", BLOCK_LL_X, BLOCK_LL_Y, BLOCK_UR_X, BLOCK_UR_Y)
-
-    origin, count, step = block_top.findTrackGrid(H_LAYER).getGridPatternY(0)
-
-    #7. Save the horizontal origin and step - DineshA
-    h_origin = origin
-    h_step   = step
-
-    h_tracks = getGrid(origin, count, step)
-
-    origin, count, step = block_top.findTrackGrid(V_LAYER).getGridPatternX(0)
-
-    #8. Save the horizontal origin and step - DineshA
-    v_origin = origin
-    v_step   = step
-
-    v_tracks = getGrid(origin, count, step)
-
-    for rev in reverse_arr:
-        pin_placement[rev].reverse()
-
-    # create the pins
-    #9.  DineshA
-    if(manual_place_flag == False):
-	    for side in pin_placement:
-                if side in ["#N", "#S"]:
-                    slots = equallySpacedSeq(len(pin_placement[side]), v_tracks)
-                else:
-                    slots = equallySpacedSeq(len(pin_placement[side]), h_tracks)
-
-                assert len(slots) == len(pin_placement[side])
-
-                for i in range(len(pin_placement[side])):
-                    bterm = pin_placement[side][i]
-                    slot = slots[i]
-
-                    pin_name = bterm.getName()
-                    pins = bterm.getBPins()
-                    if len(pins) > 0:
-                        print("Warning:", pin_name, "already has shapes. Modifying them")
-                        assert len(pins) == 1
-                        pin_bpin = pins[0]
-                    else:
-                        pin_bpin = odb.dbBPin_create(bterm)
-
-                    pin_bpin.setPlacementStatus("PLACED")
-
-                    if side in ["#N", "#S"]:
-                        rect = odb.Rect(0, 0, V_WIDTH, LENGTH + V_EXTENSION)
-                        if side == "#N":
-                            y = BLOCK_UR_Y - LENGTH
-                        else:
-                            y = BLOCK_LL_Y - V_EXTENSION
-                        rect.moveTo(slot - V_WIDTH // 2, y)
-                        odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
-                    else:
-                        rect = odb.Rect(0, 0, LENGTH + H_EXTENSION, H_WIDTH)
-                        if side == "#E":
-                            x = BLOCK_UR_X - LENGTH
-                        else:
-                            x = BLOCK_LL_X - H_EXTENSION
-                        rect.moveTo(x, slot - H_WIDTH // 2)
-                        odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
-
-    else:
-	    #10.New Logic, Manual Pin Placement - Dinesh A
-	    #print("Allowed VTracks",v_tracks)
-	    #print("Allowed hTracks",h_tracks)
-
-	    for side in pin_placement:
-
-                if(len(pin_placement[side]) != len(pin_placement_cfg[side])):
-                    print("ERROR : At Side:", side, " Total Pin Defined ",len(pin_placement_cfg[side]), "More than available:",len(pin_placement[side]))
-		    
-		#check defined pad are more than avaibale one
-                assert len(pin_placement[side]) == len(pin_placement_cfg[side])
-                start = 0
-	    
-                start_loc = 0
-                pad_pos   = 0
-                slot_pre = 0
-                #Dinesh: Give Step Multipler size *2  for better pad placement
-                multiplier= 2
-                for i in range(len(pin_placement_cfg[side])):
-                    #Dinesh: Multiply the offset by 1000 for micro conversion
-                    if(len(pin_placement_cfg[side][i]) > 1):
-                        start_loc = int(pin_placement_cfg[side][i][1])
-                    if(len(pin_placement_cfg[side][i]) > 2):
-                        pad_pos   = int(pin_placement_cfg[side][i][2])
-                    if(len(pin_placement_cfg[side][i]) > 3):
-                        multiplier = int(pin_placement_cfg[side][i][3])
-
-                    if side in ["#N", "#S"]:
-                        slott = start_loc*1000+int(v_origin)+(int(v_step) * pad_pos * multiplier)
-                        slot =findSlot(slott,v_tracks)
-                    else:
-                        slott = start_loc*1000+int(h_origin)+(int(h_step) * pad_pos * multiplier)
-                        slot =findSlot(slott,h_tracks)
-		  
-                    pad_pos +=1
-                    bterm = pin_placement[side][i]
-	    
-                    pin_name = bterm.getName()
-                    pins = bterm.getBPins()
-                    if len(pins) > 0:
-                        print("Warning:", pin_name, "already has shapes. Modifying them")
-                        assert len(pins) == 1
-                        pin_bpin = pins[0]
-                    else:
-                        pin_bpin = odb.dbBPin_create(bterm)
-
-                    if(slot < slot_pre):
-                        print("ERROR:", "Current Pad:", pin_name, " Slot:" , slot, " is less than Previous One:",slot_pre)
-                        sys.exit(1)
-
-                    slot_pre = slot
-
-                    print("Dinesh: Placing Pad:" ,pin_name, " At Side: ", side, " Slot: ", slot)
-                    pin_bpin.setPlacementStatus("PLACED")
-	    
-                    if side in ["#N", "#S"]:
-                        rect = odb.Rect(0, 0, V_WIDTH, LENGTH+V_EXTENSION)
-                        if side == "#N":
-                            y = BLOCK_UR_Y-LENGTH
-                        else:
-                            y = BLOCK_LL_Y-V_EXTENSION
-                        rect.moveTo(slot-V_WIDTH//2, y)
-                        odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
-                    else:
-                        rect = odb.Rect(0, 0, LENGTH+H_EXTENSION, H_WIDTH)
-                        if side == "#E":
-                            x = BLOCK_UR_X-LENGTH
-                        else:
-                            x = BLOCK_LL_X-H_EXTENSION
-                        rect.moveTo(x, slot-H_WIDTH//2)
-                        odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
-
-
-    print(
-        f"Writing {output_def_file_name}...",
-    )
-    odb.write_def(block_top, output_def_file_name)
-
-
-if __name__ == "__main__":
-    cli()
diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl
index 1a720a6..8d8c8e0 100644
--- a/openlane/user_project_wrapper/config.tcl
+++ b/openlane/user_project_wrapper/config.tcl
@@ -20,11 +20,11 @@
 set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
 
 # YOU ARE NOT ALLOWED TO CHANGE ANY VARIABLES DEFINED IN THE FIXED WRAPPER CFGS 
-source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper_empty/fixed_wrapper_cfgs.tcl
+source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/fixed_wrapper_cfgs.tcl
 
 
 # YOU CAN CHANGE ANY VARIABLES DEFINED IN THE DEFAULT WRAPPER CFGS BY OVERRIDING THEM IN THIS CONFIG.TCL
-source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper_empty/default_wrapper_cfgs.tcl
+source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper/default_wrapper_cfgs.tcl
 
 
 set script_dir [file dirname [file normalize [info script]]]