@@ -46,9 +46,46 @@ def __init__(self, slicer, bankn, slots):
46
46
self .adr = Signal (self .slots [0 ].adr .bv )
47
47
self .we = Signal ()
48
48
49
+ # derived classes should drive rr.request
50
+ self .rr = RoundRobin (self .nslots , SP_CE )
51
+
52
+ def get_fragment (self ):
53
+ comb = []
54
+ rr = self .rr
55
+
56
+ # Multiplex
57
+ state = Signal (BV (2 ))
58
+ comb += [
59
+ state .eq (Array (slot .state for slot in self .slots )[rr .grant ]),
60
+ self .adr .eq (Array (slot .adr for slot in self .slots )[rr .grant ]),
61
+ self .we .eq (Array (slot .we for slot in self .slots )[rr .grant ]),
62
+ self .stb .eq (
63
+ (self .slicer .bank (self .adr ) == self .bankn ) \
64
+ & (state == SLOT_PENDING )),
65
+ rr .ce .eq (self .ack ),
66
+ self .tag .eq (rr .grant )
67
+ ]
68
+ comb += [If ((rr .grant == i ) & self .stb & self .ack , slot .process .eq (1 ))
69
+ for i , slot in enumerate (self .slots )]
70
+
71
+ return Fragment (comb ) + rr .get_fragment ()
72
+
73
+ class _SimpleSelector (_Selector ):
74
+ def get_fragment (self ):
75
+ comb = []
76
+ for i , slot in enumerate (self .slots ):
77
+ comb .append (self .rr .request [i ].eq (
78
+ (self .slicer .bank (slot .adr ) == self .bankn ) & \
79
+ (slot .state == SLOT_PENDING )
80
+ ))
81
+
82
+ return Fragment (comb ) + super ().get_fragment ()
83
+
84
+ class _FullSelector (_Selector ):
49
85
def get_fragment (self ):
50
86
comb = []
51
87
sync = []
88
+ rr = self .rr
52
89
53
90
# List outstanding requests for our bank
54
91
outstandings = []
@@ -112,22 +149,7 @@ def get_fragment(self):
112
149
select_stmt = If (has_mature , * best_mature ).Else (select_stmt )
113
150
comb .append (select_stmt )
114
151
115
- # Multiplex
116
- state = Signal (BV (2 ))
117
- comb += [
118
- state .eq (Array (slot .state for slot in self .slots )[rr .grant ]),
119
- self .adr .eq (Array (slot .adr for slot in self .slots )[rr .grant ]),
120
- self .we .eq (Array (slot .we for slot in self .slots )[rr .grant ]),
121
- self .stb .eq (
122
- (self .slicer .bank (self .adr ) == self .bankn ) \
123
- & (state == SLOT_PENDING )),
124
- rr .ce .eq (self .ack ),
125
- self .tag .eq (rr .grant )
126
- ]
127
- comb += [If ((rr .grant == i ) & self .stb & self .ack , slot .process .eq (1 ))
128
- for i , slot in enumerate (self .slots )]
129
-
130
- return Fragment (comb , sync ) + rr .get_fragment ()
152
+ return Fragment (comb , sync ) + super ().get_fragment ()
131
153
132
154
class _Buffer :
133
155
def __init__ (self , source ):
@@ -156,12 +178,13 @@ def get_fragment(self):
156
178
return Fragment (comb , sync )
157
179
158
180
class BankMachine :
159
- def __init__ (self , geom_settings , timing_settings , address_align , bankn , slots ):
181
+ def __init__ (self , geom_settings , timing_settings , address_align , bankn , slots , full_selector = False ):
160
182
self .geom_settings = geom_settings
161
183
self .timing_settings = timing_settings
162
184
self .address_align = address_align
163
185
self .bankn = bankn
164
186
self .slots = slots
187
+ self .full_selector = full_selector
165
188
166
189
self .refresh_req = Signal ()
167
190
self .refresh_gnt = Signal ()
@@ -174,7 +197,10 @@ def get_fragment(self):
174
197
175
198
# Sub components
176
199
slicer = _AddressSlicer (self .geom_settings , self .address_align )
177
- selector = _Selector (slicer , self .bankn , self .slots )
200
+ if self .full_selector :
201
+ selector = _FullSelector (slicer , self .bankn , self .slots )
202
+ else :
203
+ selector = _SimpleSelector (slicer , self .bankn , self .slots )
178
204
buf = _Buffer (selector )
179
205
180
206
# Row tracking
0 commit comments