@@ -129,10 +129,14 @@ def __init__(self, layout, n):
129
129
130
130
131
131
class _UpConverter (Module ):
132
- def __init__ (self , nbits_from , nbits_to , ratio , reverse ):
132
+ def __init__ (self , nbits_from , nbits_to , ratio , reverse ,
133
+ report_valid_token_count ):
133
134
self .sink = sink = Endpoint ([("data" , nbits_from )])
134
- self .source = source = Endpoint ([("data" , nbits_to ),
135
- ("valid_token_count" , bits_for (ratio ))])
135
+ source_layout = [("data" , nbits_to )]
136
+ if report_valid_token_count :
137
+ source_layout .append (("valid_token_count" , bits_for (ratio )))
138
+ self .source = source = Endpoint (source_layout )
139
+ self .ratio = ratio
136
140
137
141
# # #
138
142
@@ -172,15 +176,19 @@ def __init__(self, nbits_from, nbits_to, ratio, reverse):
172
176
cases [i ] = source .data [n * nbits_from :(n + 1 )* nbits_from ].eq (sink .data )
173
177
self .sync += If (load_part , Case (demux , cases ))
174
178
175
- # valid token count
176
- self .sync += If (load_part , source .valid_token_count .eq (demux + 1 ))
179
+ if report_valid_token_count :
180
+ self .sync += If (load_part , source .valid_token_count .eq (demux + 1 ))
177
181
178
182
179
183
class _DownConverter (Module ):
180
- def __init__ (self , nbits_from , nbits_to , ratio , reverse ):
184
+ def __init__ (self , nbits_from , nbits_to , ratio , reverse ,
185
+ report_valid_token_count ):
181
186
self .sink = sink = Endpoint ([("data" , nbits_from )])
182
- self .source = source = Endpoint ([("data" , nbits_to ),
183
- ("valid_token_count" , 1 )])
187
+ source_layout = [("data" , nbits_to )]
188
+ if report_valid_token_count :
189
+ source_layout .append (("valid_token_count" , 1 ))
190
+ self .source = source = Endpoint (source_layout )
191
+ self .ratio = ratio
184
192
185
193
# # #
186
194
@@ -209,63 +217,58 @@ def __init__(self, nbits_from, nbits_to, ratio, reverse):
209
217
cases [i ] = source .data .eq (sink .data [n * nbits_to :(n + 1 )* nbits_to ])
210
218
self .comb += Case (mux , cases ).makedefault ()
211
219
212
- # valid token count
213
- self .comb += source .valid_token_count .eq (last )
220
+ if report_valid_token_count :
221
+ self .comb += source .valid_token_count .eq (last )
214
222
215
223
216
224
class _IdentityConverter (Module ):
217
- def __init__ (self , nbits_from , nbits_to , ratio , reverse ):
225
+ def __init__ (self , nbits_from , nbits_to , ratio , reverse ,
226
+ report_valid_token_count ):
218
227
self .sink = sink = Endpoint ([("data" , nbits_from )])
219
- self .source = source = Endpoint ([("data" , nbits_to ),
220
- ("valid_token_count" , 1 )])
228
+ source_layout = [("data" , nbits_to )]
229
+ if report_valid_token_count :
230
+ source_layout .append (("valid_token_count" , 1 ))
231
+ self .source = source = Endpoint (source_layout )
232
+ assert ratio == 1
233
+ self .ratio = ratio
221
234
222
235
# # #
223
236
224
- self .comb += [
225
- sink .connect (source ),
226
- source .valid_token_count .eq (1 )
227
- ]
237
+ self .comb += sink .connect (source )
238
+ if report_valid_token_count :
239
+ self .comb += source .valid_token_count .eq (1 )
228
240
229
241
230
242
def _get_converter_ratio (nbits_from , nbits_to ):
231
243
if nbits_from > nbits_to :
232
- converter_cls = _DownConverter
244
+ specialized_cls = _DownConverter
233
245
if nbits_from % nbits_to :
234
246
raise ValueError ("Ratio must be an int" )
235
247
ratio = nbits_from // nbits_to
236
248
elif nbits_from < nbits_to :
237
- converter_cls = _UpConverter
249
+ specialized_cls = _UpConverter
238
250
if nbits_to % nbits_from :
239
251
raise ValueError ("Ratio must be an int" )
240
252
ratio = nbits_to // nbits_from
241
253
else :
242
- converter_cls = _IdentityConverter
254
+ specialized_cls = _IdentityConverter
243
255
ratio = 1
244
256
245
- return converter_cls , ratio
257
+ return specialized_cls , ratio
246
258
247
259
248
260
class Converter (Module ):
249
261
def __init__ (self , nbits_from , nbits_to , reverse = False ,
250
- report_valid_token_count = False ):
251
- self .cls , self .ratio = _get_converter_ratio (nbits_from , nbits_to )
252
-
253
- # # #
254
-
255
- converter = self .cls (nbits_from , nbits_to , self .ratio , reverse )
256
- self .submodules += converter
257
-
258
- self .sink = converter .sink
259
- if report_valid_token_count :
260
- self .source = converter .source
261
- else :
262
- self .source = Endpoint ([("data" , nbits_to )])
263
- self .comb += converter .source .connect (self .source ,
264
- leave_out = set (["valid_token_count" ]))
262
+ report_valid_token_count = False ):
263
+ cls , ratio = _get_converter_ratio (nbits_from , nbits_to )
264
+ self .submodules .specialized = cls (nbits_from , nbits_to , ratio ,
265
+ reverse , report_valid_token_count )
266
+ self .sink = self .specialized .sink
267
+ self .source = self .specialized .source
265
268
266
269
267
270
class StrideConverter (Module ):
268
- def __init__ (self , layout_from , layout_to , reverse = False ):
271
+ def __init__ (self , layout_from , layout_to , * args , ** kwargs ):
269
272
self .sink = sink = Endpoint (layout_from )
270
273
self .source = source = Endpoint (layout_to )
271
274
@@ -274,7 +277,7 @@ def __init__(self, layout_from, layout_to, reverse=False):
274
277
nbits_from = len (sink .payload .raw_bits ())
275
278
nbits_to = len (source .payload .raw_bits ())
276
279
277
- converter = Converter (nbits_from , nbits_to , reverse )
280
+ converter = Converter (nbits_from , nbits_to , * args , ** kwargs )
278
281
self .submodules += converter
279
282
280
283
# cast sink to converter.sink (user fields --> raw bits)
@@ -283,8 +286,8 @@ def __init__(self, layout_from, layout_to, reverse=False):
283
286
converter .sink .eop .eq (sink .eop ),
284
287
sink .ack .eq (converter .sink .ack )
285
288
]
286
- if converter .cls == _DownConverter :
287
- ratio = converter .ratio
289
+ if isinstance ( converter .specialized , _DownConverter ) :
290
+ ratio = converter .specialized . ratio
288
291
for i in range (ratio ):
289
292
j = 0
290
293
for name , width in layout_to :
@@ -302,8 +305,8 @@ def __init__(self, layout_from, layout_to, reverse=False):
302
305
source .eop .eq (converter .source .eop ),
303
306
converter .source .ack .eq (source .ack )
304
307
]
305
- if converter .cls == _UpConverter :
306
- ratio = converter .ratio
308
+ if isinstance ( converter .specialized , _UpConverter ) :
309
+ ratio = converter .specialized . ratio
307
310
for i in range (ratio ):
308
311
j = 0
309
312
for name , width in layout_from :
0 commit comments