Beispiel #1
0
def log_to_vcd(cfg):
    """
    Cyclically poll heating and log results to VCD file.
    """
    global SIGINT

    # set up VCD logging
    now_utc = datetime.datetime.now(datetime.timezone.utc)
    vcdwriter = VCDWriter(open('vitopy1.vcd', 'w'),
                          timescale='1s',
                          init_timestamp=now_utc.timestamp())
    vcdvars = {}
    for v in config['datapoints']:
        if not 'addr' in v:
            continue
        if not 'id' in v:
            v['id'] = 'NOID'
        if type(v['addr']) is str:
            v['addr'] = int(v['addr'], 0)  # parse non-decimal numbers
        name = '%s_%s' % (v['id'], v['addr'])
        if 'uint8' == v['type']:
            logging.info('Adding variable %s' % v['addr'])
            vcdvars.update({
                v['addr']:
                vcdwriter.register_var('vitopy', name, 'integer', size=8)
            })
        if 'int8' == v['type']:
            logging.info('Adding variable %s' % v['addr'])
            vcdvars.update({
                v['addr']:
                vcdwriter.register_var('vitopy', name, 'integer', size=8)
            })
        if 'uint16' == v['type']:
            logging.info('Adding variable %s' % v['addr'])
            vcdvars.update({
                v['addr']:
                vcdwriter.register_var('vitopy', name, 'integer', size=16)
            })
        if 'uint32' == v['type']:
            logging.info('Adding variable %s' % v['addr'])
            vcdvars.update({
                v['addr']:
                vcdwriter.register_var('vitopy', name, 'integer', size=32)
            })

    # poll heating
    o = optolink.OptoLink()
    o.open_port(args.port)
    o.init()
    while True:
        logging.info('-- start of query --')
        now_utc = datetime.datetime.now(datetime.timezone.utc)
        allreadings = retrieve_all_readings_as_per_configuration(o, config)
        print(allreadings)

        for k in allreadings.keys():
            r = allreadings[k]
            if k in vcdvars:
                vcdwriter.change(vcdvars[k], now_utc.timestamp(), r)
                if args.publishmqtt:
                    mqttc.publish(str(k), r)

        vcdwriter.flush()

        for i in range(10):
            time.sleep(1)
            if SIGINT:
                break
        if SIGINT:
            break
        logging.info('-- end of query --')

    o.deinit()
    o.close_port()
    vcdwriter.close()

    return
Beispiel #2
0
                _name = _bName + "." + _bID

                if _I == 0:
                    # _c = COLS.setdefault(_bName, {})
                    # _v = _c.setdefault(_bID, [0])
                    # _v[0] +=1
                    # dump.writerow(["TS", "BUS", "BUS_DESC", "ID", "ID_DESC", "VAL"])
                    dump.writerow({_k:_v for _k,_v in r.iteritems() if _k in dump.fieldnames})
                    _fo.flush()

                    _l = BUSES.setdefault(_name, [])
                    if not _l:
                        trace.set_scope_type(r['busID'], 'module')
                        _l.append(trace.register_var(r['busID'], _name,'reg', (8, ) * r['dlc'], (0, ) * r['dlc']))

                elif _I == 1:
                    _val = r['data']

                    _dd = [_l[0], _ts, _val[:]]

                    try:
                        trace.change(*_dd)
                    except:
                        print(_dd)
                    trace.flush(_dd[1])
                else:
                    assert False

if trace:
    trace.close()
