Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

bus/csr: support memories with larger word width than the bus (read o…

…nly)
  • Loading branch information...
commit 9b4ca987e04591d5e865fe0797566b4d114f2134 1 parent bb5ee8d
Sébastien Bourdeauducq authored March 03, 2013

Showing 1 changed file with 31 additions and 15 deletions. Show diff stats Hide diff stats

  1. 46  migen/bus/csr.py
46  migen/bus/csr.py
@@ -4,6 +4,7 @@
4 4
 from migen.bus.transactions import *
5 5
 from migen.sim.generic import PureSimulable
6 6
 from migen.bank.description import RegisterField
  7
+from migen.genlib.misc import chooser
7 8
 
8 9
 data_width = 8
9 10
 
@@ -55,12 +56,17 @@ def _compute_page_bits(nwords):
55 56
 class SRAM:
56 57
 	def __init__(self, mem_or_size, address, bus=None):
57 58
 		if isinstance(mem_or_size, Memory):
58  
-			assert(mem_or_size.width <= data_width)
59 59
 			self.mem = mem_or_size
60 60
 		else:
61 61
 			self.mem = Memory(data_width, mem_or_size//(data_width//8))
62 62
 		self.address = address
63  
-		page_bits = _compute_page_bits(self.mem.depth)
  63
+		if self.mem.width > data_width:
  64
+			self.csrw_per_memw = (self.mem.width + data_width - 1)//data_width
  65
+			self.word_bits = bits_for(self.csrw_per_memw-1)
  66
+		else:
  67
+			self.csrw_per_memw = 1
  68
+			self.word_bits = 0
  69
+		page_bits = _compute_page_bits(self.mem.depth + self.word_bits)
64 70
 		if page_bits:
65 71
 			self._page = RegisterField(self.mem.name_override + "_page", page_bits)
66 72
 		else:
@@ -76,26 +82,36 @@ def get_registers(self):
76 82
 			return [self._page]
77 83
 	
78 84
 	def get_fragment(self):
79  
-		port = self.mem.get_port(write_capable=True)
  85
+		port = self.mem.get_port(write_capable=not self.word_bits)
80 86
 		
81 87
 		sel = Signal()
82 88
 		sel_r = Signal()
83 89
 		sync = [sel_r.eq(sel)]
84  
-		
85  
-		comb = [
86  
-			sel.eq(self.bus.adr[9:] == self.address),
87  
-			port.we.eq(sel & self.bus.we),
88  
-			
89  
-			port.dat_w.eq(self.bus.dat_w),
90  
-			If(sel_r,
91  
-				self.bus.dat_r.eq(port.dat_r)
92  
-			)
93  
-		]
  90
+		comb = [sel.eq(self.bus.adr[9:] == self.address)]
  91
+
  92
+		if self.word_bits:
  93
+			word_index = Signal(self.word_bits)
  94
+			word_expanded = Signal(self.csrw_per_memw*data_width)
  95
+			sync.append(word_index.eq(self.bus.adr[:self.word_bits]))
  96
+			comb += [
  97
+				word_expanded.eq(port.dat_r),
  98
+				If(sel_r,
  99
+					chooser(word_expanded, word_index, self.bus.dat_r, n=self.csrw_per_memw, reverse=True)
  100
+				)
  101
+			]
  102
+		else:
  103
+			comb += [
  104
+				port.we.eq(sel & self.bus.we),
  105
+				port.dat_w.eq(self.bus.dat_w),
  106
+				If(sel_r,
  107
+					self.bus.dat_r.eq(port.dat_r)
  108
+				)
  109
+			]
94 110
 		
95 111
 		if self._page is None:
96  
-			comb.append(port.adr.eq(self.bus.adr[:len(port.adr)]))
  112
+			comb.append(port.adr.eq(self.bus.adr[self.word_bits:len(port.adr)]))
97 113
 		else:
98 114
 			pv = self._page.field.r
99  
-			comb.append(port.adr.eq(Cat(self.bus.adr[:len(port.adr)-len(pv)], pv)))
  115
+			comb.append(port.adr.eq(Cat(self.bus.adr[self.word_bits:len(port.adr)-len(pv)], pv)))
100 116
 		
101 117
 		return Fragment(comb, sync, specials={self.mem})

0 notes on commit 9b4ca98

Please sign in to comment.
Something went wrong with that request. Please try again.