Exemple #1
0
    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)
Exemple #2
0
	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
Exemple #3
0
    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)
Exemple #4
0
 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)
Exemple #5
0
	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)
Exemple #6
0
	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)
Exemple #7
0
	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)
Exemple #8
0
 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)
Exemple #9
0
	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
Exemple #10
0
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
Exemple #11
0
 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
Exemple #12
0
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
Exemple #13
0
	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)
Exemple #14
0
	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)
Exemple #15
0
 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)
Exemple #16
0
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)
Exemple #17
0
	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)
Exemple #18
0
	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)
Exemple #19
0
    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)
Exemple #20
0
    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)
Exemple #21
0
    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)
Exemple #22
0
	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)
Exemple #23
0
    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))