This update changes the way that 3rd party repositories are pulled,
by using (a shallow) git clone instead of pulling a tarball.  That
allows the commit hash of every repository pulled to be queried and
saved in the .config/nodeinfo.json file for reference.  Also in this
update:  Corrected the diode device in the diode cell in the HVL
standard cell library.  Corrected the build sequence for the I/O
library, which was causing the addition of the SPICE netlists for
the I/O pads to be missed.
diff --git a/scripts/download.sh b/scripts/download.sh
index a4188d9..574c1f2 100755
--- a/scripts/download.sh
+++ b/scripts/download.sh
@@ -8,47 +8,68 @@
 #
 # where:
 #
-#	<url> is the URL of the repository to download, in gzipped tarball format
+#	<url> is the URL of the repository to download.  If the <url> ends
+#		in 'gz' then it is assumed to be a gzipped tarball format.
+#		Otherwise, it is assumed to be a clonable git repo.
 #	<target_dir> is the local name to call the untarred directory.  The
 #		tarball will be downloaded to the directory above this,
 #		untarred while renaming to <target_dir>, and then the tarball
 #		file will be deleted.
 #	<strip> is the number of directory levels to strip off the front of the
-#		tarball contents.  Defaults to 1 if not specified.
+#		tarball contents.  Defaults to 1 if not specified (only
+#		applicable if <url> points to a tarball).
 #
 
-# Neither curl or wget are guaranteed to be included in all *nix systems,
-# (but most have *one* of them). This tools tries its best to find one.
+# Check if <url> points to a tarball or a repository (note:  this assumes
+# the form on github where the filename is spelled out as ".tar.gz" and
+# not ".tgz")
 
-DL_CMD=
-if type "wget" > /dev/null; then
-    DL_CMD="wget -qO"
-fi
+if ${1: -3} == ".gz"; then
 
-if type "curl" > /dev/null; then
-    DL_CMD="curl -sLo"
-fi
+    # Neither curl or wget are guaranteed to be included in all *nix systems,
+    # (but most have *one* of them). This tools tries its best to find one.
 
-if [ "$DL_CMD" = "" ]; then
-    echo "ERROR: Either curl or wget are required to automatically install tools."
-    exit 1
-fi
+    DL_CMD=
+    if type "wget" > /dev/null; then
+        DL_CMD="wget -qO"
+    fi
 
-pdir=`dirname $2`
-mkdir -p $pdir
-cd $pdir
+    if type "curl" > /dev/null; then
+        DL_CMD="curl -sLo"
+    fi
 
-echo "Downloading $1 to $2"
-$DL_CMD $2.tar.gz $1
+    if [ "$DL_CMD" = "" ]; then
+        echo "ERROR: Either curl or wget are required to automatically install tools."
+        exit 1
+    fi
 