Beispiel #3
0
class VCD(SimExtend):
    @inject
    def __init__(self,
                 trace_fn='pygears.vcd',
                 include=Inject('debug/trace'),
                 tlm=False,
                 shmidcat=Inject('sim_extens/vcd/shmidcat'),
                 vcd_fifo=Inject('sim_extens/vcd/vcd_fifo'),
                 sim=Inject('sim/simulator'),
                 outdir=Inject('results-dir')):

        super().__init__()
        self.sim = sim
        self.finished = False
        self.vcd_fifo = vcd_fifo
        self.shmidcat = shmidcat
        self.outdir = outdir
        self.trace_fn = None
        self.shmid_proc = None

        vcd_visitor = VCDHierVisitor(include, tlm)
        vcd_visitor.visit(find('/'))

        if not vcd_visitor.vcd_vars:
            self.deactivate()
            return

        self.trace_fn = os.path.abspath(os.path.join(self.outdir, trace_fn))
        atexit.register(self.finish)

        try:
            subprocess.call(f"rm -f {self.trace_fn}", shell=True)
        except OSError:
            pass

        if self.vcd_fifo:
            subprocess.call(f"mkfifo {self.trace_fn}", shell=True)
        else:
            log.info(f'Main VCD dump to "{self.trace_fn}"')

        if self.shmidcat:
            self.shmid_proc = subprocess.Popen(f'shmidcat {self.trace_fn}',
                                               shell=True,
                                               stdout=subprocess.PIPE)

            # Wait for shmidcat to actually open the pipe, which is necessary
            # to happen prior to init of the verilator. If shmidcat does not
            # open the pipe, verilator will get stuck
            import time
            time.sleep(0.1)

        self.vcd_file = open(self.trace_fn, 'w')

        if self.shmidcat:
            self.shmid = self.shmid_proc.stdout.readline().decode().strip()
            log.info(f'Main VCD dump to shared memory at 0x{self.shmid}')

        self.writer = VCDWriter(self.vcd_file, timescale='1 ns', date='today')

        reg['VCDWriter'] = self.writer
        reg['VCD'] = self

        self.clk_var = self.writer.register_var('', 'clk', 'wire', size=1, init=1)

        self.timestep_var = self.writer.register_var('', 'timestep', 'integer', init=0)

        self.handhake = set()

        self.vcd_vars = {
            p: register_traces_for_intf(p.dtype, scope, self.writer)
            for p, scope in vcd_visitor.vcd_vars.items()
        }

        self.writer.flush()

    def before_run(self, sim):
        vcd_intf_vars = {}
        for p, v in self.vcd_vars.items():
            intf = p.consumer
            intf.events['put'].append(self.intf_put)
            intf.events['ack'].append(self.intf_ack)
            vcd_intf_vars[intf] = v

        self.vcd_vars = vcd_intf_vars

    def intf_put(self, intf, val):
        if intf not in self.vcd_vars:
            return True

        v = self.vcd_vars[intf]

        if typeof(intf.dtype, TLM):
            self.writer.change(v['data'], timestep() * 10, str(val))
        else:
            visitor = VCDValVisitor(v, self.writer, timestep() * 10)
            visitor.visit(intf.dtype, 'data', val=val)

        self.writer.change(v['valid'], timestep() * 10, 1)
        return True

    def intf_ack(self, intf):
        if intf not in self.vcd_vars:
            return True

        v = self.vcd_vars[intf]
        self.writer.change(v['ready'], timestep() * 10, 1)

        self.handhake.add(intf)
        return True

    def before_timestep(self, sim, timestep):
        self.writer.change(self.clk_var, timestep * 10 + 5, 0)
        return True

    def after_timestep(self, sim, timestep):
        timestep += 1
        self.writer.change(self.timestep_var, timestep * 10, timestep)
        self.writer.change(self.clk_var, timestep * 10, 1)
        for intf, v in self.vcd_vars.items():
            if intf in self.handhake:
                self.writer.change(v['ready'], timestep * 10, 0)
                self.writer.change(v['valid'], timestep * 10, 0)
                self.handhake.remove(intf)

        self.writer.flush()

        return True

    def finish(self):
        if not self.finished:
            self.writer.close()
            self.vcd_file.close()
            self.finished = True

            if self.shmid_proc:
                self.shmid_proc.terminate()

    def after_cleanup(self, sim):
        self.finish()
