From 834fa349bcafe0c8b29d7058a222fe146c534c91 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 19 Jun 2019 18:47:51 -0700 Subject: [PATCH] add feed_logic substitution generator --- configure/CONFIG_SITE | 2 + src/Db/Makefile | 3 + src/Db/feed_logic.py | 192 ++++++++++++++++++++++++++ src/Db/feed_logic_array_mask.template | 5 + src/Db/feed_logic_fanout.template | 9 ++ src/Db/feed_logic_read.template | 27 ++++ src/Db/feed_logic_signal.template | 88 ++++++++++++ src/Db/feed_logic_trigger.template | 108 +++++++++++++++ 8 files changed, 434 insertions(+) create mode 100755 src/Db/feed_logic.py create mode 100644 src/Db/feed_logic_array_mask.template create mode 100644 src/Db/feed_logic_fanout.template create mode 100644 src/Db/feed_logic_read.template create mode 100644 src/Db/feed_logic_signal.template create mode 100644 src/Db/feed_logic_trigger.template diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index 25630bd..d9c089e 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -37,6 +37,8 @@ CHECK_RELEASE = YES USR_CPPFLAGS += -DUSE_TYPED_RSET +PYTHON = python + # These allow developers to override the CONFIG_SITE variable # settings without having to modify the configure/CONFIG_SITE # file itself. diff --git a/src/Db/Makefile b/src/Db/Makefile index a6ef210..00cc80f 100644 --- a/src/Db/Makefile +++ b/src/Db/Makefile @@ -50,3 +50,6 @@ DB += cav.template include $(TOP)/configure/RULES #---------------------------------------- # ADD RULES AFTER THIS LINE + +%.substitutions: ../%.json ../feed_logic.py + $(PYTHON) ../feed_logic.py $< $@ diff --git a/src/Db/feed_logic.py b/src/Db/feed_logic.py new file mode 100755 index 0000000..f0a9cae --- /dev/null +++ b/src/Db/feed_logic.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +""" +FEED acquisition device logic substitution generator + +{ + "signal_group":{ + # required + "reset":{"name":"reg_reset","bit": 0} + ,"status":{"name":"reg_status","bit": 1 } + # optional + ,"readback":{ + "scalar1":{"name":"reg_name"} + ,"wf1":{ + "name":"reg_name1" + ,"max_size":8196, + ,"mask":"mask_reg" + ,"signals":[ + {"name":"CH1"} + ] + } + } + } +} +""" + +from __future__ import print_function + +import json, re, itertools +from collections import OrderedDict + +try: + from itertools import izip as zip +except ImportError: + pass + +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO + +def strip_comments(inp): + return re.sub(r'#.*$', '', inp, flags=re.MULTILINE) + +def getargs(): + from argparse import ArgumentParser + P = ArgumentParser() + P.add_argument('json', help='json config file') + P.add_argument('output', help='output .substitution file') + return P.parse_args() + +def batchby(it, cnt): + grp = [] + for item in it: + grp.append(item) + if len(grp)==cnt: + yield grp + grp = [] + if len(grp): + yield grp + +class Main(object): + def __init__(self, args): + with open(args.json, 'r') as F: + raw = F.read() + + cooked = strip_comments(raw) + + try: + conf = json.loads(cooked) + except: + print("Error parsing JSON") + print("======") + print(cooked) + raise + + # {"file.template": [('macro', 'value'), ...], ...} + self.out = OrderedDict([ + ('feed_logic_trigger.template', []), + ('feed_logic_read.template', []), + ('feed_logic_array_mask.template', []), + ('feed_logic_fanout.template', []), + ('feed_logic_signal.template', []), + ]) + + for gname, gconf in conf.items(): + #out.write('### Start Signal Group: %s\n#\n'%gname) + #for line in json.dumps(gconf, indent=' ').splitlines(): + # out.write('%s\n'%line) + + self.signal_group(gname, gconf) + + #out.write('\n### End Signal Group: %s\n'%name) + + fd = StringIO() + fd.write("# Generated from:\n") + for line in raw.splitlines(): + fd.write('# %s\n'%line) + fd.write("\n") + + for fname, lines in self.out.items(): + if not lines: + fd.write("\n# no %s\n"%fname) + continue + + fd.write(""" +file "%s" +{ +"""%fname) + + lines.reverse() + for ent in lines: + fd.write('{' + ', '.join(['%s="%s"'%(k,v) for k, v in ent.items()]) + '}\n') + + fd.write("}\n") + + with open(args.output, 'w') as F: + F.write(fd.getvalue()) + + def signal_group(self, gname, gconf): + # we append template blocks in reverse order to simplify accounting of next record. + # start with the last link in the chain, which then re-arms + nextrec = '$(PREF)%sREARM'%gname + + # de-mux of signals from array registers. + # these will be synchronously processed through a set of fanouts + fanout2 = [] + for rname, rconf in gconf.get('readback', {}).items(): + signals = rconf.get('signals', []) + mask = hex((1<