1
1
from migen .fhdl .structure import *
2
+ from migen .fhdl .module import Module
2
3
from migen .bus .asmibus import *
3
4
from migen .genlib .roundrobin import *
4
5
from migen .genlib .fsm import FSM
@@ -33,97 +34,81 @@ def col(self, address):
33
34
else :
34
35
return Cat (Replicate (0 , self .address_align ), address [:self ._b1 ])
35
36
36
- class _Selector :
37
+ class _Selector ( Module ) :
37
38
def __init__ (self , slicer , bankn , slots ):
38
- self .slicer = slicer
39
- self .bankn = bankn
40
- self .slots = slots
41
-
42
- self .nslots = len (self .slots )
39
+ nslots = len (slots )
43
40
self .stb = Signal ()
44
41
self .ack = Signal ()
45
- self .tag = Signal (max = self . nslots )
46
- self .adr = Signal (self . slots [0 ].adr .nbits )
42
+ self .tag = Signal (max = nslots )
43
+ self .adr = Signal (slots [0 ].adr .nbits )
47
44
self .we = Signal ()
48
45
49
46
# derived classes should drive rr.request
50
- self .rr = RoundRobin (self . nslots , SP_CE )
47
+ self .submodules . rr = RoundRobin (nslots , SP_CE )
51
48
52
- def get_fragment (self ):
53
- comb = []
54
- rr = self .rr
55
-
49
+ ###
50
+
56
51
# Multiplex
52
+ rr = self .rr
57
53
state = Signal (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 ]),
54
+ self . comb += [
55
+ state .eq (Array (slot .state for slot in slots )[rr .grant ]),
56
+ self .adr .eq (Array (slot .adr for slot in slots )[rr .grant ]),
57
+ self .we .eq (Array (slot .we for slot in slots )[rr .grant ]),
62
58
self .stb .eq (
63
- (self . slicer .bank (self .adr ) == self . bankn ) \
59
+ (slicer .bank (self .adr ) == bankn ) \
64
60
& (state == SLOT_PENDING )),
65
61
rr .ce .eq (self .ack | ~ self .stb ),
66
62
self .tag .eq (rr .grant )
67
63
]
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 ( )
64
+ self . comb += [If ((rr .grant == i ) & self .stb & self .ack , slot .process .eq (1 ))
65
+ for i , slot in enumerate (slots )]
66
+
67
+ self . complete_selector ( slicer , bankn , slots )
72
68
73
69
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 ) + _Selector .get_fragment (self )
70
+ def complete_selector (self , slicer , bankn , slots ):
71
+ for i , slot in enumerate (slots ):
72
+ self .comb += self .rr .request [i ].eq (
73
+ (slicer .bank (slot .adr ) == bankn ) & \
74
+ (slot .state == SLOT_PENDING ))
83
75
84
76
class _FullSelector (_Selector ):
85
- def get_fragment (self ):
86
- comb = []
87
- sync = []
77
+ def complete_selector (self , slicer , bankn , slots ):
88
78
rr = self .rr
89
79
90
80
# List outstanding requests for our bank
91
81
outstandings = []
92
- for slot in self . slots :
82
+ for slot in slots :
93
83
outstanding = Signal ()
94
- comb .append (outstanding .eq (
95
- (self .slicer .bank (slot .adr ) == self .bankn ) & \
96
- (slot .state == SLOT_PENDING )
97
- ))
84
+ self .comb += outstanding .eq (
85
+ (slicer .bank (slot .adr ) == bankn ) & \
86
+ (slot .state == SLOT_PENDING ))
98
87
outstandings .append (outstanding )
99
88
100
89
# Row tracking
101
- openrow_r = Signal (self . slicer .geom_settings .row_a )
102
- openrow_n = Signal (self . slicer .geom_settings .row_a )
103
- openrow = Signal (self . slicer .geom_settings .row_a )
104
- comb += [
105
- openrow_n .eq (self . slicer .row (self .adr )),
90
+ openrow_r = Signal (slicer .geom_settings .row_a )
91
+ openrow_n = Signal (slicer .geom_settings .row_a )
92
+ openrow = Signal (slicer .geom_settings .row_a )
93
+ self . comb += [
94
+ openrow_n .eq (slicer .row (self .adr )),
106
95
If (self .stb ,
107
96
openrow .eq (openrow_n )
108
97
).Else (
109
98
openrow .eq (openrow_r )
110
99
)
111
100
]
112
- sync += [
113
- If (self .stb & self .ack ,
114
- openrow_r .eq (openrow_n )
115
- )
116
- ]
101
+ self .sync += If (self .stb & self .ack , openrow_r .eq (openrow_n ))
117
102
hits = []
118
- for slot , os in zip (self . slots , outstandings ):
103
+ for slot , os in zip (slots , outstandings ):
119
104
hit = Signal ()
120
- comb . append ( hit .eq ((self . slicer .row (slot .adr ) == openrow ) & os ) )
105
+ self . comb += hit .eq ((slicer .row (slot .adr ) == openrow ) & os )
121
106
hits .append (hit )
122
107
123
108
# Determine best request
124
109
rr = RoundRobin (self .nslots , SP_CE )
125
110
has_hit = Signal ()
126
- comb . append ( has_hit .eq (optree ("|" , hits ) ))
111
+ self . comb += has_hit .eq (optree ("|" , hits ))
127
112
128
113
best_hit = [rr .request [i ].eq (hit )
129
114
for i , hit in enumerate (hits )]
@@ -135,84 +120,72 @@ def get_fragment(self):
135
120
* best_fallback
136
121
)
137
122
138
- if self . slots [0 ].time :
123
+ if slots [0 ].time :
139
124
# Implement anti-starvation timer
140
125
matures = []
141
- for slot , os in zip (self . slots , outstandings ):
126
+ for slot , os in zip (slots , outstandings ):
142
127
mature = Signal ()
143
128
comb .append (mature .eq (slot .mature & os ))
144
129
matures .append (mature )
145
130
has_mature = Signal ()
146
- comb . append ( has_mature .eq (optree ("|" , matures ) ))
131
+ self . comb += has_mature .eq (optree ("|" , matures ))
147
132
best_mature = [rr .request [i ].eq (mature )
148
133
for i , mature in enumerate (matures )]
149
134
select_stmt = If (has_mature , * best_mature ).Else (select_stmt )
150
- comb .append (select_stmt )
151
-
152
- return Fragment (comb , sync ) + _Selector .get_fragment (self )
135
+ self .comb += select_stmt
153
136
154
- class _Buffer :
137
+ class _Buffer ( Module ) :
155
138
def __init__ (self , source ):
156
- self .source = source
157
-
158
139
self .stb = Signal ()
159
140
self .ack = Signal ()
160
- self .tag = Signal (self . source .tag .bv )
161
- self .adr = Signal (self . source .adr .bv )
141
+ self .tag = Signal (source .tag .bv )
142
+ self .adr = Signal (source .adr .bv )
162
143
self .we = Signal ()
163
144
164
- def get_fragment (self ):
145
+ ###
146
+
165
147
en = Signal ()
166
- comb = [
148
+ self . comb + = [
167
149
en .eq (self .ack | ~ self .stb ),
168
- self . source .ack .eq (en )
150
+ source .ack .eq (en )
169
151
]
170
- sync = [
152
+ self . sync + = [
171
153
If (en ,
172
- self .stb .eq (self . source .stb ),
173
- self .tag .eq (self . source .tag ),
174
- self .adr .eq (self . source .adr ),
175
- self .we .eq (self . source .we )
154
+ self .stb .eq (source .stb ),
155
+ self .tag .eq (source .tag ),
156
+ self .adr .eq (source .adr ),
157
+ self .we .eq (source .we )
176
158
)
177
159
]
178
- return Fragment (comb , sync )
179
160
180
- class BankMachine :
161
+ class BankMachine ( Module ) :
181
162
def __init__ (self , geom_settings , timing_settings , address_align , bankn , slots , full_selector ):
182
- self .geom_settings = geom_settings
183
- self .timing_settings = timing_settings
184
- self .address_align = address_align
185
- self .bankn = bankn
186
- self .slots = slots
187
- self .full_selector = full_selector
188
-
189
163
self .refresh_req = Signal ()
190
164
self .refresh_gnt = Signal ()
191
165
self .cmd = CommandRequestRW (geom_settings .mux_a , geom_settings .bank_a ,
192
166
bits_for (len (slots )- 1 ))
193
167
194
- def get_fragment (self ):
195
- comb = []
196
- sync = []
197
-
168
+ ###
169
+
198
170
# Sub components
199
- slicer = _AddressSlicer (self . geom_settings , self . address_align )
200
- if self . full_selector :
201
- selector = _FullSelector (slicer , self . bankn , self . slots )
202
- buf = _Buffer (selector )
203
- cmdsource = buf
171
+ slicer = _AddressSlicer (geom_settings , address_align )
172
+ if full_selector :
173
+ selector = _FullSelector (slicer , bankn , slots )
174
+ self . submodules . buf = _Buffer (selector )
175
+ cmdsource = self . buf
204
176
else :
205
- selector = _SimpleSelector (slicer , self . bankn , self . slots )
177
+ selector = _SimpleSelector (slicer , bankn , slots )
206
178
cmdsource = selector
179
+ self .submodules += selector
207
180
208
181
# Row tracking
209
182
has_openrow = Signal ()
210
- openrow = Signal (self . geom_settings .row_a )
183
+ openrow = Signal (geom_settings .row_a )
211
184
hit = Signal ()
212
- comb . append ( hit .eq (openrow == slicer .row (cmdsource .adr ) ))
185
+ self . comb += hit .eq (openrow == slicer .row (cmdsource .adr ))
213
186
track_open = Signal ()
214
187
track_close = Signal ()
215
- sync += [
188
+ self . sync += [
216
189
If (track_open ,
217
190
has_openrow .eq (1 ),
218
191
openrow .eq (slicer .row (cmdsource .adr ))
@@ -224,23 +197,23 @@ def get_fragment(self):
224
197
225
198
# Address generation
226
199
s_row_adr = Signal ()
227
- comb += [
228
- self .cmd .ba .eq (self . bankn ),
200
+ self . comb += [
201
+ self .cmd .ba .eq (bankn ),
229
202
If (s_row_adr ,
230
203
self .cmd .a .eq (slicer .row (cmdsource .adr ))
231
204
).Else (
232
205
self .cmd .a .eq (slicer .col (cmdsource .adr ))
233
206
)
234
207
]
235
208
236
- comb . append ( self .cmd .tag .eq (cmdsource .tag ) )
209
+ self . comb += self .cmd .tag .eq (cmdsource .tag )
237
210
238
211
# Respect write-to-precharge specification
239
212
precharge_ok = Signal ()
240
- t_unsafe_precharge = 2 + self . timing_settings .tWR - 1
213
+ t_unsafe_precharge = 2 + timing_settings .tWR - 1
241
214
unsafe_precharge_count = Signal (max = t_unsafe_precharge + 1 )
242
- comb . append ( precharge_ok .eq (unsafe_precharge_count == 0 ) )
243
- sync += [
215
+ self . comb += precharge_ok .eq (unsafe_precharge_count == 0 )
216
+ self . sync += [
244
217
If (self .cmd .stb & self .cmd .ack & self .cmd .is_write ,
245
218
unsafe_precharge_count .eq (t_unsafe_precharge )
246
219
).Elif (~ precharge_ok ,
@@ -250,9 +223,10 @@ def get_fragment(self):
250
223
251
224
# Control and command generation FSM
252
225
fsm = FSM ("REGULAR" , "PRECHARGE" , "ACTIVATE" , "REFRESH" , delayed_enters = [
253
- ("TRP" , "ACTIVATE" , self . timing_settings .tRP - 1 ),
254
- ("TRCD" , "REGULAR" , self . timing_settings .tRCD - 1 )
226
+ ("TRP" , "ACTIVATE" , timing_settings .tRP - 1 ),
227
+ ("TRCD" , "REGULAR" , timing_settings .tRCD - 1 )
255
228
])
229
+ self .submodules += fsm
256
230
fsm .act (fsm .REGULAR ,
257
231
If (self .refresh_req ,
258
232
fsm .next_state (fsm .REFRESH )
@@ -298,12 +272,3 @@ def get_fragment(self):
298
272
track_close .eq (1 ),
299
273
If (~ self .refresh_req , fsm .next_state (fsm .REGULAR ))
300
274
)
301
-
302
- if self .full_selector :
303
- buf_fragment = buf .get_fragment ()
304
- else :
305
- buf_fragment = Fragment ()
306
- return Fragment (comb , sync ) + \
307
- selector .get_fragment () + \
308
- buf_fragment + \
309
- fsm .get_fragment ()
0 commit comments