+from soc.config.pinouts import get_pinspecs
+from soc.debug.jtag import Pins
+from c4m.nmigen.jtag.tap import IOType
+
+from libresoc.ls180 import io
+from litex.build.generic_platform import ConstraintManager
+
+
+CPU_VARIANTS = ["standard", "standard32", "standardjtag", "ls180"]
+
+
+def make_wb_bus(prefix, obj, simple=False):
+ res = {}
+ outpins = ['stb', 'cyc', 'we', 'adr', 'dat_w', 'sel']
+ if not simple:
+ outpins += ['cti', 'bte']
+ for o in outpins:
+ res['o_%s__%s' % (prefix, o)] = getattr(obj, o)
+ for i in ['ack', 'err', 'dat_r']:
+ res['i_%s__%s' % (prefix, i)] = getattr(obj, i)
+ return res
+
+def make_wb_slave(prefix, obj):
+ res = {}
+ for i in ['stb', 'cyc', 'cti', 'bte', 'we', 'adr', 'dat_w', 'sel']:
+ res['i_%s__%s' % (prefix, i)] = getattr(obj, i)
+ for o in ['ack', 'err', 'dat_r']:
+ res['o_%s__%s' % (prefix, o)] = getattr(obj, o)
+ return res
+
+def make_pad(res, dirn, name, suffix, cpup, iop):
+ cpud, iod = ('i', 'o') if dirn else ('o', 'i')
+ res['%s_%s__core__%s' % (cpud, name, suffix)] = cpup
+ res['%s_%s__pad__%s' % (iod, name, suffix)] = iop
+
+def get_field(rec, name):
+ for f in rec.layout:
+ f = f[0]
+ if f.endswith(name):
+ return getattr(rec, f)
+
+
+def make_jtag_ioconn(res, pin, cpupads, iopads):
+ (fn, pin, iotype, pin_name, scan_idx) = pin
+ #serial_tx__core__o, serial_rx__pad__i,
+ # special-case sdram_clock
+ if pin == 'clock' and fn == 'sdr':
+ cpu = cpupads['sdram_clock']
+ io = iopads['sdram_clock']
+ else:
+ cpu = cpupads[fn]
+ io = iopads[fn]
+ print ("cpupads", cpupads)
+ print ("iopads", iopads)
+ print ("pin", fn, pin, iotype, pin_name)
+ print ("cpu fn", cpu)
+ print ("io fn", io)
+ name = "%s_%s" % (fn, pin)
+ print ("name", name)
+ sigs = []
+
+ if iotype in (IOType.In, IOType.Out):
+ ps = pin.split("_")
+ if pin == 'clock' and fn == 'sdr':
+ cpup = cpu
+ iop = io
+ elif len(ps) == 2 and ps[-1].isdigit():
+ pin, idx = ps
+ idx = int(idx)
+ cpup = getattr(cpu, pin)[idx]
+ iop = getattr(io, pin)[idx]
+ elif pin.isdigit():
+ idx = int(pin)
+ cpup = cpu[idx]
+ iop = io[idx]
+ else:
+ cpup = getattr(cpu, pin)
+ iop = getattr(io, pin)
+
+ if iotype == IOType.Out:
+ # output from the pad is routed through C4M JTAG and so
+ # is an *INPUT* into core. ls180soc connects this to "real" peripheral
+ make_pad(res, True, name, "o", cpup, iop)
+
+ elif iotype == IOType.In:
+ # input to the pad is routed through C4M JTAG and so
+ # is an *OUTPUT* into core. ls180soc connects this to "real" peripheral
+ make_pad(res, False, name, "i", cpup, iop)
+
+ elif iotype == IOType.InTriOut:
+ if fn == 'gpio': # sigh decode GPIO special-case
+ idx = int(pin[1:])
+ else:
+ idx = 0
+ cpup, iop = get_field(cpu, "i")[idx], get_field(io, "i")[idx]
+ make_pad(res, False, name, "i", cpup, iop)
+ cpup, iop = get_field(cpu, "o")[idx], get_field(io, "o")[idx]
+ make_pad(res, True, name, "o", cpup, iop)
+ cpup, iop = get_field(cpu, "oe")[idx], get_field(io, "oe")[idx]
+ make_pad(res, True, name, "oe", cpup, iop)
+
+ if iotype in (IOType.In, IOType.InTriOut):
+ sigs.append(("i", 1))
+ if iotype in (IOType.Out, IOType.TriOut, IOType.InTriOut):
+ sigs.append(("o", 1))
+ if iotype in (IOType.TriOut, IOType.InTriOut):
+ sigs.append(("oe", 1))