Skip to content

Commit 9b4ca98

Browse files
author
Sebastien Bourdeauducq
committedMar 3, 2013
bus/csr: support memories with larger word width than the bus (read only)
1 parent bb5ee8d commit 9b4ca98

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed
 

‎migen/bus/csr.py

+31-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from migen.bus.transactions import *
55
from migen.sim.generic import PureSimulable
66
from migen.bank.description import RegisterField
7+
from migen.genlib.misc import chooser
78

89
data_width = 8
910

@@ -55,12 +56,17 @@ def _compute_page_bits(nwords):
5556
class SRAM:
5657
def __init__(self, mem_or_size, address, bus=None):
5758
if isinstance(mem_or_size, Memory):
58-
assert(mem_or_size.width <= data_width)
5959
self.mem = mem_or_size
6060
else:
6161
self.mem = Memory(data_width, mem_or_size//(data_width//8))
6262
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)
6470
if page_bits:
6571
self._page = RegisterField(self.mem.name_override + "_page", page_bits)
6672
else:
@@ -76,26 +82,36 @@ def get_registers(self):
7682
return [self._page]
7783

7884
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)
8086

8187
sel = Signal()
8288
sel_r = Signal()
8389
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+
]
94110

95111
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)]))
97113
else:
98114
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)))
100116

101117
return Fragment(comb, sync, specials={self.mem})

0 commit comments

Comments
 (0)
Please sign in to comment.