Made several improvements for handling timestamps.  All of the .mag
files generated now get a timestamp that is derived from the date of
the last open_pdks commit.  In particular, the abstract and full views
of cells both have the same timestamp, so changing views by dereferencing
won't result in timestamp updates.  This is not as good as implementing a
checksum method, but it is an improvement over having all timestamps
being the time at which each individual file was written.
diff --git a/VERSION b/VERSION
index ee05afe..3b79cbb 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.271
+1.0.272
diff --git a/common/foundry_install.py b/common/foundry_install.py
index 0747c68..6657793 100755
--- a/common/foundry_install.py
+++ b/common/foundry_install.py
@@ -9,6 +9,7 @@
 # Options:
 #    -ef_format		Use efabless naming (libs.ref/techLEF),
 #			otherwise use generic naming (libs.tech/lef)
+#    -timestamp <value>	Pass a timestamp to use for stamping GDS and MAG files
 #    -clean		Clear out and remove target directory before starting
 #    -source <path>	Path to source data top level directory
 #    -target <path>	Path to target (staging) top level directory
@@ -188,6 +189,7 @@
     print("foundry_install.py [options...]")
     print("   -copy             Copy files from source to target (default)")
     print("   -ef_format        Use efabless naming conventions for local directories")
+    print("   -timestamp <value> Use <value> for timestamping files")
     print("")
     print("   -source <path>    Path to top of source directory tree")
     print("   -target <path>    Path to top of target directory tree")
@@ -441,6 +443,8 @@
     targetdir = None
 
     ef_format = False
+    do_timestamp = False
+    timestamp_value = 0
     do_clean = False
 
     have_lef = False
@@ -484,6 +488,14 @@
         elif option[0] == 'std_naming' or option[0] == 'std_names' or option[0] == 'std_format':
             optionlist.remove(option)
             ef_format = False
+        elif option[0] == 'timestamp':
+            optionlist.remove(option)
+            if len(option) > 1:
+                timestamp_value = option[1]
+                do_timestamp = True
+            else:
+                print('Error: Option "timestamp" used with no value.')
+
         elif option[0] == 'clean':
             do_clean = True
 
@@ -562,6 +574,7 @@
     # Check for magic version and set flag if it does not exist or if
     # it has the wrong version.
     have_mag_8_2 = False
+    have_mag_8_3_261 = False
     try:
         mproc = subprocess.run(
             ['magic', '--version'],
@@ -580,6 +593,14 @@
                     if int(mag_version_info[1]) >= 2:
                         have_mag_8_2 = True
                         print('Magic version 8.2 (or better) available on the system.')
+                if int(mag_version_info[0]) > 8:
+                    have_mag_8_3_261 = True
+                elif int(mag_version_info[0]) == 8:
+                    if int(mag_version_info[1]) > 3:
+                        have_mag_8_3_261 = True
+                    elif int(mag_version_info[1]) == 3:
+                        if int(mag_version_info[2]) >= 261:
+                            have_mag_8_3_261 = True
             except ValueError:
                 print('Error: "magic --version" did not return valid version number.')
                 if mproc.stderr:
@@ -1407,6 +1428,8 @@
                     print('#--------------------------------------------', file=ofile)
                     print('crashbackups stop', file=ofile)
                     print('drc off', file=ofile)
+                    if do_timestamp and have_mag_8_3_261:
+                        print('gds datestamp ' + str(timestamp_value), file=ofile)
                     print('gds readonly true', file=ofile)
                     print('gds drccheck false', file=ofile)
                     print('gds flatten true', file=ofile)
@@ -1799,6 +1822,10 @@
                         tcldevlist = '{' + ' '.join(shortdevlist) + '}'
                         print('set devlist ' + tcldevlist, file=ofile)
 
+                    # Force the abstract view timestamps to match the full views
+                    if do_timestamp and have_mag_8_3_261:
+                        print('lef datestamp ' + str(timestamp_value), file=ofile)
+
                     for leffile in leffiles:
                         print('lef read ' + srclibdir + '/' + leffile, file=ofile)
 
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index 8215e18..9baeb8c 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -265,6 +265,10 @@
 SKY130A_DEFS += -DSTAGING_PATH=${STAGING_PATH}
 SKY130B_DEFS += -DSTAGING_PATH=${STAGING_PATH}
 
+# Get the timestamp of the open_pdks commit to use for stamping layouts.
+OPEN_PDKS_TIMESTAMP = $(shell git log -1 --format="%ad" --date=raw | cut -d' ' -f1)
+TIMESTAMP_OPT = -timestamp ${OPEN_PDKS_TIMESTAMP}
+
 # Record commit numbers for the nodeinfo.json file
 OPEN_PDKS_COMMIT = $(shell git rev-parse HEAD)
 ifeq (${OPEN_PDKS_COMMIT},)
@@ -451,7 +455,7 @@
 
 # The following script in the ../common directory does most of the work of
 # copying or linking the foundry vendor files to the target directory.
-STAGE = set -f ; ../common/foundry_install.py ${EF_FORMAT}
+STAGE = set -f ; ../common/foundry_install.py ${EF_FORMAT} ${TIMESTAMP_OPT}
 ifneq ($(DESTDIR), )
 INSTALL = ../common/staging_install.py -writeto $(DESTDIR) ${EF_FORMAT}
 else
diff --git a/sky130/magic/sky130.tech b/sky130/magic/sky130.tech
index c89d937..4252baf 100644
--- a/sky130/magic/sky130.tech
+++ b/sky130/magic/sky130.tech
@@ -23,7 +23,7 @@
 version
  version REVISION
  description "SkyWater SKY130: Open Source rules and DRC"
- requires magic-8.3.111
+ requires magic-8.3.260
 end
 
 #------------------------------------------------------------------------
@@ -722,10 +722,10 @@
   paint  coreli  nsc    nsc
   paint  coreli  psc    psc
   paint  coreli  viali  viali
-  paint  coreli  mvpdc  mvdc
-  paint  coreli  mvndc  mvdc
-  paint  coreli  mvnsc  mvsc
-  paint  coreli  mvpsc  mvsc
+  paint  coreli  mvpdc  mvpdc
+  paint  coreli  mvndc  mvndc
+  paint  coreli  mvnsc  mvnsc
+  paint  coreli  mvpsc  mvpsc
 
 #ifdef RERAM
   paint  reram  metal2  reram