Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 4 commits
  • 2 files changed
  • 0 comments
  • 2 contributors
103  migen/bus/wishbone.py
... ...
@@ -1,7 +1,8 @@
1 1
 from migen.fhdl.std import *
2 2
 from migen.genlib import roundrobin
3 3
 from migen.genlib.record import *
4  
-from migen.genlib.misc import optree
  4
+from migen.genlib.misc import optree, chooser
  5
+from migen.genlib.fsm import FSM, NextState
5 6
 from migen.bus.transactions import *
6 7
 from migen.sim.generic import Proxy
7 8
 
@@ -111,6 +112,95 @@ def __init__(self, masters, slaves, register=False):
111 112
 		for column, bus in zip(zip(*access), busses):
112 113
 			self.submodules += Arbiter(column, bus)
113 114
 
  115
+class DownConverter(Module):
  116
+	# DownConverter splits Wishbone accesses of N bits in M accesses of L bits where:
  117
+	# N is the original data-width
  118
+	# L is the target data-width
  119
+	# M = N/L
  120
+	def __init__(self, dw_i, dw_o):
  121
+
  122
+		self.wishbone_i = Interface(dw_i)
  123
+		self.wishbone_o = Interface(dw_o)
  124
+		self.ratio = dw_i//dw_o
  125
+
  126
+		###
  127
+		
  128
+		rst = Signal()
  129
+
  130
+		# generate internal write and read ack
  131
+		write_ack = Signal()
  132
+		read_ack = Signal()
  133
+		ack = Signal()
  134
+		self.comb += [
  135
+			ack.eq(self.wishbone_o.cyc & self.wishbone_o.stb & self.wishbone_o.ack),
  136
+			write_ack.eq(ack & self.wishbone_o.we),
  137
+			read_ack.eq(ack & ~self.wishbone_o.we)
  138
+		]
  139
+		
  140
+		# accesses counter logic
  141
+		cnt = Signal(max=self.ratio)
  142
+		self.sync += If(rst, cnt.eq(0)).Elif(ack, cnt.eq(cnt + 1))
  143
+		
  144
+		# read data path
  145
+		dat_r = Signal(dw_i)
  146
+		self.sync += If(ack, dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o])))
  147
+		
  148
+		# write data path
  149
+		dat_w = Signal(dw_i)
  150
+		self.comb += dat_w.eq(self.wishbone_i.dat_w)
  151
+		
  152
+		# errors generation
  153
+		err = Signal()
  154
+		self.sync += If(ack, err.eq(self.wishbone_o.err))
  155
+		
  156
+		# direct connection of wishbone_i --> wishbone_o signals
  157
+		for name, size, direction in self.wishbone_i.layout:
  158
+			if direction == DIR_M_TO_S and name not in ["adr", "dat_w"]:
  159
+				self.comb += getattr(self.wishbone_o, name).eq(getattr(self.wishbone_i, name))
  160
+		
  161
+		# adaptation of adr & dat signals
  162
+		self.comb += [
  163
+			self.wishbone_o.adr[0:flen(cnt)].eq(cnt),
  164
+			self.wishbone_o.adr[flen(cnt):].eq(self.wishbone_i.adr)
  165
+		]
  166
+		
  167
+		self.comb += chooser(dat_w, cnt, self.wishbone_o.dat_w, reverse=True)
  168
+		
  169
+		# fsm
  170
+		fsm = FSM(reset_state="IDLE")
  171
+		self.submodules += fsm
  172
+		
  173
+		fsm.act("IDLE",
  174
+			If(write_ack,
  175
+				NextState("WRITE_ADAPT")
  176
+			),
  177
+			If(read_ack,
  178
+				NextState("READ_ADAPT")
  179
+			)
  180
+		)
  181
+		
  182
+		fsm.act("WRITE_ADAPT",
  183
+			If(write_ack & (cnt == self.ratio-1),
  184
+				NextState("IDLE"),
  185
+				rst.eq(1),
  186
+				self.wishbone_i.err.eq(err | self.wishbone_o.err),
  187
+				self.wishbone_i.ack.eq(1),
  188
+			)
  189
+		)
  190
