blob: 6bb61a23f4c3c0279f0ceeb79cdcd836791545f4 [file] [log] [blame]
#!/usr/bin/env python3
import pprint
from collections import defaultdict
REPLACEMENTS = {
#'NOTIFIER': 'NOTIFY',
'NOTI_REG': 'NOTIFIER_REG',
'NFR': 'NOTIFIER',
'ntfy': 'NOTIFIER',
'R': 'RESET',
'S': 'SET',
'SB': 'SET_ASYNC',
'DE': 'DATA_ENABLE',
'KAPWR': 'VKAPWR',
'LVPWR': 'VLPWR',
}
YOSYS_ARGS = {
'RESET': 'R',
'CLK_N': 'C',
'CLK_P': 'C',
'G': 'E',
'Q': 'Q',
}
# DFF_{C:N|P}_ (D, C, Q);
# DFFE_{C:N|P}{E:N|P}_ (D, C, E, Q);
# DFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q);
# DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q);
# DLATCH_{E:N|P}_ (E, D, Q);
# DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q);
def pp(args):
args = list(args)
pp = []
po = []
for a in reversed(list(sorted(args))):
if a.startswith('V'):
args.remove(a)
pp.append(a[1])
elif a == 'NOTIFIER':
args.remove(a)
po.append('N')
elif a == 'NOTIFIER_REG':
args.remove(a)
po.append('N')
elif a == 'SLEEP':
args.remove(a)
po.append('S')
elif a == 'SLEEPB':
args.remove(a)
po.append('s')
a = []
if pp:
a.append(''.join(pp))
if po:
a.append(''.join(po))
if a:
a.insert(0, 'pp')
return '$'.join(a), args
RESET_SET_NAME = {
# Reset, Set
(None, None ): None,
('RESET', None ): 'R' ,
('RESET', 'SET_DOM' ): 'SR',
('RESET_DOM', 'SET' ): 'RS',
('RESET_DOM', None ): 'R' ,
(None, 'SET_DOM' ): 'S' ,
(None, 'SET' ): 'S' ,
(None, 'SET_ASYNC'): 'Sa',
}
def n(args):
args = list(args)
n = []
if 'CLK_P' in args:
args.remove('CLK_P')
n.append('P')
if 'CLK_N' in args:
args.remove('CLK_N')
n.append('N')
if 'GATE_P' in args:
args.remove('GATE_P')
n.append('P')
if 'GATE_N' in args:
args.remove('GATE_N')
n.append('N')
if 'DATA_ENABLE' in args:
args.remove('DATA_ENABLE')
n.append('E')
if "LOW_POWER" in args:
args.remove('LOW_POWER')
n.insert(0, 'l')
if "UDB" in args:
args.remove('UDB')
n.insert(0, 'u')
reset_set = [None, None]
if args and args[0].startswith('RESET'):
reset_set[0] = args.pop(0)
if args and args[0].startswith('SET'):
reset_set[1] = args.pop(0)
reset_set = tuple(reset_set)
n.append(RESET_SET_NAME[reset_set])
if not n[-1]:
n.pop(-1)
return "".join(n), args
outmap = defaultdict(lambda: list())
outargs = {}
routmap = {}
for i, l in enumerate(open('primitive_map.csv')):
name, args = l.strip().split(' ', 1)
assert args[0] == '(', (i, l, name, args)
assert args[-2:] == ');', (i, l, name, args)
args = args[1:-2].split(', ')
oargs = []
for a in args:
if a in REPLACEMENTS and 'MUX' not in name:
oargs.append(REPLACEMENTS[a])
else:
oargs.append(a)
args = list(oargs)
ppa = None
ppn = None
new_name = None
to_remove = []
if 'lpflow' in name:
args.append('LOW_POWER')
if 'udb' in name:
args.append('UDB')
if 'DF' in name:
new_name = 'dff'
to_remove = ['Q', 'D']
elif 'ISOLATCH' in name:
new_name = 'isolatch'
to_remove = ['Q', 'D']
elif 'isosrchv' in name:
new_name = 'isolatchhv'
to_remove = ['UDP_OUT', 'UDP_IN']
elif 'DL' in name:
new_name = 'dlatch'
to_remove = ['Q', 'D']
elif 'MUX' in name:
new_name = 'mux'
args = []
bits = name.split('MUX_', 1)[1].split('_')
from_n = int(bits.pop(0))
to_n = int(bits.pop(0))
assert to_n in (1, 2), to_n
args.append('%ito%i'%(from_n, to_n))
# FIXME: Hack for scs8ls_udb_pg_U_MUX_2_1_SEL_X
while len(bits) > 0 and (bits[0] == 'SEL' or bits[0] == 'X'):
bits.pop(0)
if bits:
assert bits[0] == 'INV', (bits[0], i, l)
args.append(bits.pop(0))
else:
new_name = 'pwrgood'
to_remove = ['UDP_OUT', 'UDP_IN']
for j in to_remove:
assert j in args, (j, i, l, name, args)
args.remove(j)
if 'SETDOM' in name:
assert args[0] == 'SET', (i, l, name, args)
args[0] = 'SET_DOM'
else:
for j, v in enumerate(args):
if v == 'RESET':
args[j] = 'RESET_DOM'
if 'DL_N' in name:
assert 'G' in args, (i, l, name, args)
args[args.index('G')] = 'GATE_N'
if 'DL_P' in name:
assert 'G' in args, (i, l, name, args)
args[args.index('G')] = 'GATE_P'
if 'DF_N' in name:
assert 'CK' in args, (i, l, name, args)
args[args.index('CK')] = 'CLK_N'
if 'DFB' in name:
assert 'CK' in args, (i, l, name, args)
args[args.index('CK')] = 'CLK_N'
if 'DF_P' in name:
assert 'CP' in args, (i, l, name, args)
args[args.index('CP')] = 'CLK_P'
args.sort()
if 'MUX' not in name:
ppa, remains = pp(args)
ppn, remains = n(remains)
else:
ppa = args.pop(0)
if 'SEL_X' in l:
ppn = 'x'
if args:
assert args.pop(0) == 'INV'
ppa += '_N'
remains = []
assert not remains, (name, remains, oargs)
fullname = 'udp_'+new_name
if ppn:
fullname += '$'+ppn
if ppa:
fullname += '_'+ppa
outmap[fullname].append(name)
assert name not in routmap
routmap[name] = fullname
if fullname not in outargs:
outargs[fullname] = tuple(oargs)
else:
assert outargs[fullname] == tuple(oargs), (fullname, outargs[fullname], oargs)
outmap = dict(outmap)
if __name__ == "__main__":
maxlenk = max(len(s) for s in routmap)
maxlenv = max(len(s) for s in routmap.values())
for k, v in routmap.items():
print(k.ljust(maxlenk), v.ljust(maxlenv), outargs[v])