-if [ $# -gt 2 ]; then
-    snum=$3
+    pdir=`dirname $2`
+    mkdir -p $pdir
+    cd $pdir
+
+    echo "Downloading $1 to $2"
+    $DL_CMD $2.tar.gz $1
+
+    if [ $# -gt 2 ]; then
+        snum=$3
+    else
+        snum=1
+    fi
+
+    mkdir -p $2
+    echo "Untarring and removing $2.tar.gz"
+    tar -xf $2.tar.gz --strip-components $snum -C $2
+    rm $2.tar.gz
+
 else
-    snum=1
+
+    if type "git" > /dev/null; then
+        echo "Cloning $1 to $2"
+        git clone --depth 1 $1 $2
+    else
+        echo "ERROR: \"git\" is required to automatically install tools."
+        exit 1
+    fi
 fi
 
-mkdir -p $2
-echo "Untarring and removing $2.tar.gz"
-tar -xf $2.tar.gz --strip-components $snum -C $2
-rm $2.tar.gz
 exit 0
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index ace3f01..cc3bce0 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -211,13 +211,13 @@
 OSU_T18_PATH = @SKY130_OSU_T18_PATH@
 
 PDK_URL = https://github.com/google/skywater-pdk
-ALPHA_URL = https://github.com/PaulSchulz/sky130_pschulz_xx_hd/archive/master.tar.gz
-XSCHEM_URL = https://github.com/StefanSchippers/xschem_sky130/archive/main.tar.gz
-SRAM_URL = https://github.com/efabless/sky130_sram_macros/archive/main.tar.gz
-OSU_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc/+archive/refs/heads/main.tar.gz
-OSU_T12_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12/+archive/refs/heads/main.tar.gz
-OSU_T15_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t15/+archive/refs/heads/main.tar.gz
-OSU_T18_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t18/+archive/refs/heads/main.tar.gz
+ALPHA_URL = https://github.com/PaulSchulz/sky130_pschulz_xx_hd
+XSCHEM_URL = https://github.com/StefanSchippers/xschem_sky130
+SRAM_URL = https://github.com/efabless/sky130_sram_macros
+OSU_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc
+OSU_T12_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12
+OSU_T15_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t15
+OSU_T18_URL = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t18
 
 # NOTE:  Install destination is the git repository of the technology platform.
 # Once updated in git, the git project can be distributed to all hosts.
@@ -256,6 +256,65 @@
 # Add staging path
 SKY130A_DEFS += -DSTAGING_PATH=${STAGING_PATH}
 
+# Record commit numbers for the nodeinfo.json file
+OPEN_PDKS_COMMIT = $(shell git rev-parse HEAD)
+ifeq (${OPEN_PDKS_COMMIT},)
+    COMMIT_DEFS = -DOPEN_PDKS_COMMIT=${REVISION}
+else
+    COMMIT_DEFS = -DOPEN_PDKS_COMMIT=${OPEN_PDKS_COMMIT}
+endif
+ifeq (${ALPHA_PATH},)
+    COMMIT_DEFS += -DALPHA_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DALPHA_COMMIT=$(shell cd ${ALPHA_PATH} ; git rev-parse HEAD)
+endif
+ifeq (${SRAM_PATH},)
+    COMMIT_DEFS += -DSRAM_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DSRAM_COMMIT=$(shell cd ${SRAM_PATH} ; git rev-parse HEAD)
+endif
+ifeq (${OSU_PATH},)
+    COMMIT_DEFS += -DOSU_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DOSU_COMMIT=$(shell cd ${OSU_PATH} ; git rev-parse HEAD)
+endif
+ifeq (${OSU_T12_PATH},)
+    COMMIT_DEFS += -DOSU_T12_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DOSU_T12_COMMIT=$(shell cd ${OSU_T12_PATH} ; git rev-parse HEAD)
+endif
+ifeq (${OSU_T15_PATH},)
+    COMMIT_DEFS += -DOSU_T15_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DOSU_T15_COMMIT=$(shell cd ${OSU_T15_PATH} ; git rev-parse HEAD)
+endif
+ifeq (${OSU_T18_PATH},)
+    COMMIT_DEFS += -DOSU_T18_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DOSU_T18_COMMIT=$(shell cd ${OSU_T18_PATH} ; git rev-parse HEAD)
+endif
+ifeq (${SKYWATER_PATH},)
+    COMMIT_DEFS += -DFD_PR_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_IO_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_HD_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_HDLL_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_HVL_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_HS_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_MS_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_LS_COMMIT="unknown"
+    COMMIT_DEFS += -DFD_SC_LP_COMMIT="unknown"
+else
+    COMMIT_DEFS += -DFD_PR_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_pr/latest)
+    COMMIT_DEFS += -DFD_IO_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_io/latest)
+    COMMIT_DEFS += -DFD_SC_HD_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_hd/latest)
+    COMMIT_DEFS += -DFD_SC_HDLL_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_hdll/latest)
+    COMMIT_DEFS += -DFD_SC_HVL_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_hvl/latest)
+    COMMIT_DEFS += -DFD_SC_HS_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_hs/latest)
+    COMMIT_DEFS += -DFD_SC_MS_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_ms/latest)
+    COMMIT_DEFS += -DFD_SC_LS_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_ls/latest)
+    COMMIT_DEFS += -DFD_SC_LP_COMMIT=$(shell cd ${SKYWATER_PATH} ; git rev-parse @:libraries/sky130_fd_sc_lp/latest)
+endif
+
 ifeq (${EF_STYLE}, 1)
     EF_FORMAT = -ef_format
     SKY130A_DEFS += -DEF_FORMAT
@@ -512,7 +571,7 @@
 general-a: ${TECH}.json
 	mkdir -p ${STAGING_PATH}/${SKY130A}/${CONFIG_DIR}
 	rm -f ${STAGING_PATH}/${SKY130A}/${CONFIG_DIR}/nodeinfo.json
