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 commit comments