Added support for Paul Schulz's alphanumeric font character library
for magic, including a modification of the text2mag.py script for
use with the open_pdks installation.
diff --git a/VERSION b/VERSION
index 5ca0603..9d25b39 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.88
+1.0.89
diff --git a/sky130/Makefile.in b/sky130/Makefile.in
index 194b5e6..aab678b 100644
--- a/sky130/Makefile.in
+++ b/sky130/Makefile.in
@@ -46,6 +46,10 @@
# cloned from https://github.com/google/skywater-pdk. This
# option is mandatory and has no default.
#
+#
+# NOTE: The comments below are for features that have not yet been
+# implemented.
+#
# Enable/disable for specific libraries to be installed (and downloaded if
# needed). Libraries that are part of the open_pdks repository are enabled
# by default and must be disabled by passing an option to configure. Libraries
@@ -85,11 +89,9 @@
# repository and installed.
#
# --enable-alpha-lib[=<path>]
-# If enabled, install the alphanumeric library. If <path> is
-# specified, then the alphanumeric library is expected to be
-# found rooted at the given path. If not specified, then the
-# alphanumeric library will be cloned from the git repository
-# and installed.
+# If enabled, install the sky130_ml_xx_hd font library from
+# Paul Schulz on github. If not specified, then the font
+# library will be cloned from the git repository and installed.
#
# --enable-xschem[=<path>]
# If enabled, install the Sky130 setup for the xschem schematic
@@ -169,6 +171,9 @@
# Path to OSU standard cell library sources (to be added to configuration options).
OSU_PATH = ~/gits/osu_130_pdk
+# Path to independent library sources (to be added to configuration options).
+REPO_PATH = ~/gits
+
# NOTE: Install destination is the git repository of the technology platform.
# Once updated in git, the git project can be distributed to all hosts.
#
@@ -506,6 +511,14 @@
${RM} ${STAGING_PATH}/${SKY130A}/libs.ref/sky130_fd_sc_ms/verilog/*.*.v
${RM} ${STAGING_PATH}/${SKY130A}/libs.ref/sky130_fd_sc_ls/verilog/*.*.v
${RM} ${STAGING_PATH}/${SKY130A}/libs.ref/sky130_fd_sc_lp/verilog/*.*.v
+ # Install alphanumeric library.
+ ${STAGE} -source ${REPO_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -mag %l/mag/*.mag \
+ -library general sky130_ml_xx_hd |& tee -a ${SKY130A}_install.log
+ # Install text2mag.py script for alphanumeric library
+ mkdir -p ${STAGING_PATH}/${SKY130A}/libs.ref/sky130_ml_xx_hd/scripts
+ cp custom/scripts/text2mag.py \
+ ${STAGING_PATH}/${SKY130A}/libs.ref/sky130_ml_xx_hd/scripts
# Install OSU digital standard cells.
${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
-techlef %l/latest/lef/sky130_osu_sc.tlef rename=sky130_osu_sc_t18.tlef \
diff --git a/sky130/custom/scripts/text2mag.py b/sky130/custom/scripts/text2mag.py
new file mode 100755
index 0000000..8d62db3
--- /dev/null
+++ b/sky130/custom/scripts/text2mag.py
@@ -0,0 +1,143 @@
+#!/bin/env python3
+
+# text2mag.py
+#
+# Read a text file from standard input and write out the text as an
+# array of magic cells using the sky130_ml_xx_hd library.
+#
+# Adapted from the script by Paul Schulz <paul@mawsonlakes.org> in
+# the sky130_ml_xx_hd repository. Modified for open_pdks standard
+# paths, and to take the text string as an argument in addition to
+# stdin.
+
+import getopt
+import sys
+import os
+import subprocess
+
+
+# Options
+options, remainder = getopt.getopt(sys.argv[1:],
+ 'c:p:m:kh',
+ ['cellname',
+ 'pdk',
+ 'message',
+ 'keep',
+ 'help',
+ ])
+
+def usage(ofile):
+ print('text2mag.py <options>', file=ofile)
+ print('', file=ofile)
+ print(' Options:', file=ofile)
+ print(' [-c|--cellname] - Required. Cell name to use.', file=ofile)
+ print(' [-m|--message] - Text to convert (default: use stdin).', file=ofile)
+ print(' [-k|--keep] - Keep generator script', file=ofile)
+ print(' [-h|--help] - Display these details', file=ofile)
+
+keep = False
+message = None
+cellname = None
+for opt, arg in options:
+ if opt in ('-c', '--cellname'):
+ cellname = arg
+ elif opt in ('-m', '--message'):
+ message = arg
+ elif opt in ('-k', '--keep'):
+ keep = True
+ elif opt in ('-h', '--help'):
+ usage(sys.stdout)
+ sys.exit(0)
+ else:
+ usage(sys.stderr)
+ sys.exit(1)
+
+if not cellname:
+ usage(sys.stderr)
+ print('', file=sys.stderr)
+ print('*** cellname required', file=sys.stderr)
+ sys.exit(1)
+
+# Convert character ID to cellname
+# Accepts character UTF-8 encodings
+
+def get_cellname (ch):
+ """Return name of cell used to store character data"""
+
+ prefix = 'font_'
+
+ if (ord(ch) < 0x100):
+ cellname = '{:02X}'.format(ord(ch))
+ elif (ord(ch) < 0x10000):
+ cellname = '{:04X}'.format(ord(ch))
+ elif (ord(ch) < 0x1000000):
+ cellname = '{:06X}'.format(ord(ch))
+ else:
+ cellname = '{:X}'.format(ord(ch))
+
+ return prefix + cellname
+
+def write_text_generator(message, ofile):
+ x = 0
+ y = 0
+ baselineskip = 400
+
+ print('drc off', file=ofile)
+ print('snap int', file=ofile)
+ print('select top cell', file=ofile)
+ print('box position 0 0', file=ofile)
+ print('', file=ofile)
+
+ # NOTE: When a character is not found, substitute "?"
+
+ for char in message:
+ if char != '\n':
+ filename = get_cellname(char)
+ print('if {[catch {getcell ' + filename + ' child 0 0}]} {', file=ofile)
+ print(' getcell font_3F child 0 0', file=ofile)
+ print('}', file=ofile)
+ print('pushstack', file=ofile)
+ print('set bbox [property FIXED_BBOX]', file=ofile)
+ print('set width [expr {[lindex $bbox 2] - [lindex $bbox 0]}]', file=ofile)
+ print('popstack', file=ofile)
+ print('box move e $width', file=ofile)
+ else:
+ x = 0
+ y = y - baselineskip
+ print('box position {} {}'.format(x,y), file=ofile)
+
+ print('save ' + cellname, file=ofile)
+ print('quit -noprompt', file=ofile)
+
+##############################################################################
+# Take message from stdin if not specified on the command line.
+
+if not message:
+ for line in sys.stdin:
+ message = message + line
+
+with open('gen_message.tcl', 'w') as ofile:
+ write_text_generator(message, ofile)
+
+ # Run magic with the text generator script as input.
+ # NOTE: Assumes that a .magicrc file exists at the target and that
+ # it already includes the library in the search path.
+
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole', 'gen_message.tcl'],
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, universal_newlines = True)
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+
+# Delete the text generator script
+if not keep:
+ os.remove('gen_message.tcl')
+
+sys.exit(mproc.returncode)
diff --git a/sky130/magic/sky130.magicrc b/sky130/magic/sky130.magicrc
index 601e378..c0828aa 100644
--- a/sky130/magic/sky130.magicrc
+++ b/sky130/magic/sky130.magicrc
@@ -61,6 +61,7 @@
addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_ms
addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_osu_sc
addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_osu_sc_t18
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_ml_xx_hd
} else {
addpath ${PDKPATH}/libs.ref/sky130_fd_pr/${MAGTYPE}
addpath ${PDKPATH}/libs.ref/sky130_fd_io/${MAGTYPE}
@@ -73,6 +74,7 @@
addpath ${PDKPATH}/libs.ref/sky130_fd_sc_ms/${MAGTYPE}
addpath ${PDKPATH}/libs.ref/sky130_osu_sc/${MAGTYPE}
addpath ${PDKPATH}/libs.ref/sky130_osu_sc_t18/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_ml_xx_hd/${MAGTYPE}
}
# add path to GDS cells
@@ -89,6 +91,7 @@
path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_ms
path cell +${PDKPATH}/libs.ref/gds/sky130_osu130
path cell +${PDKPATH}/libs.ref/gds/sky130_osu130_t18
+ path cell +${PDKPATH}/libs.ref/gds/sky130_ml_xx_hd
} else {
path cell ${PDKPATH}/libs.ref/sky130_fd_pr/gds
path cell +${PDKPATH}/libs.ref/sky130_fd_io/gds
@@ -101,6 +104,7 @@
path cell +${PDKPATH}/libs.ref/sky130_fd_sc_ms/gds
path cell +${PDKPATH}/libs.ref/sky130_osu130/gds
path cell +${PDKPATH}/libs.ref/sky130_osu130_t18/gds
+ path cell +${PDKPATH}/libs.ref/sky130_ml_xx_hd/gds
}
#endif (FULLTECH)