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)