def intf_put(self, intf, val): if intf not in self.vcd_vars: return True for v in self.vcd_vars[intf]: if typeof(intf.dtype, TLM): self.writer.change(v.waves['data'], timestep(), str(val)) else: visitor = WaveJSONValVisitor(v.waves, self.writer, timestep()) visitor.visit(v.dtype, '', val=val) return True
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 test_pygears_sim(): seq = list(range(10)) directed(drv(t=Uint[16], seq=seq), f=dreg, ref=seq) sim() assert timestep() == len(seq) + 2
def sim_vcd_to_json(self): graph = dump_json_graph('/') if self.multiprocess: self.finish_event.set() json_vcds = [qin.recv() for qin in self.qin] for p in self.p: p.join() else: json_vcds = [] for top, trace_fn in self.cosim_modules: json_vcds.append(vcd_to_json(top, follow(trace_fn))) json_vcds.append(vcd_to_json(find('/'), follow(self.vcd_fn))) visited_channels = set() changes = [] for json_vcd in json_vcds: if json_vcd is None: continue for p_name in json_vcd: p = find(p_name) intf_name = p_name port_name = None if isinstance(p, Intf) else p.producer.name if ((isinstance(p, InPort) or (isinstance(p, OutPort) and node_hierarchical(p.gear))) and len(p.producer.consumers) > 1): for i in range(len(p.producer.consumers)): if p.producer.consumers[i] is p: break if isinstance(p, InPort) and node_hierarchical(p.gear): intf_name = p_name bc_name = f'{p.producer.parent.name}/{p.producer.basename}_bc' port_name = f'{bc_name}.dout{i}' if isinstance(p, InPort) and (p.consumer is None or any( isinstance(c, HDLConsumer) for c in p.consumer.consumers)): intf_name = None for channel_name in [intf_name, port_name]: if channel_name is not None and channel_name not in visited_channels: changes.append({ 'channelName': channel_name, 'changes': json_vcd[p_name] }) visited_channels.add(channel_name) return { 'graphInfo': graph, 'simulationChanges': { 'startCycle': 0, 'endCycle': timestep(), 'channelChanges': changes } }
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
async def actuator(x: Float, *, qin, clk_freq, init): x_data = init while (1): if not x.empty(): x_data = x.get_nb() qin.put((x_data, (timestep() + 1) / clk_freq)) await clk()
def intf_ack(self, intf): if intf not in self.vcd_vars: return True ts = timestep() for v in self.vcd_vars[intf]: for sig in v.waves.values(): self.writer.ack(sig, ts) self.handhake.add(intf) 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 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)
async def scope(*xs, clk_freq=None, title=None, scale=None, method=None, live=None, dump=None, transaction=False): if clk_freq is None: clk_freq = reg['sim/clk_freq'] if method is None: method = ['plot'] * len(xs) if len(method) != len(xs): raise Exception( f'Number of plotting methods ({method}) needs to match the number of inputs ({len(xs)})' ) if title is None: title = module().name parallel_steps = max( len(x.dtype) if typeof(x.dtype, Array) else 1 for x in xs) backends = [] kwds = { 'method': method, 'clk_freq': clk_freq * parallel_steps, 'title': title, 'scale': scale, 'transaction': transaction } if live or (live is None and dump is None): backends.append(plot_live(**kwds)) if dump: backends.append(plot_dump(dump, **kwds)) for b in backends: b.send(None) try: while True: for ch, x in enumerate(xs): if x.done: raise GearDone if x.empty(): continue async with x as x_data: if isinstance(x_data, Queue): x_data, eot = x_data else: eot = 0 if not isinstance(x_data, Array): x_data = [x_data] for i, v in enumerate(x_data): point = (ch, (timestep() + i / len(x_data)) / clk_freq, float(v), int(eot)) for b in backends: b.send(point) await clk() except GearDone: for b in backends: b.close() raise GearDone
def json(self, vcd_vars): if timestep() is None: return {} def get_sig_scope(data, scope): if not scope: return data for child in data: if not isinstance(child, list): continue if child[0] == scope[0]: return get_sig_scope(child, scope[1:]) data.append([scope[0]]) return get_sig_scope(data[-1], scope[1:]) data = { 'signal': [{ 'name': 'clk', 'wave': 'p' + '.' * (timestep()) }], 'head': { 'tock': 0 }, } for _, wintfs in vcd_vars.items(): for w in wintfs: for name, s in w.waves.items(): # for s in self.signals: vals = self.values[s] eot = 0 js_sig = {'name': s.name, 'wave': '', 'data': []} state = None for t in range(timestep() + 1): if t in vals: if typeof(w.dtype, Queue): if self.values[w.waves['eot']][t].val: eot = 1 elif self.values[w.waves['eot']][t].val == 0: eot = 0 val = vals[t] if val.state == 1: js_sig['wave'] += '4' elif eot: js_sig['wave'] += '3' else: js_sig['wave'] += '5' state = val.state if val.val is not None: js_sig['data'].append(str(val.val)) else: js_sig['data'].append(js_sig['data'][-1]) elif state == 3: state = 0 js_sig['wave'] += 'z' elif state is None: state = 0 js_sig['wave'] += 'z' else: js_sig['wave'] += '.' scope = get_sig_scope(data['signal'], s.scope) scope.append(js_sig) return data