+		
  191
+		master_i_dat_r = Signal(dw_i)
  192
+		self.comb += master_i_dat_r.eq(Cat(self.wishbone_o.dat_r, dat_r[:dw_i-dw_o]))
  193
+
  194
+		fsm.act("READ_ADAPT",
  195
+			If(read_ack & (cnt == self.ratio-1),
  196
+				NextState("IDLE"),
  197
+				rst.eq(1),
  198
+				self.wishbone_i.err.eq(err | self.wishbone_o.err),
  199
+				self.wishbone_i.ack.eq(1),
  200
+				self.wishbone_i.dat_r.eq(master_i_dat_r)
  201
+			)
  202
+		)
  203
+
114 204
 class Tap(Module):
115 205
 	def __init__(self, bus, handler=print):
116 206
 		self.bus = bus
@@ -196,19 +286,20 @@ def do_simulation(self, s):
196 286
 
197 287
 class SRAM(Module):
198 288
 	def __init__(self, mem_or_size, read_only=None, init=None, bus=None):
  289
+		if bus is None:
  290
+			bus = Interface()
  291
+		self.bus = bus
  292
+		bus_data_width = flen(self.bus.dat_r)
199 293
 		if isinstance(mem_or_size, Memory):
200  
-			assert(mem_or_size.width <= 32)
  294
+			assert(mem_or_size.width <= bus_data_width)
201 295
 			mem = mem_or_size
202 296
 		else:
203  
-			mem = Memory(32, mem_or_size//4, init=init)
  297
+			mem = Memory(bus_data_width, mem_or_size//(bus_data_width//8), init=init)
204 298
 		if read_only is None:
205 299
 			if hasattr(mem, "bus_read_only"):
206 300
 				read_only = mem.bus_read_only
207 301
 			else:
208 302
 				read_only = False
209  
-		if bus is None:
210  
-			bus = Interface()
211  
-		self.bus = bus
212 303
 	
213 304
 		###
214 305
 	
19  migen/bus/wishbone2lasmi.py
@@ -6,19 +6,22 @@
6 6
 
7 7
 # cachesize (in 32-bit words) is the size of the data store, must be a power of 2
8 8
 class WB2LASMI(Module):
9  
-	def __init__(self, cachesize, lasmim):
10  
-		self.wishbone = wishbone.Interface()
  9
+	def __init__(self, cachesize, lasmim, wbm=None):
  10
+		if wbm is None:
  11
+			wbm = wishbone.Interface()
  12
+		self.wishbone = wbm
11 13
 
12 14
 		###
13 15
 
14  
-		if lasmim.dw < 32:
15  
-			raise ValueError("LASMI data width must be >= 32")
16  
-		if (lasmim.dw % 32) != 0:
17  
-			raise ValueError("LASMI data width must be a multiple of 32")
  16
+		data_width = flen(self.wishbone.dat_r)
  17
+		if lasmim.dw < data_width:
  18
+			raise ValueError("LASMI data width must be >= {dw}".format(dw=data_width))
  19
+		if (lasmim.dw % data_width) != 0:
  20
+			raise ValueError("LASMI data width must be a multiple of {dw}".format(dw=data_width))
18 21
 
19 22
 		# Split address:
20 23
 		# TAG | LINE NUMBER | LINE OFFSET
21  
-		offsetbits = log2_int(lasmim.dw//32)
  24
+		offsetbits = log2_int(lasmim.dw//data_width)
22 25
 		addressbits = lasmim.aw + offsetbits
23 26
 		linebits = log2_int(cachesize) - offsetbits
24 27
 		tagbits = addressbits - linebits
@@ -43,7 +46,7 @@ def __init__(self, cachesize, lasmim):
43 46
 				data_port.dat_w.eq(lasmim.dat_r),
44 47
 				data_port.we.eq(Replicate(1, lasmim.dw//8))
45 48
 			).Else(
46  
-				data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//32)),
  49
+				data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//data_width)),
47 50
 				If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack,
48 51
 					displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
49 52
 				)

No commit comments for this range

Something went wrong with that request. Please try again.