Permalink
Browse files

bus: simplify and cleanup

Unify slave and master interfaces
Remove signal direction suffixes
Generic simple interconnect
Wishbone point-to-point interconnect
Description filter (get_name)
Misc cleanups
  • Loading branch information...
sbourdeauducq committed Feb 15, 2012
1 parent 46b1f74 commit 04932121246b8e0e859fbdd0c890f4138ed73109
@@ -1,19 +1,19 @@
from migen.fhdl import verilog
from migen.bus import wishbone
-m1 = wishbone.Master()
-m2 = wishbone.Master()
-s1 = wishbone.Slave()
-s2 = wishbone.Slave()
+m1 = wishbone.Interface()
+m2 = wishbone.Interface()
+s1 = wishbone.Interface()
+s2 = wishbone.Interface()
wishbonecon0 = wishbone.InterconnectShared(
[m1, m2],
[(0, s1), (1, s2)],
register=True,
offset=1)
frag = wishbonecon0.get_fragment()
-v = verilog.convert(frag, name="intercon", ios={m1.cyc_o, m1.stb_o, m1.we_o, m1.adr_o, m1.sel_o, m1.dat_o, m1.dat_i, m1.ack_i,
- m2.cyc_o, m2.stb_o, m2.we_o, m2.adr_o, m2.sel_o, m2.dat_o, m2.dat_i, m2.ack_i,
- s1.cyc_i, s1.stb_i, s1.we_i, s1.adr_i, s1.sel_i, s1.dat_i, s1.dat_o, s1.ack_o,
- s2.cyc_i, s2.stb_i, s2.we_i, s2.adr_i, s2.sel_i, s2.dat_i, s2.dat_o, s2.ack_o})
+v = verilog.convert(frag, name="intercon", ios={m1.cyc, m1.stb, m1.we, m1.adr, m1.sel, m1.dat_w, m1.dat_r, m1.ack,
+ m2.cyc, m2.stb, m2.we, m2.adr, m2.sel, m2.dat_r, m2.dat_w, m2.ack,
+ s1.cyc, s1.stb, s1.we, s1.adr, s1.sel, s1.dat_r, s1.dat_w, s1.ack,
+ s2.cyc, s2.stb, s2.we, s2.adr, s2.sel, s2.dat_r, s2.dat_w, s2.ack})
print(v)
@@ -80,42 +80,42 @@ intercon dut(
.sys_rst(sys_rst),
// Master 0
- .m1_wishbone_dat_o(m1_wishbone_dat_w),
- .m1_wishbone_dat_i(m1_wishbone_dat_r),
- .m1_wishbone_adr_o(m1_wishbone_adr),
- .m1_wishbone_we_o(m1_wishbone_we),
- .m1_wishbone_sel_o(m1_wishbone_sel),
- .m1_wishbone_cyc_o(m1_wishbone_cyc),
- .m1_wishbone_stb_o(m1_wishbone_stb),
- .m1_wishbone_ack_i(m1_wishbone_ack),
+ .m1_wishbone_dat_w(m1_wishbone_dat_w),
+ .m1_wishbone_dat_r(m1_wishbone_dat_r),
+ .m1_wishbone_adr(m1_wishbone_adr),
+ .m1_wishbone_we(m1_wishbone_we),
+ .m1_wishbone_sel(m1_wishbone_sel),
+ .m1_wishbone_cyc(m1_wishbone_cyc),
+ .m1_wishbone_stb(m1_wishbone_stb),
+ .m1_wishbone_ack(m1_wishbone_ack),
// Master 1
- .m2_wishbone_dat_o(m2_wishbone_dat_w),
- .m2_wishbone_dat_i(m2_wishbone_dat_r),
- .m2_wishbone_adr_o(m2_wishbone_adr),
- .m2_wishbone_we_o(m2_wishbone_we),
- .m2_wishbone_sel_o(m2_wishbone_sel),
- .m2_wishbone_cyc_o(m2_wishbone_cyc),
- .m2_wishbone_stb_o(m2_wishbone_stb),
- .m2_wishbone_ack_i(m2_wishbone_ack),
+ .m2_wishbone_dat_w(m2_wishbone_dat_w),
+ .m2_wishbone_dat_r(m2_wishbone_dat_r),
+ .m2_wishbone_adr(m2_wishbone_adr),
+ .m2_wishbone_we(m2_wishbone_we),
+ .m2_wishbone_sel(m2_wishbone_sel),
+ .m2_wishbone_cyc(m2_wishbone_cyc),
+ .m2_wishbone_stb(m2_wishbone_stb),
+ .m2_wishbone_ack(m2_wishbone_ack),
// Slave 0
- .s1_wishbone_dat_o(s1_wishbone_dat_r),
- .s1_wishbone_dat_i(s1_wishbone_dat_w),
- .s1_wishbone_adr_i(s1_wishbone_adr),
- .s1_wishbone_sel_i(s1_wishbone_sel),
- .s1_wishbone_we_i(s1_wishbone_we),
- .s1_wishbone_cyc_i(s1_wishbone_cyc),
- .s1_wishbone_stb_i(s1_wishbone_stb),
- .s1_wishbone_ack_o(s1_wishbone_ack),
+ .s1_wishbone_dat_r(s1_wishbone_dat_r),
+ .s1_wishbone_dat_w(s1_wishbone_dat_w),
+ .s1_wishbone_adr(s1_wishbone_adr),
+ .s1_wishbone_sel(s1_wishbone_sel),
+ .s1_wishbone_we(s1_wishbone_we),
+ .s1_wishbone_cyc(s1_wishbone_cyc),
+ .s1_wishbone_stb(s1_wishbone_stb),
+ .s1_wishbone_ack(s1_wishbone_ack),
// Slave 1
- .s2_wishbone_dat_o(s2_wishbone_dat_r),
- .s2_wishbone_dat_i(s2_wishbone_dat_w),
- .s2_wishbone_adr_i(s2_wishbone_adr),
- .s2_wishbone_sel_i(s2_wishbone_sel),
- .s2_wishbone_we_i(s2_wishbone_we),
- .s2_wishbone_cyc_i(s2_wishbone_cyc),
- .s2_wishbone_stb_i(s2_wishbone_stb),
- .s2_wishbone_ack_o(s2_wishbone_ack)
+ .s2_wishbone_dat_r(s2_wishbone_dat_r),
+ .s2_wishbone_dat_w(s2_wishbone_dat_w),
+ .s2_wishbone_adr(s2_wishbone_adr),
+ .s2_wishbone_sel(s2_wishbone_sel),
+ .s2_wishbone_we(s2_wishbone_we),
+ .s2_wishbone_cyc(s2_wishbone_cyc),
+ .s2_wishbone_stb(s2_wishbone_stb),
+ .s2_wishbone_ack(s2_wishbone_ack)
);
//---------------------------------------------------------------------------
View
@@ -1,33 +1,16 @@
from migen.fhdl.structure import *
-from migen.corelogic.misc import optree
-from migen.bus.simple import Simple
+from migen.bus.simple import *
-_desc = [
- (True, "adr", 14),
- (True, "we", 1),
- (True, "dat", 8),
- (False, "dat", 8)
-]
+_desc = Description(
+ (M_TO_S, "adr", 14),
+ (M_TO_S, "we", 1),
+ (M_TO_S, "dat_w", 8),
+ (S_TO_M, "dat_r", 8)
+)
-class Master(Simple):
+class Interface(SimpleInterface):
def __init__(self):
- Simple.__init__(self, _desc, False)
+ SimpleInterface.__init__(self, _desc)
-class Slave(Simple):
- def __init__(self):
- Simple.__init__(self, _desc, True)
-
-class Interconnect:
- def __init__(self, master, slaves):
- self.master = master
- self.slaves = slaves
-
- def get_fragment(self):
- comb = []
- for slave in self.slaves:
- comb.append(slave.adr_i.eq(self.master.adr_o))
- comb.append(slave.we_i.eq(self.master.we_o))
- comb.append(slave.dat_i.eq(self.master.dat_o))
- rb = optree("|", [slave.dat_o for slave in self.slaves])
- comb.append(self.master.dat_i.eq(rb))
- return Fragment(comb)
+class Interconnect(SimpleInterconnect):
+ pass
View
@@ -1,25 +1,44 @@
from migen.fhdl.structure import *
+from migen.corelogic.misc import optree
-def get_sig_name(signal, slave):
- if signal[0] ^ slave:
- suffix = "_o"
- else:
- suffix = "_i"
- return signal[1] + suffix
+(S_TO_M, M_TO_S) = range(2)
# desc is a list of tuples, each made up of:
-# 0) boolean: "master to slave"
+# 0) S_TO_M/M_TO_S: data direction
# 1) string: name
# 2) int: width
-class Simple():
- def __init__(self, desc, slave):
- for signal in desc:
- modules = self.__module__.split(".")
- busname = modules[len(modules)-1]
- signame = get_sig_name(signal, slave)
+
+class Description:
+ def __init__(self, *desc):
+ self.desc = desc
+
+ def get_names(self, direction, *exclude_list):
+ exclude = set(exclude_list)
+ return [signal[1]
+ for signal in self.desc
+ if signal[0] == direction and signal[1] not in exclude]
+
+class SimpleInterface:
+ def __init__(self, desc):
+ self.desc = desc
+ modules = self.__module__.split(".")
+ busname = modules[len(modules)-1]
+ for signal in self.desc.desc:
+ signame = signal[1]
setattr(self, signame, Signal(BV(signal[2]), busname + "_" + signame))
+
+class SimpleInterconnect:
+ def __init__(self, master, slaves):
+ self.master = master
+ self.slaves = slaves
- def signals(self):
- return [self.__dict__[k]
- for k in self.__dict__
- if isinstance(self.__dict__[k], Signal)]
+ def get_fragment(self):
+ s2m = master.desc.get_names(S_TO_M)
+ m2s = master.desc.get_names(M_TO_S)
+ comb = [getattr(slave, name).eq(getattr(master, name))
+ for name in m2s for slave in self.slave]
+ comb += [getattr(master, name).eq(
+ optree("|", [getattr(slave, name) for slave in self.slaves])
+ )
+ for name in s2m]
+ return Fragment(comb)
View
@@ -1,29 +1,29 @@
from migen.fhdl.structure import *
from migen.corelogic import roundrobin
from migen.corelogic.misc import multimux, optree
-from migen.bus.simple import Simple, get_sig_name
+from migen.bus.simple import *
-_desc = [
- (True, "adr", 30),
- (True, "dat", 32),
- (False, "dat", 32),
- (True, "sel", 4),
- (True, "cyc", 1),
- (True, "stb", 1),
- (False, "ack", 1),
- (True, "we", 1),
- (True, "cti", 3),
- (True, "bte", 2),
- (False, "err", 1)
-]
+_desc = Description(
+ (M_TO_S, "adr", 30),
+ (M_TO_S, "dat_w", 32),
+ (S_TO_M, "dat_r", 32),
+ (M_TO_S, "sel", 4),
+ (M_TO_S, "cyc", 1),
+ (M_TO_S, "stb", 1),
+ (S_TO_M, "ack", 1),
+ (M_TO_S, "we", 1),
+ (M_TO_S, "cti", 3),
+ (M_TO_S, "bte", 2),
+ (S_TO_M, "err", 1)
+)
-class Master(Simple):
+class Interface(SimpleInterface):
def __init__(self):
- Simple.__init__(self, _desc, False)
+ SimpleInterface.__init__(self, _desc)
-class Slave(Simple):
- def __init__(self):
- Simple.__init__(self, _desc, True)
+class InterconnectPointToPoint(SimpleInterconnect):
+ def __init__(self, master, slave):
+ SimpleInterconnect.__init__(self, master, [slave])
class Arbiter:
def __init__(self, masters, target):
@@ -35,26 +35,23 @@ def get_fragment(self):
comb = []
# mux master->slave signals
- m2s_names = [get_sig_name(x, False) for x in _desc if x[0]]
+ m2s_names = _desc.get_names(M_TO_S)
m2s_masters = [[getattr(m, name) for name in m2s_names] for m in self.masters]
m2s_target = [getattr(self.target, name) for name in m2s_names]
comb += multimux(self.rr.grant, m2s_masters, m2s_target)
# connect slave->master signals
- s2m_names = [get_sig_name(x, False) for x in _desc if not x[0]]
- for name in s2m_names:
+ for name in _desc.get_names(S_TO_M):
source = getattr(self.target, name)
- i = 0
- for m in self.masters:
+ for i, m in enumerate(self.masters):
dest = getattr(m, name)
- if name == "ack_i" or name == "err_i":
+ if name == "ack" or name == "err":
comb.append(dest.eq(source & (self.rr.grant == Constant(i, self.rr.grant.bv))))
else:
comb.append(dest.eq(source))
- i += 1
# connect bus requests to round-robin selector
- reqs = [m.cyc_o for m in self.masters]
+ reqs = [m.cyc for m in self.masters]
comb.append(self.rr.request.eq(Cat(*reqs)))
return Fragment(comb) + self.rr.get_fragment()
@@ -92,42 +89,38 @@ def get_fragment(self):
slave_sel_r = Signal(BV(ns))
# decode slave addresses
- i = 0
- hi = self.master.adr_o.bv.width - self.offset
- for addr in self.addresses:
- comb.append(slave_sel[i].eq(
- self.master.adr_o[hi-addr.bv.width:hi] == addr))
- i += 1
+ 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 = [(get_sig_name(x, False), get_sig_name(x, True))
- for x in _desc if x[0] and x[1] != "cyc"]
- comb += [getattr(slave[1], name[1]).eq(getattr(self.master, name[0]))
+ 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
- i = 0
- for slave in self.slaves:
- comb.append(slave[1].cyc_i.eq(self.master.cyc_o & slave_sel[i]))
- i += 1
+ 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.append(self.master.ack_i.eq(optree("|", [slave[1].ack_o for slave in self.slaves])))
- comb.append(self.master.err_i.eq(optree("|", [slave[1].err_o for slave in self.slaves])))
+ 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_i.bv.width) & self.slaves[i][1].dat_o for i in range(len(self.slaves))]
- comb.append(self.master.dat_i.eq(optree("|", masked)))
+ 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)
class InterconnectShared:
def __init__(self, masters, slaves, offset=0, register=False):
- self._shared = Master()
+ self._shared = Interface()
self._arbiter = Arbiter(masters, self._shared)
self._decoder = Decoder(self._shared, slaves, offset, register)
self.addresses = self._decoder.addresses
Oops, something went wrong.

0 comments on commit 0493212

Please sign in to comment.