From: Jean-Paul Chaput Date: Wed, 27 Jan 2021 13:02:55 +0000 (+0100) Subject: Pinmux loading is now integrated in Coriolis. X-Git-Tag: LS180_RC3~195 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a8f8c0a6894e142ffbf4f1f64dfd85afcd839241;p=soclayout.git Pinmux loading is now integrated in Coriolis. --- diff --git a/experiments9/doDesign.py b/experiments9/doDesign.py index db4f3c7..890564d 100644 --- a/experiments9/doDesign.py +++ b/experiments9/doDesign.py @@ -1,152 +1,44 @@ + from __future__ import print_function import os import json -from pprint import pprint import sys import traceback import CRL import helpers -from helpers.io import ErrorMessage -from helpers.io import WarningMessage -from helpers import trace -from helpers import l, u, n +from helpers.io import ErrorMessage, WarningMessage +from helpers import trace, l, u, n import plugins from Hurricane import DbU -if True: # change this to False to get errors to "go away" so that - # print / debug statements in generation of spec can be seen - # without the hard dependence of having to run via "cgt" - from plugins.alpha.block.configuration import IoPin - from plugins.alpha.block.block import Block - from plugins.alpha.block.configuration import GaugeConf - from plugins.alpha.core2chip.niolib import CoreToChip - from plugins.alpha.chip.configuration import ChipConf - from plugins.alpha.chip.chip import Chip - - -af = CRL.AllianceFramework.get() - -# converts unicode strings to utf-8 because coriolis2 python code is expecting -# str not unicode -def _byteify(data, ignore_dicts = False): - # if this is a unicode string, return its string representation - if isinstance(data, unicode): - return data.encode('utf-8') - # if this is a list of values, return list of byteified values - if isinstance(data, list): - return [ _byteify(item, ignore_dicts=True) for item in data ] - # if this is a dictionary, return dictionary of byteified keys and values - # but only if we haven't already byteified it - if isinstance(data, dict) and not ignore_dicts: - return dict((_byteify(key, ignore_dicts=True), - _byteify(value, ignore_dicts=True)) - for key, value in data.iteritems()) - # if it's anything else, return it in its original form - return data - -# load JSON-formatted pad info from pinmux -pth = os.path.abspath(__file__) -pth = os.path.split(pth)[0] -print ("path", pth) -with open("%s/ls180/litex_pinpads.json" % pth) as f: - txt = f.read() -chip = json.loads(txt, object_hook=_byteify) -chip = _byteify(chip, ignore_dicts=True) -print (chip) - -chip.update({ 'pads.ioPadGauge' : 'niolib', - # core option (big, time-consuming) - #'core.size' : (l(28000), l(28000)), - #'chip.size' : (l(30200), l(30200)), - # no-core option (test_issuer but no actual core) - 'core.size' : (l(13000), l(13000)), - 'chip.size' : (l(14400), l(14400)), - 'pads.useCoreSize': True, - 'chip.clockTree' : True, - }) - -# this function is the equivalent of statically-declared io pad specs. -# it is not ok to have io declared manually, duplicated in (literally) 5 -# different places, too many mistakes can be made and changes are a -# nightmare. -# -# therefore the pinmux code takes responsibility for declaring the pinouts, -# generates a JSON file which is read (above) and *creates* the list from -# that auto-generated file. the core, litex peripheral code, *and* the C4M -# JTAG Boundary Scan code do *EXACTLY* the same thing and in this way they -# all "match". -# -# here we do some weirdness to convert from the ioring.py pads list format over -# to the new niolib format. - -def generate_spec(): - # convert old ioring format to ioPadsSpec - ioPadsSpec = [] - sd = {'pads.east': IoPin.EAST, - 'pads.west': IoPin.WEST, - 'pads.south': IoPin.SOUTH, - 'pads.north': IoPin.NORTH, - } - # create lookup dict for resolving pads.instances "side" (NSEW) - sides = {} - for side in ['pads.east', 'pads.west', 'pads.south', 'pads.north']: - io_pin_spec = sd[side] - #if side not in sides: - # sides[side] = {} - for pinname in chip[side]: - sides[pinname] = io_pin_spec - - # now go through pads.instances - pprint (sides) - for pad in chip['pads.instances']: - padname = pad[0] - padside = sides[padname] - print ("padside", padname, padside) - - # format here is ['padname', 'to core', 'from core', 'direction'] - # where direction is "+" for out, "-" for in, "*" for bi-directionaly - if len(pad) == 4: - print("4-long io", pad) - padspec = [padside, None, padname, pad[1], pad[2]] - - # format here is: - # ['padname', 'something', 'to core', 'from core', 'en', 'direction'] - elif len(pad) == 6: - print("6-long io", pad) - padspec = [padside, None, padname] + pad[1:5] - - # format here is power/gnd (io)vss/vdd - elif len(pad) == 2: - print("2-long io", pad) - padspec = [padside, None] + pad - else: - print("? long io", pad) - assert False - print ("padspec", padspec) - ioPadsSpec.append(tuple(padspec)) - - return ioPadsSpec +from plugins.alpha.block.configuration import IoPin, GaugeConf +from plugins.alpha.block.iospecs import IoSpecs +from plugins.alpha.block.block import Block +from plugins.alpha.core2chip.niolib import CoreToChip +from plugins.alpha.chip.configuration import ChipConf +from plugins.alpha.chip.chip import Chip -ioPadsSpec = generate_spec() +af = CRL.AllianceFramework.get() def scriptMain (**kw): """The mandatory function to be called by Coriolis CGT/Unicorn.""" global af rvalue = True - sz = 26000 # core size + coreSize = 26000 + cwd = os.path.split( os.path.abspath(__file__) )[0] + ioSpecs = IoSpecs() + ioSpecs.loadFromPinmux( '{}/ls180/litex_pinpads.json'.format(cwd) ) try: - helpers.setTraceLevel(550) - usePadsPosition = True - buildChip = True - cell, editor = plugins.kwParseMain(**kw) - cell = af.getCell('ls180', CRL.Catalog.State.Logical) + #helpers.setTraceLevel( 550 ) + cell, editor = plugins.kwParseMain( **kw ) + cell = af.getCell( 'ls180', CRL.Catalog.State.Logical ) if cell is None: - print(ErrorMessage(2, 'doDesign.scriptMain(): Unable to load ' - 'cell "{}".'.format('ls180'))) + print( ErrorMessage( 2, 'doDesign.scriptMain(): Unable to load cell "{}".' \ + .format('ls180') )) sys.exit(1) - if editor: editor.setCell(cell) - ls180Conf = ChipConf(cell, ioPads=ioPadsSpec) + if editor: editor.setCell( cell ) + ls180Conf = ChipConf( cell, ioPads=ioSpecs.ioPadsSpec ) ls180Conf.cfg.etesian.bloat = 'nsxlib' ls180Conf.cfg.etesian.uniformDensity = True ls180Conf.cfg.etesian.aspectRatio = 1.0 @@ -160,11 +52,11 @@ def scriptMain (**kw): ls180Conf.bRows = 2 ls180Conf.chipConf.name = 'chip' ls180Conf.chipConf.ioPadGauge = 'niolib' - ls180Conf.coreSize = (l(sz), l(sz)) - ls180Conf.chipSize = (l(sz+3360), l(sz+3360)) - ls180ToChip = CoreToChip(ls180Conf) + ls180Conf.coreSize = (l(coreSize ), l(coreSize )) + ls180Conf.chipSize = (l(coreSize+3360), l(coreSize+3360)) + ls180ToChip = CoreToChip( ls180Conf ) ls180ToChip.buildChip() - chipBuilder = Chip(ls180Conf) + chipBuilder = Chip( ls180Conf ) rvalue = chipBuilder.doPnR() chipBuilder.save() except Exception, e: