Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a653a6144b0c
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: dac10f557061
Choose a head ref
  • 4 commits
  • 2 files changed
  • 2 contributors

Commits on Aug 26, 2013

  1. wishbone : add DownConverter

    enjoy-digital authored and Sebastien Bourdeauducq committed Aug 26, 2013
    Copy the full SHA
    628fa8c View commit details
  2. wishbone2lasmi: configurable data width

    enjoy-digital authored and Sebastien Bourdeauducq committed Aug 26, 2013
    Copy the full SHA
    33ca4d7 View commit details
  3. wishbone/SRAM: fix non-32-bit bus

    Sebastien Bourdeauducq committed Aug 26, 2013
    Copy the full SHA
    2cf6b6c View commit details
  4. bus/wb2lasmi: use existing interface to determine WB width to be cons…

    …istent with other modules
    Sebastien Bourdeauducq committed Aug 26, 2013
    Copy the full SHA
    dac10f5 View commit details
Showing with 108 additions and 14 deletions.
  1. +97 −6 migen/bus/wishbone.py
  2. +11 −8 migen/bus/wishbone2lasmi.py
103 changes: 97 additions & 6 deletions migen/bus/wishbone.py
Original file line number Diff line number Diff line change
@@ -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

###

19 changes: 11 additions & 8 deletions migen/bus/wishbone2lasmi.py
Original file line number Diff line number Diff line change
@@ -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)
)