blob: 8d62db33f502331666d13f5fff1ac08501b11f02 [file] [log] [blame]
Tim Edwardsbcf59aa2020-12-17 16:55:13 -05001#!/bin/env python3
2
3# text2mag.py
4#
5# Read a text file from standard input and write out the text as an
6# array of magic cells using the sky130_ml_xx_hd library.
7#
8# Adapted from the script by Paul Schulz <paul@mawsonlakes.org> in
9# the sky130_ml_xx_hd repository. Modified for open_pdks standard
10# paths, and to take the text string as an argument in addition to
11# stdin.
12
13import getopt
14import sys
15import os
16import subprocess
17
18
19# Options
20options, remainder = getopt.getopt(sys.argv[1:],
21 'c:p:m:kh',
22 ['cellname',
23 'pdk',
24 'message',
25 'keep',
26 'help',
27 ])
28
29def usage(ofile):
30 print('text2mag.py <options>', file=ofile)
31 print('', file=ofile)
32 print(' Options:', file=ofile)
33 print(' [-c|--cellname] - Required. Cell name to use.', file=ofile)
34 print(' [-m|--message] - Text to convert (default: use stdin).', file=ofile)
35 print(' [-k|--keep] - Keep generator script', file=ofile)
36 print(' [-h|--help] - Display these details', file=ofile)
37
38keep = False
39message = None
40cellname = None
41for opt, arg in options:
42 if opt in ('-c', '--cellname'):
43 cellname = arg
44 elif opt in ('-m', '--message'):
45 message = arg
46 elif opt in ('-k', '--keep'):
47 keep = True
48 elif opt in ('-h', '--help'):
49 usage(sys.stdout)
50 sys.exit(0)
51 else:
52 usage(sys.stderr)
53 sys.exit(1)
54
55if not cellname:
56 usage(sys.stderr)
57 print('', file=sys.stderr)
58 print('*** cellname required', file=sys.stderr)
59 sys.exit(1)
60
61# Convert character ID to cellname
62# Accepts character UTF-8 encodings
63
64def get_cellname (ch):
65 """Return name of cell used to store character data"""
66
67 prefix = 'font_'
68
69 if (ord(ch) < 0x100):
70 cellname = '{:02X}'.format(ord(ch))
71 elif (ord(ch) < 0x10000):
72 cellname = '{:04X}'.format(ord(ch))
73 elif (ord(ch) < 0x1000000):
74 cellname = '{:06X}'.format(ord(ch))
75 else:
76 cellname = '{:X}'.format(ord(ch))
77
78 return prefix + cellname
79
80def write_text_generator(message, ofile):
81 x = 0
82 y = 0
83 baselineskip = 400
84
85 print('drc off', file=ofile)
86 print('snap int', file=ofile)
87 print('select top cell', file=ofile)
88 print('box position 0 0', file=ofile)
89 print('', file=ofile)
90
91 # NOTE: When a character is not found, substitute "?"
92
93 for char in message:
94 if char != '\n':
95 filename = get_cellname(char)
96 print('if {[catch {getcell ' + filename + ' child 0 0}]} {', file=ofile)
97 print(' getcell font_3F child 0 0', file=ofile)
98 print('}', file=ofile)
99 print('pushstack', file=ofile)
100 print('set bbox [property FIXED_BBOX]', file=ofile)
101 print('set width [expr {[lindex $bbox 2] - [lindex $bbox 0]}]', file=ofile)
102 print('popstack', file=ofile)
103 print('box move e $width', file=ofile)
104 else:
105 x = 0
106 y = y - baselineskip
107 print('box position {} {}'.format(x,y), file=ofile)
108
109 print('save ' + cellname, file=ofile)
110 print('quit -noprompt', file=ofile)
111
112##############################################################################
113# Take message from stdin if not specified on the command line.
114
115if not message:
116 for line in sys.stdin:
117 message = message + line
118
119with open('gen_message.tcl', 'w') as ofile:
120 write_text_generator(message, ofile)
121
122 # Run magic with the text generator script as input.
123 # NOTE: Assumes that a .magicrc file exists at the target and that
124 # it already includes the library in the search path.
125
126 mproc = subprocess.run(['magic', '-dnull', '-noconsole', 'gen_message.tcl'],
127 stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
128 stderr = subprocess.PIPE, universal_newlines = True)
129 if mproc.stdout:
130 for line in mproc.stdout.splitlines():
131 print(line)
132 if mproc.stderr:
133 print('Error message output from magic:')
134 for line in mproc.stderr.splitlines():
135 print(line)
136 if mproc.returncode != 0:
137 print('ERROR: Magic exited with status ' + str(mproc.returncode))
138
139# Delete the text generator script
140if not keep:
141 os.remove('gen_message.tcl')
142
143sys.exit(mproc.returncode)