-	${CPP} ${SKY130A_DEFS} ${TECH}.json \
+	${CPP} ${SKY130A_DEFS} ${COMMIT_DEFS} ${TECH}.json \
 		${STAGING_PATH}/${SKY130A}/${CONFIG_DIR}/nodeinfo.json
 
 tools-a: $(addsuffix -a, $(TOOLS))
@@ -842,8 +901,6 @@
 		-library general sky130_fd_io 2>&1 | tee -a ${SKY130A}_make.log
 	# Install SkyWater I/O pad library
 	${STAGE} -source ${SKYWATER_LIBS_PATH} -target ${STAGING_PATH}/${SKY130A} \
-		-spice %l/latest/cells/*/*.spice compile-only \
-			sort=custom/scripts/sort_pdkfiles.py \
 		-cdl %l/latest/cells/*/*.cdl ignore=topography compile-only \
 			sort=custom/scripts/sort_pdkfiles.py \
 		-lef %l/latest/cells/*/*.magic.lef compile-only \
diff --git a/sky130/custom/scripts/fix_device_models.py b/sky130/custom/scripts/fix_device_models.py
index 3cafe1f..f9a258e 100755
--- a/sky130/custom/scripts/fix_device_models.py
+++ b/sky130/custom/scripts/fix_device_models.py
@@ -31,12 +31,15 @@
     modified = False
 
     dioderex = re.compile('.*[ \t]+sky130_fd_pr__diode_pw2nd[ \t]+')
+    ndioderex = re.compile('.*[ \t]+ndiode_h[ \t]+')
     shortrex = re.compile('.*[ \t]+short[ \t]+')
 
     for line in slines:
 
         # Check for incorrect diode reference
         dmatch = dioderex.match(line)
+        # Check for incorrect HVL diode ("ndiode_h") reference
+        nmatch = ndioderex.match(line)
         # Check for incorrect resistor reference
         smatch = shortrex.match(line)
         if dmatch:
@@ -46,6 +49,13 @@
             fline = re.sub('p=', 'pj=', fline)
             fixedlines.append(fline)
             modified = True
+        elif nmatch:
+            fline = re.sub('ndiode_h', 'sky130_fd_pr__diode_pw2nd_11v0', line)
+            fline = re.sub('^X', 'D', fline)
+            fline = re.sub('a=', 'area=', fline)
+            fline = re.sub('p=', 'pj=', fline)
+            fixedlines.append(fline)
+            modified = True
         elif smatch:
             fline = re.sub('short', 'sky130_fd_pr__res_generic_po', line)
             fline = re.sub('^X', 'R', fline)
diff --git a/sky130/custom/sky130_fd_io/spice/sky130_fd_io.spice b/sky130/custom/sky130_fd_io/spice/sky130_fd_io.spice
index 30002f9..da3871a 100644
--- a/sky130/custom/sky130_fd_io/spice/sky130_fd_io.spice
+++ b/sky130/custom/sky130_fd_io/spice/sky130_fd_io.spice
@@ -2910,7 +2910,6 @@
 XI288 N0 net193 VGND_IO sky130_fd_pr__res_generic_nd__hv W=0.5 L=113.375 m=1 isHV=TRUE
 XI287 vdiode net190 VGND_IO sky130_fd_pr__res_generic_nd__hv W=0.5 L=113.375 m=1
 + isHV=TRUE
-xI99
 XI206 N0 en VGND_IO VGND_IO sky130_fd_pr__nfet_g5v0d10v5 m=1 w=5.0 l=0.5 mult=1
 + sa=0.265 sb=0.265 sd=0.28 topography=normal area=0.063 perim=1.14
 XI190 net531 en VGND_IO VGND_IO sky130_fd_pr__nfet_g5v0d10v5 m=1 w=5.0 l=0.5
diff --git a/sky130/nodeinfo.json b/sky130/nodeinfo.json
new file mode 100644
index 0000000..28a2a0b
--- /dev/null
+++ b/sky130/nodeinfo.json
@@ -0,0 +1,39 @@
+{
+    "foundry" : "SW",
+    "foundry-name" : "SkyWater",
+    "node" : "sky130A",
+    "feature-size" : "130nm",
+    "status" : "active",
+    "commit" : "1c74f85cd8dbb6c0cf514316b127d746d35d829b",
+    "description" : "Skywater 0.13um CMOS, local interconntect + high-resistance poly + 5 metal layer backend stack + MiM caps + redistribution layer",
+    "options" : [
+        "METAL5",
+        "MIM",
+        "REDISTRIBUTION"
+    ],
+    "stdcells" : [
+	"sky130_fd_sc_hd" : "ac7fb61f06e6470b94e8afdf7c25268f62fbd7b1",
+	"sky130_fd_sc_hdll" : "0694bd23893de20f5233ef024acf6cca1e750ac6",
+	"sky130_fd_sc_hs" : "1d051f49bfe4e2fe9108d702a8bc2e9c081005a4",
+	"sky130_fd_sc_hvl" : "4fd4f858d16c558a6a488b200649e909bb4dd800",
+	"sky130_fd_sc_lp" : "e2c1e0646999163d35ea7b2521c3ec5c28633e63",
+	"sky130_fd_sc_ls" : "4f549e30dd91a1c264f8895e07b2872fe410a8c2",
+	"sky130_fd_sc_ms" : "ae1b7f68821505cf2d93d9d44cce5ece22710fad",
+	"sky130_osu_sc" : "unknown",
+	"sky130_osu_sc_t12" : "unknown",
+	"sky130_osu_sc_t15" : "unknown",
+	"sky130_osu_sc_t18" : "unknown"
+    ],
+    "iocells" : [
+        "sky130_fd_io" : "01b18699b4102d8e54ad1406b3991ecb652e5aee"
+    ]
+    "primitive" : [
+	"sky130_fd_pr" : "f62031a1be9aefe902d6d54cddd6f59b57627436"
+    ]
+    "memory" : [
+	"sky130_sram_macros" : "a2a737043f68ac5058aa6e62241eb3ce2a7bc062"
+    ]
+    "other" : [
+	"sky130_ml_xx_hd" : "6eb3b0718552b034f1bf1870285ff135e3fb2dcb"
+    ]
+}
diff --git a/sky130/sky130.json b/sky130/sky130.json
index f9c69ab..df875be 100644
--- a/sky130/sky130.json
+++ b/sky130/sky130.json
@@ -14,6 +14,7 @@
     "node" : "TECHNAME",
     "feature-size" : "130nm",
     "status" : "active",
+    "commit" : "OPEN_PDKS_COMMIT",
     "description" : "DESCRIPTION OPTION1 OPTION2 OPTION3",
     "options" : [
 #ifdef METAL5
@@ -38,19 +39,28 @@
 #endif (REDISTRIBUTION)
     ],
     "stdcells" : [
-	"sky130_fd_sc_hd",
-	"sky130_fd_sc_hdll",
-	"sky130_fd_sc_hs",
-	"sky130_fd_sc_hvl",
-	"sky130_fd_sc_lp",
-	"sky130_fd_sc_ls",
-	"sky130_fd_sc_ms",
-	"sky130_osu_sc",
-	"sky130_osu_sc_t12",
-	"sky130_osu_sc_t15",
-	"sky130_osu_sc_t18"
+	"sky130_fd_sc_hd" : "FD_SC_HD_COMMIT",
+	"sky130_fd_sc_hdll" : "FD_SC_HDLL_COMMIT",
+	"sky130_fd_sc_hs" : "FD_SC_HS_COMMIT",
+	"sky130_fd_sc_hvl" : "FD_SC_HVL_COMMIT",
+	"sky130_fd_sc_lp" : "FD_SC_LP_COMMIT",
+	"sky130_fd_sc_ls" : "FD_SC_LS_COMMIT",
+	"sky130_fd_sc_ms" : "FD_SC_MS_COMMIT",
+	"sky130_osu_sc" : "OSU_COMMIT",
+	"sky130_osu_sc_t12" : "OSU_T12_COMMIT",
+	"sky130_osu_sc_t15" : "OSU_T15_COMMIT",
+	"sky130_osu_sc_t18" : "OSU_T18_COMMIT"
     ],
     "iocells" : [
-        "sky130_fd_io"
+        "sky130_fd_io" : "FD_IO_COMMIT"
+    ]
+    "primitive" : [
+	"sky130_fd_pr" : "FD_PR_COMMIT"
+    ]
+    "memory" : [
+	"sky130_sram_macros" : "SRAM_COMMIT"
+    ]
+    "other" : [
+	"sky130_ml_xx_hd" : "ALPHA_COMMIT"
     ]
 }