Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 4 commits
  • 2 files changed
  • 0 commit comments
  • 2 contributors
Showing with 108 additions and 14 deletions.
  1. +97 −6 migen/bus/wishbone.py
  2. +11 −8 migen/bus/wishbone2lasmi.py
View
103 migen/bus/wishbone.py
@@ -1,7 +1,8 @@
from migen.fhdl.std import *
from migen.genlib import roundrobin
from migen.genlib.record import *
-from migen.genlib.misc import optree
+from migen.genlib.misc import optree, chooser
+from migen.genlib.fsm import FSM, NextState
from migen.bus.transactions import *
from migen.sim.generic import Proxy
@@ -111,6 +112,95 @@ def __init__(self, masters, slaves, register=False):
for column, bus in zip(zip(*access), busses):
self.submodules += Arbiter(column, bus)
+class DownConverter(Module):
+ # DownConverter splits Wishbone accesses of N bits in M accesses of L bits where:
+ # N is the original data-width
+ # L is the target data-width
+ # M = N/L
+ def __init__(self, dw_i, dw_o):
+
+ self.wishbone_i = Interface(dw_i)
+ self.wishbone_o = Interface(dw_o)
+ self.ratio = dw_i//dw_o
+
+ ###
+
+ rst = Signal()
+
+ # generate internal write and read ack
+ write_ack = Signal()
+ read_ack = Signal()
+ ack = Signal()
+ self.comb += [
+ ack.eq(self.wishbone_o.cyc & self.wishbone_o.stb & self.wishbone_o.ack),
+ write_ack.eq(ack & self.wishbone_o.we),
+ read_ack.eq(ack & ~self.wishbone_o.we)
+ ]
+
+ # accesses counter logic
+ cnt = Signal(max=self.ratio)
+ self.sync += If(rst, cnt.eq(0)).Elif(ack, cnt.eq(cnt + 1))
+
+ # read data path
+ dat_r = Signal(dw_i)
+ self.sync += If(ack, dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o])))
+
+ # write data path
+ dat_w = Signal(dw_i)
+ self.comb += dat_w.eq(self.wishbone_i.dat_w)
+
+ # errors generation
+ err = Signal()
+ self.sync += If(ack, err.eq(self.wishbone_o.err))
+
+ # direct connection of wishbone_i --> wishbone_o signals
+ for name, size, direction in self.wishbone_i.layout:
+ if direction == DIR_M_TO_S and name not in ["adr", "dat_w"]:
+ self.comb += getattr(self.wishbone_o, name).eq(getattr(self.wishbone_i, name))
+
+ # adaptation of adr & dat signals
+ self.comb += [
+ self.wishbone_o.adr[0:flen(cnt)].eq(cnt),
+ self.wishbone_o.adr[flen(cnt):].eq(self.wishbone_i.adr)
+ ]
+
+ self.comb += chooser(dat_w, cnt, self.wishbone_o.dat_w, reverse=True)
+
+ # fsm
+ fsm = FSM(reset_state="IDLE")
+ self.submodules += fsm
+
+ fsm.act("IDLE",
+ If(write_ack,
+ NextState("WRITE_ADAPT")
+ ),
+ If(read_ack,
+ NextState("READ_ADAPT")
+ )
+ )
+
+ fsm.act("WRITE_ADAPT",
+ If(write_ack & (cnt == self.ratio-1),
+ NextState("IDLE"),
+ rst.eq(1),
+ self.wishbone_i.err.eq(err | self.wishbone_o.err),
+ self.wishbone_i.ack.eq(1),
+ )
+ )
+
+ master_i_dat_r = Signal(dw_i)
+ self.comb += master_i_dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o]))
+
+ fsm.act("READ_ADAPT",
+ If(read_ack & (cnt == self.ratio-1),
+ NextState("IDLE"),
+ rst.eq(1),
+ self.wishbone_i.err.eq(err | self.wishbone_o.err),
+ self.wishbone_i.ack.eq(1),
+ self.wishbone_i.dat_r.eq(master_i_dat_r)
+ )
+ )
+
class Tap(Module):
def __init__(self, bus, handler=print):
self.bus = bus
@@ -196,19 +286,20 @@ def do_simulation(self, s):
class SRAM(Module):
def __init__(self, mem_or_size, read_only=None, init=None, bus=None):
+ if bus is None:
+ bus = Interface()
+ self.bus = bus
+ bus_data_width = flen(self.bus.dat_r)
if isinstance(mem_or_size, Memory):
- assert(mem_or_size.width <= 32)
+ assert(mem_or_size.width <= bus_data_width)
mem = mem_or_size
else:
- mem = Memory(32, mem_or_size//4, init=init)
+ mem = Memory(bus_data_width, mem_or_size//(bus_data_width//8), init=init)
if read_only is None:
if hasattr(mem, "bus_read_only"):
read_only = mem.bus_read_only
else:
read_only = False
- if bus is None:
- bus = Interface()
- self.bus = bus
###
View
19 migen/bus/wishbone2lasmi.py
@@ -6,19 +6,22 @@
# cachesize (in 32-bit words) is the size of the data store, must be a power of 2
class WB2LASMI(Module):
- def __init__(self, cachesize, lasmim):
- self.wishbone = wishbone.Interface()
+ def __init__(self, cachesize, lasmim, wbm=None):
+ if wbm is None:
+ wbm = wishbone.Interface()
+ self.wishbone = wbm
###
- if lasmim.dw < 32:
- raise ValueError("LASMI data width must be >= 32")
- if (lasmim.dw % 32) != 0:
- raise ValueError("LASMI data width must be a multiple of 32")
+ data_width = flen(self.wishbone.dat_r)
+ if lasmim.dw < data_width:
+ raise ValueError("LASMI data width must be >= {dw}".format(dw=data_width))
+ if (lasmim.dw % data_width) != 0:
+ raise ValueError("LASMI data width must be a multiple of {dw}".format(dw=data_width))
# Split address:
# TAG | LINE NUMBER | LINE OFFSET
- offsetbits = log2_int(lasmim.dw//32)
+ offsetbits = log2_int(lasmim.dw//data_width)
addressbits = lasmim.aw + offsetbits
linebits = log2_int(cachesize) - offsetbits
tagbits = addressbits - linebits
@@ -43,7 +46,7 @@ def __init__(self, cachesize, lasmim):
data_port.dat_w.eq(lasmim.dat_r),
data_port.we.eq(Replicate(1, lasmim.dw//8))
).Else(
- data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//32)),
+ data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//data_width)),
If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack,
displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
)

No commit comments for this range

Something went wrong with that request. Please try again.