def get_fragment(self): comb = [] sync = [] ns = len(self.slaves) slave_sel = Signal(BV(ns)) slave_sel_r = Signal(BV(ns)) # decode slave addresses hi = self.master.adr.bv.width - self.offset comb += [ slave_sel[i].eq(self.master.adr[hi - addr.bv.width:hi] == addr) for i, addr in enumerate(self.addresses) ] if self.register: sync.append(slave_sel_r.eq(slave_sel)) else: comb.append(slave_sel_r.eq(slave_sel)) # connect master->slaves signals except cyc m2s_names = _desc.get_names(M_TO_S, "cyc") comb += [ getattr(slave[1], name).eq(getattr(self.master, name)) for name in m2s_names for slave in self.slaves ] # combine cyc with slave selection signals comb += [ slave[1].cyc.eq(self.master.cyc & slave_sel[i]) for i, slave in enumerate(self.slaves) ] # generate master ack (resp. err) by ORing all slave acks (resp. errs) comb += [ self.master.ack.eq( optree("|", [slave[1].ack for slave in self.slaves])), self.master.err.eq( optree("|", [slave[1].err for slave in self.slaves])) ] # mux (1-hot) slave data return masked = [ Replicate(slave_sel_r[i], self.master.dat_r.bv.width) & self.slaves[i][1].dat_r for i in range(len(self.slaves)) ] comb.append(self.master.dat_r.eq(optree("|", masked))) return Fragment(comb, sync)
def get_fragment(self): this_fragments = [get_conn_fragment(x[0].endpoints[x[2]["source"]], x[1].endpoints[x[2]["sink"]]) for x in self.dfg.edges(data=True)] this = sum(this_fragments, Fragment()) others = sum([node.get_fragment() for node in self.dfg], Fragment()) busy = Fragment([self.busy.eq(optree("|", [node.busy for node in self.dfg]))]) return this + others + busy
def get_fragment(self): if not self.finalized: raise FinalizeError slots_fragment = sum([s.get_fragment() for s in self.slots], Fragment()) comb = [] sync = [] # allocate for s in self.slots: comb += [s.allocate_we.eq(self.we), s.allocate_adr.eq(self.adr)] choose_slot = None for s in reversed(self.slots): choose_slot = If(s.state == SLOT_EMPTY, s.allocate.eq(self.stb)).Else(choose_slot) comb.append(choose_slot) comb.append( self.ack.eq( optree("|", [s.state == SLOT_EMPTY for s in self.slots]))) # call comb += [ s.call.eq(self.get_call_expression(n)) for n, s in enumerate(self.slots) ] return slots_fragment + Fragment(comb, sync)
def get_fragment(self): if not self.finalized: raise FinalizeError ports = sum([port.get_fragment() for port in self.ports], Fragment()) comb = [] for port in self.ports: comb += [ port.call.eq(self.call), port.tag_call.eq(self.tag_call), port.dat_r.eq(self.dat_r) ] comb += [ self.dat_w.eq(optree("|", [port.dat_w for port in self.ports])), self.dat_wm.eq(optree("|", [port.dat_wm for port in self.ports])) ] return ports + Fragment(comb)
def get_fragment(self): if not self.finalized: raise FinalizeError slots_fragment = sum([s.get_fragment() for s in self.slots], Fragment()) comb = [] sync = [] # allocate for s in self.slots: comb += [ s.allocate_we.eq(self.we), s.allocate_adr.eq(self.adr) ] choose_slot = None needs_tags = len(self.slots) > 1 for n, s in reversed(list(enumerate(self.slots))): choose_slot = If(s.state == SLOT_EMPTY, s.allocate.eq(self.stb), self.tag_issue.eq(n) if needs_tags else None ).Else(choose_slot) comb.append(choose_slot) comb.append(self.ack.eq(optree("|", [s.state == SLOT_EMPTY for s in self.slots]))) # call comb += [s.call.eq(self.get_call_expression(n)) for n, s in enumerate(self.slots)] return slots_fragment + Fragment(comb, sync)
def get_fragment(self): source = self.endpoints["source"] sinks = [self.endpoints["sink{0}".format(n)] for n in range(len(self.endpoints)-1)] comb = [source.stb.eq(optree("&", [sink.stb for sink in sinks]))] comb += [sink.ack.eq(source.ack & source.stb) for sink in sinks] return Fragment(comb)
def get_fragment(self): source = self.endpoints["source"] sinks = [ self.endpoints["sink{0}".format(n)] for n in range(len(self.endpoints) - 1) ] comb = [source.stb.eq(optree("&", [sink.stb for sink in sinks]))] comb += [sink.ack.eq(source.ack & source.stb) for sink in sinks] return Fragment(comb)
def get_fragment(self): comb = [self.busy.eq(optree("|", [node.actor.busy for node in self.dfg]))] fragment = Fragment(comb) for node in self.dfg: fragment += node.actor.get_fragment() for u, v, d in self.dfg.edges_iter(data=True): ep_src = u.actor.endpoints[d["source"]] ep_dst = v.actor.endpoints[d["sink"]] fragment += get_conn_fragment(ep_src, ep_dst) return fragment
def simple_interconnect_stmts(desc, master, slaves): s2m = desc.get_names(S_TO_M) m2s = desc.get_names(M_TO_S) sl = [getattr(slave, name).eq(getattr(master, name)) for name in m2s for slave in slaves] sl += [getattr(master, name).eq( optree("|", [getattr(slave, name) for slave in slaves]) ) for name in s2m] return sl
def get_fragment(self): comb = [ self.busy.eq(optree("|", [node.actor.busy for node in self.dfg])) ] fragment = Fragment(comb) for node in self.dfg: fragment += node.actor.get_fragment() for u, v, d in self.dfg.edges_iter(data=True): ep_src = u.actor.endpoints[d["source"]] ep_dst = v.actor.endpoints[d["sink"]] fragment += get_conn_fragment(ep_src, ep_dst) return fragment
def simple_interconnect_stmts(desc, master, slaves): s2m = desc.get_names(S_TO_M) m2s = desc.get_names(M_TO_S) sl = [ getattr(slave, name).eq(getattr(master, name)) for name in m2s for slave in slaves ] sl += [ getattr(master, name).eq( optree("|", [getattr(slave, name) for slave in slaves])) for name in s2m ] return sl
def get_fragment(self): muls = [] sync = [] src = self.i for c in self.coef: sreg = Signal((self.wsize, True)) sync.append(sreg.eq(src)) src = sreg c_fp = int(c*2**(self.wsize - 1)) muls.append(c_fp*sreg) sum_full = Signal((2*self.wsize-1, True)) sync.append(sum_full.eq(optree("+", muls))) comb = [self.o.eq(sum_full[self.wsize-1:])] return Fragment(comb, sync)
def get_fragment(self): comb = [] sync = [] ns = len(self.slaves) slave_sel = Signal(BV(ns)) slave_sel_r = Signal(BV(ns)) # decode slave addresses hi = self.master.adr.bv.width - self.offset comb += [slave_sel[i].eq(self.master.adr[hi-addr.bv.width:hi] == addr) for i, addr in enumerate(self.addresses)] if self.register: sync.append(slave_sel_r.eq(slave_sel)) else: comb.append(slave_sel_r.eq(slave_sel)) # connect master->slaves signals except cyc m2s_names = _desc.get_names(M_TO_S, "cyc") comb += [getattr(slave[1], name).eq(getattr(self.master, name)) for name in m2s_names for slave in self.slaves] # combine cyc with slave selection signals comb += [slave[1].cyc.eq(self.master.cyc & slave_sel[i]) for i, slave in enumerate(self.slaves)] # generate master ack (resp. err) by ORing all slave acks (resp. errs) comb += [ self.master.ack.eq(optree("|", [slave[1].ack for slave in self.slaves])), self.master.err.eq(optree("|", [slave[1].err for slave in self.slaves])) ] # mux (1-hot) slave data return masked = [Replicate(slave_sel_r[i], self.master.dat_r.bv.width) & self.slaves[i][1].dat_r for i in range(len(self.slaves))] comb.append(self.master.dat_r.eq(optree("|", masked))) return Fragment(comb, sync)
def get_fragment(self): muls = [] sync = [] src = self.i for c in self.coef: sreg = Signal(BV(self.wsize, True)) sync.append(sreg.eq(src)) src = sreg c_fp = int(c * 2**(self.wsize - 1)) c_e = Constant(c_fp, BV(bits_for(c_fp), True)) muls.append(c_e * sreg) sum_full = Signal(BV(2 * self.wsize - 1, True)) sync.append(sum_full.eq(optree("+", muls))) comb = [self.o.eq(sum_full[self.wsize - 1:])] return Fragment(comb, sync)
def _control_fragment_pipe(latency, stb_i, ack_o, stb_o, ack_i, busy, pipe_ce): valid = Signal(BV(latency)) if latency > 1: sync = [If(pipe_ce, valid.eq(Cat(stb_i, valid[:latency-1])))] else: sync = [If(pipe_ce, valid.eq(stb_i))] last_valid = valid[latency-1] comb = [ pipe_ce.eq(ack_i | ~last_valid), ack_o.eq(pipe_ce), stb_o.eq(last_valid), busy.eq(optree("|", [valid[i] for i in range(latency)])) ] return Fragment(comb, sync)
def get_binary_control_fragment(self, stb_i, ack_o, stb_o, ack_i): valid = Signal(BV(self.latency)) if self.latency > 1: sync = [If(self.pipe_ce, valid.eq(Cat(stb_i, valid[:self.latency-1])))] else: sync = [If(self.pipe_ce, valid.eq(stb_i))] last_valid = valid[self.latency-1] comb = [ self.pipe_ce.eq(ack_i | ~last_valid), ack_o.eq(self.pipe_ce), stb_o.eq(last_valid), busy.eq(optree("|", [valid[i] for i in range(self.latency)])) ] return Fragment(comb, sync)
def get_fragment(self): sources = [self.endpoints[e] for e in self.sources()] sink = self.endpoints[self.sinks()[0]] already_acked = Signal(len(sources)) sync = [ If(sink.stb, already_acked.eq(already_acked | Cat(*[s.ack for s in sources])), If(sink.ack, already_acked.eq(0)) ) ] comb = [ sink.ack.eq(optree("&", [s.ack | already_acked[n] for n, s in enumerate(sources)])) ] for n, s in enumerate(sources): comb.append(s.stb.eq(sink.stb & ~already_acked[n])) return Fragment(comb, sync)
def get_binary_control_fragment(self, stb_i, ack_o, stb_o, ack_i): valid = Signal(BV(self.latency)) if self.latency > 1: sync = [ If(self.pipe_ce, valid.eq(Cat(stb_i, valid[:self.latency - 1]))) ] else: sync = [If(self.pipe_ce, valid.eq(stb_i))] last_valid = valid[self.latency - 1] comb = [ self.pipe_ce.eq(ack_i | ~last_valid), ack_o.eq(self.pipe_ce), stb_o.eq(last_valid), busy.eq(optree("|", [valid[i] for i in range(self.latency)])) ] return Fragment(comb, sync)
def get_fragment(self): sources = [self.endpoints[e] for e in self.sources()] sink = self.endpoints[self.sinks()[0]] already_acked = Signal(BV(len(sources))) sync = [ If( sink.stb, already_acked.eq(already_acked | Cat(*[s.ack for s in sources])), If(sink.ack, already_acked.eq(0))) ] comb = [ sink.ack.eq( optree( "&", [s.ack | already_acked[n] for n, s in enumerate(sources)])) ] for n, s in enumerate(sources): comb.append(s.stb.eq(sink.stb & ~already_acked[n])) return Fragment(comb, sync)
def get_fragment(self): comb = [] sync = [] # status for i, source in enumerate(self.sources): if isinstance(source, EventSourcePulse): comb.append(self.status.w[i].eq(0)) elif isinstance(source, EventSourceLevel): comb.append(self.status.w[i].eq(source.trigger)) else: raise TypeError # pending for i, source in enumerate(self.sources): # W1C sync.append( If(self.pending.re & self.pending.r[i], source.pending.eq(0))) if isinstance(source, EventSourcePulse): # set on a positive trigger pulse sync.append(If(source.trigger, source.pending.eq(1))) elif isinstance(source, EventSourceLevel): # set on the falling edge of the trigger old_trigger = Signal() sync += [ old_trigger.eq(source.trigger), If(~source.trigger & old_trigger, source.pending.eq(1)) ] else: raise TypeError comb.append(self.pending.w[i].eq(source.pending)) # IRQ irqs = [ self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields) ] comb.append(self.irq.eq(optree("|", irqs))) return Fragment(comb, sync)
def get_fragment(self): comb = [] sync = [] # status for i, source in enumerate(self.sources): if isinstance(source, EventSourcePulse): comb.append(self.status.w[i].eq(0)) elif isinstance(source, EventSourceLevel): comb.append(self.status.w[i].eq(source.trigger)) else: raise TypeError # pending for i, source in enumerate(self.sources): pending = Signal() # W1C sync.append(If(self.pending.re & self.pending.r[i], pending.eq(0))) if isinstance(source, EventSourcePulse): # set on a positive trigger pulse sync.append(If(source.trigger, pending.eq(1))) elif isinstance(source, EventSourceLevel): # set on the falling edge of the trigger old_trigger = Signal() sync += [ old_trigger.eq(source.trigger), If(~source.trigger & old_trigger, pending.eq(1)) ] else: raise TypeError comb.append(self.pending.w[i].eq(pending)) # IRQ irqs = [self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields)] comb.append(self.irq.eq(optree("|", irqs))) return Fragment(comb, sync)
def __init__(self): la = gen_list(3) lb = gen_2list(2) self.sigs = la + lb class Bar: def __init__(self): self.sigs = gen_list(2) class Toto: def __init__(self): self.sigs = gen_list(2) a = [Bar() for x in range(3)] b = [Foo() for x in range(3)] c = b b = [Bar() for x in range(2)] output = Signal() allsigs = [] for lst in [a, b, c]: for obj in lst: allsigs.extend(obj.sigs) comb = [output.eq(optree("|", allsigs))] f = Fragment(comb) print(verilog.convert(f))