@@ -129,10 +129,10 @@ def __init__(self, layout, n):
129
129
130
130
131
131
class _UpConverter (Module ):
132
- def __init__ (self , layout_from , layout_to , ratio , reverse ):
133
- self .sink = sink = Endpoint (layout_from )
134
- self .source = source = Endpoint (layout_to )
135
- self .chunks = Signal (bits_for (ratio ))
132
+ def __init__ (self , nbits_from , nbits_to , ratio , reverse ):
133
+ self .sink = sink = Endpoint ([( "data" , nbits_from )] )
134
+ self .source = source = Endpoint ([( "data" , nbits_to )] )
135
+ self .valid_token_count = Signal (bits_for (ratio ))
Has conversations. Original line has conversations. 136
136
137
137
# # #
138
138
@@ -166,26 +166,21 @@ def __init__(self, layout_from, layout_to, ratio, reverse):
166
166
]
167
167
168
168
# data path
169
- source_payload_raw_bits = Signal (len (source .payload .raw_bits ()))
170
169
cases = {}
171
170
for i in range (ratio ):
172
171
n = ratio - i - 1 if reverse else i
173
- width = len (sink .payload .raw_bits ())
174
- src = sink .payload .raw_bits ()
175
- dst = source_payload_raw_bits [n * width :(n + 1 )* width ]
176
- cases [i ] = dst .eq (src )
172
+ cases [i ] = source .data [n * nbits_from :(n + 1 )* nbits_from ].eq (sink .data )
177
173
self .sync += If (load_part , Case (demux , cases ))
178
- self .comb += source .payload .raw_bits ().eq (source_payload_raw_bits )
179
174
180
- # chunks
181
- self .sync += If (load_part , self .chunks .eq (demux + 1 ))
175
+ # valid token count
176
+ self .sync += If (load_part , self .valid_token_count .eq (demux + 1 ))
182
177
183
178
184
179
class _DownConverter (Module ):
185
- def __init__ (self , layout_from , layout_to , ratio , reverse ):
186
- self .sink = sink = Endpoint (layout_from )
187
- self .source = source = Endpoint (layout_to )
188
- self .chunks = Signal ()
180
+ def __init__ (self , nbits_from , nbits_to , ratio , reverse ):
181
+ self .sink = sink = Endpoint ([( "data" , nbits_from )] )
182
+ self .source = source = Endpoint ([( "data" , nbits_to )] )
183
+ self .valid_token_count = Signal ()
189
184
190
185
# # #
191
186
@@ -208,49 +203,38 @@ def __init__(self, layout_from, layout_to, ratio, reverse):
208
203
)
209
204
210
205
# data path
211
- sink_payload_raw_bits = Signal (len (sink .payload .raw_bits ()))
212
- self .comb += sink_payload_raw_bits .eq (sink .payload .raw_bits ())
213
206
cases = {}
214
207
for i in range (ratio ):
215
208
n = ratio - i - 1 if reverse else i
216
- width = len (source .payload .raw_bits ())
217
- src = sink_payload_raw_bits [n * width :(n + 1 )* width ]
218
- dst = source .payload .raw_bits ()
219
- cases [i ] = dst .eq (src )
209
+ cases [i ] = source .data .eq (sink .data [n * nbits_to :(n + 1 )* nbits_to ])
220
210
self .comb += Case (mux , cases ).makedefault ()
221
211
222
- # chunks
223
- self .comb += self .chunks .eq (last )
212
+ # valid token count
213
+ self .comb += self .valid_token_count .eq (last )
224
214
225
215
226
216
class _IdentityConverter (Module ):
227
- def __init__ (self , layout_from , layout_to , ratio , reverse ):
228
- self .sink = sink = Endpoint (layout_from )
229
- self .source = source = Endpoint (layout_to )
230
- self .chunks = Signal ()
217
+ def __init__ (self , nbits_from , nbits_to , ratio , reverse ):
218
+ self .sink = sink = Endpoint ([( "data" , nbits_from )] )
219
+ self .source = source = Endpoint ([( "data" , nbits_to )] )
220
+ self .valid_token_count = Signal (reset = 1 )
231
221
232
222
# # #
233
223
234
- self .comb += [
235
- sink .connect (source ),
236
- self .chunks .eq (1 )
237
- ]
238
-
224
+ self .comb += sink .connect (source )
239
225
240
- def _get_converter_ratio (layout_from , layout_to ):
241
- width_from = len (Endpoint (layout_from ).payload .raw_bits ())
242
- width_to = len (Endpoint (layout_to ).payload .raw_bits ())
243
226
244
- if width_from > width_to :
227
+ def _get_converter_ratio (nbits_from , nbits_to ):
228
+ if nbits_from > nbits_to :
245
229
converter_cls = _DownConverter
246
- if width_from % width_to :
230
+ if nbits_from % nbits_to :
247
231
raise ValueError ("Ratio must be an int" )
248
- ratio = width_from // width_to
249
- elif width_from < width_to :
232
+ ratio = nbits_from // nbits_to
233
+ elif nbits_from < nbits_to :
250
234
converter_cls = _UpConverter
251
- if width_to % width_from :
235
+ if nbits_to % nbits_from :
252
236
raise ValueError ("Ratio must be an int" )
253
- ratio = width_to // width_from
237
+ ratio = nbits_to // nbits_from
254
238
else :
255
239
converter_cls = _IdentityConverter
256
240
ratio = 1
@@ -259,20 +243,21 @@ def _get_converter_ratio(layout_from, layout_to):
259
243
260
244
261
245
class Converter (Module ):
262
- def __init__ (self , layout_from , layout_to , reverse = False , insert_chunks = False ):
263
- self .cls , self .ratio = _get_converter_ratio (layout_from , layout_to )
246
+ def __init__ (self , nbits_from , nbits_to , reverse = False , report_valid_token_count = False ):
247
+ self .cls , self .ratio = _get_converter_ratio (nbits_from , nbits_to )
264
248
265
249
# # #
266
250
267
- converter = self .cls (layout_from , layout_to , self .ratio , reverse )
251
+ converter = self .cls (nbits_from , nbits_to , self .ratio , reverse )
268
252
self .submodules += converter
269
253
270
254
self .sink = converter .sink
271
- if insert_chunks :
272
- self .source = Endpoint (layout_to + [("chunks" , bits_for (self .ratio ))])
255
+ if report_valid_token_count :
256
+ self .source = Endpoint ([("data" , nbits_to ),
257
+ ("valid_token_count" , bits_for (self .ratio ))])
273
258
self .comb += [
274
259
converter .source .connect (self .source ),
275
- self .source .chunks .eq (converter .chunks )
260
+ self .source .valid_token_count .eq (converter .valid_token_count )
276
261
]
277
262
else :
278
263
self .source = converter .source
@@ -285,12 +270,10 @@ def __init__(self, layout_from, layout_to, reverse=False):
285
270
286
271
# # #
287
272
288
- width_from = len (sink .payload .raw_bits ())
289
- width_to = len (source .payload .raw_bits ())
273
+ nbits_from = len (sink .payload .raw_bits ())
274
+ nbits_to = len (source .payload .raw_bits ())
290
275
291
- converter = Converter ([("data" , width_from )],
292
- [("data" , width_to )],
293
- reverse )
276
+ converter = Converter (nbits_from , nbits_to , reverse )
294
277
self .submodules += converter
295
278
296
279
# cast sink to converter.sink (user fields --> raw bits)
@@ -305,7 +288,7 @@ def __init__(self, layout_from, layout_to, reverse=False):
305
288
j = 0
306
289
for name , width in layout_to :
307
290
src = getattr (sink , name )[i * width :(i + 1 )* width ]
308
- dst = converter .sink .data [i * width_to + j :i * width_to + j + width ]
291
+ dst = converter .sink .data [i * nbits_to + j :i * nbits_to + j + width ]
309
292
self .comb += dst .eq (src )
310
293
j += width
311
294
else :
@@ -323,7 +306,7 @@ def __init__(self, layout_from, layout_to, reverse=False):
323
306
for i in range (ratio ):
324
307
j = 0
325
308
for name , width in layout_from :
326
- src = converter .source .data [i * width_from + j :i * width_from + j + width ]
309
+ src = converter .source .data [i * nbits_from + j :i * nbits_from + j + width ]
327
310
dst = getattr (source , name )[i * width :(i + 1 )* width ]
328
311
self .comb += dst .eq (src )
329
312
j += width