Beispiel #4
0
class VCD(SimExtend):
    @inject
    def __init__(
            self,
            trace_fn='pygears.vcd',
            include=Inject('debug/trace'),
            tlm=False,
            shmidcat=Inject('sim_extens/vcd/shmidcat'),
            vcd_fifo=Inject('sim_extens/vcd/vcd_fifo'),
            sim=Inject('sim/simulator'),
            outdir=Inject('results-dir'),
            expand_data=Inject('debug/expand_trace_data'),
    ):
        super().__init__()
        self.sim = sim
        self.expand_data = expand_data
        self.finished = False
        self.vcd_fifo = vcd_fifo
        self.shmidcat = shmidcat
        self.outdir = outdir
        self.trace_fn = None
        self.shmid_proc = None
        self.include = include

        self.trace_fn = os.path.abspath(os.path.join(self.outdir, trace_fn))
        atexit.register(self.finish)

        try:
            subprocess.call(f"rm -f {self.trace_fn}", shell=True)
        except OSError:
            pass

        if self.vcd_fifo:
            subprocess.call(f"mkfifo {self.trace_fn}", shell=True)
        else:
            log.info(f'Main VCD dump to "{self.trace_fn}"')

        if self.shmidcat:
            self.shmid_proc = subprocess.Popen(f'shmidcat {self.trace_fn}',
                                               shell=True,
                                               stdout=subprocess.PIPE)

            # Wait for shmidcat to actually open the pipe, which is necessary
            # to happen prior to init of the verilator. If shmidcat does not
            # open the pipe, verilator will get stuck
            import time
            time.sleep(0.1)

        self.vcd_file = open(self.trace_fn, 'w')

        if self.shmidcat:
            self.shmid = self.shmid_proc.stdout.readline().decode().strip()
            log.info(f'Main VCD dump to shared memory at 0x{self.shmid}')

        self.writer = VCDWriter(self.vcd_file, timescale='1 ns', date='today')

        reg['VCDWriter'] = self.writer
        reg['VCD'] = self

        self.clk_var = self.writer.register_var('', 'clk', 'wire', size=1, init=1)

        self.timestep_var = self.writer.register_var('', 'timestep', 'integer', init=0)

        self.handhake = set()

    def before_run(self, sim):
        vcd_visitor = VCDHierVisitor(self.include, False)
        vcd_visitor.visit(find('/'))

        if not vcd_visitor.vcd_vars:
            self.deactivate('before_run')
            return True

        self.vcd_vars = {
            p: register_traces_for_intf(p.dtype, scope, self.writer, self.expand_data)
            for p, scope in vcd_visitor.vcd_vars.items()
        }

        self.end_consumers = vcd_visitor.end_consumers

        self.writer.flush()

        for intf in self.end_consumers:
            intf.events['put'].append(self.intf_put)
            intf.events['ack'].append(self.intf_ack)

        vcd_intf_vars = {}
        for p, v in self.vcd_vars.items():
            intf.events['put'].append(self.intf_put)
            intf.events['ack'].append(self.intf_ack)
            vcd_intf_vars[p] = v

        self.vcd_vars = vcd_intf_vars
        self.extend_intfs()

    def extend_intfs(self):
        for p, v in self.vcd_vars.items():
            v['srcs'] = [self.end_consumers[pp.consumer] for pp in get_consumer_tree(p.consumer)]
            v['srcs_active'] = [False] * len(v['srcs'])
            v['p'] = p
            for vs in v['srcs']:
                vs['prods'].append(v)

        reg['graph/consumer_tree'] = {}
        reg['graph/end_producer'] = {}

    def var_put(self, v, val):
        cur_timestep = timestep() * 10
        if typeof(v['dtype'], (Any, TLM)):
            self.writer.change(v['data'], cur_timestep, str(val))
        else:
            try:
                if self.expand_data:
                    visitor = VCDValVisitor(v, self.writer, cur_timestep, max_level=10)
                    visitor.visit(v['dtype'], 'data', val=val)
                else:
                    self.writer.change(v['data'], cur_timestep, val.code())
            except AttributeError:
                pass

        self.writer.change(v['valid'], cur_timestep, 1)

    def intf_put(self, intf, val):
        p = intf.producer
        if p in self.vcd_vars:
            v = self.vcd_vars[p]
            self.var_put(v, val)

        if intf in self.end_consumers:
            v = self.end_consumers[intf]
            for vp in v['prods']:
                if not any(vp['srcs_active']):
                    # TODO: Optimization possibility, don't write the data, only ready/valid signals
                    self.var_put(vp, val)

                for i, vv in enumerate(vp['srcs']):
                    if vv is v:
                        vp['srcs_active'][i] = True
                        break

        return True

    def intf_ack(self, intf):
        p = intf.producer
        if p in self.vcd_vars:
            v = self.vcd_vars[p]
            self.writer.change(v['ready'], timestep() * 10, 1)
            self.handhake.add(p)

        if intf in self.end_consumers:
            v = self.end_consumers[intf]
            for vp in v['prods']:

                for i, vv in enumerate(vp['srcs']):
                    if vv is v:
                        vp['srcs_active'][i] = False
                        break

                if not any(vp['srcs_active']):
                    self.writer.change(vp['ready'], timestep() * 10, 1)
                    self.handhake.add(vp['p'])

        return True

    def before_timestep(self, sim, timestep):
        self.writer.change(self.clk_var, timestep * 10 + 5, 0)
        return True

    def after_timestep(self, sim, timestep):
        timestep += 1
        self.writer.change(self.timestep_var, timestep * 10, timestep)
        self.writer.change(self.clk_var, timestep * 10, 1)
        for p, v in self.vcd_vars.items():
            if p in self.handhake:
                self.writer.change(v['ready'], timestep * 10, 0)
                if not any(v['srcs_active']):
                    self.writer.change(v['valid'], timestep * 10, 0)

                self.handhake.remove(p)

        self.writer.flush()

        return True

    def finish(self):
        if not self.finished:
            self.writer.close()
            self.vcd_file.close()
            self.finished = True

            if self.shmid_proc:
                self.shmid_proc.terminate()

    def after_cleanup(self, sim):
        self.finish()