@@ -63,8 +63,8 @@ struct RunLengthDecoderState<SYMBOL_WIDTH: u32, COUNT_WIDTH: u32> {
63
63
}
64
64
// RLE decoder implementation
65
65
pub proc RunLengthDecoder<SYMBOL_WIDTH: u32, COUNT_WIDTH: u32> {
66
- input_r: chan<DecInData<SYMBOL_WIDTH, COUNT_WIDTH>> in;
67
- output_s: chan<DecOutData<SYMBOL_WIDTH>> out;
66
+ input_r: chan<DecInData<SYMBOL_WIDTH, COUNT_WIDTH, 1 >> in;
67
+ output_s: chan<DecOutData<SYMBOL_WIDTH, 1 >> out;
68
68
69
69
init {(
70
70
RunLengthDecoderState<SYMBOL_WIDTH, COUNT_WIDTH> {
@@ -75,34 +75,38 @@ pub proc RunLengthDecoder<SYMBOL_WIDTH: u32, COUNT_WIDTH: u32> {
75
75
)}
76
76
77
77
config (
78
- input_r: chan<DecInData<SYMBOL_WIDTH, COUNT_WIDTH>> in,
79
- output_s: chan<DecOutData<SYMBOL_WIDTH>> out,
78
+ input_r: chan<DecInData<SYMBOL_WIDTH, COUNT_WIDTH, 1 >> in,
79
+ output_s: chan<DecOutData<SYMBOL_WIDTH, 1 >> out,
80
80
) {(input_r, output_s)}
81
81
82
82
next (tok: token, state: RunLengthDecoderState<SYMBOL_WIDTH, COUNT_WIDTH>) {
83
83
let state_input = DecInData {
84
- symbol: state.symbol ,
85
- count: state.count ,
84
+ symbols: [ state.symbol] ,
85
+ counts: [ state.count] ,
86
86
last: state.last
87
87
};
88
88
let recv_next_symbol = (state.count == bits[COUNT_WIDTH]:0 );
89
89
let (tok, input) = recv_if (tok, input_r, recv_next_symbol, state_input);
90
- let next_count = if input.count == bits[COUNT_WIDTH]:0 {
91
- fail!( " invalid_count_0 " , input.count )
90
+ let next_count = if input.counts [ 0 ] == bits[COUNT_WIDTH]:0 {
91
+ input.counts [ 0 ]
92
92
} else {
93
- input.count - bits[COUNT_WIDTH]:1
93
+ input.counts [ 0 ] - bits[COUNT_WIDTH]:1
94
94
};
95
95
let done_sending = (next_count == bits[COUNT_WIDTH]:0 );
96
96
let send_last = input.last && done_sending;
97
- let data_tok = send (tok, output_s, DecOutData {
98
- symbol: input.symbol ,
99
- last: send_last
97
+ let symbol_valid = input.counts [0 ] > bits[COUNT_WIDTH]:0 ;
98
+ let data_tok = send_if (tok, output_s,
99
+ symbol_valid || send_last,
100
+ DecOutData {
101
+ symbols: [input.symbols[0 ]],
102
+ symbol_valids: [symbol_valid],
103
+ last: send_last
100
104
});
101
105
if (send_last) {
102
106
zero!<RunLengthDecoderState>()
103
107
} else {
104
108
RunLengthDecoderState {
105
- symbol: input.symbol ,
109
+ symbol: input.symbols [ 0 ] ,
106
110
count: next_count,
107
111
last: input.last ,
108
112
}
@@ -116,8 +120,8 @@ proc RunLengthDecoder32 {
116
120
init {()}
117
121
118
122
config (
119
- input_r: chan<DecInData<32 , 2 >> in,
120
- output_s: chan<DecOutData<32 >> out,
123
+ input_r: chan<DecInData<32 , 2 , 1 >> in,
124
+ output_s: chan<DecOutData<32 , 1 >> out,
121
125
) {
122
126
spawn RunLengthDecoder<u32:32 , u32:2 >(input_r, output_s);
123
127
()
@@ -136,8 +140,8 @@ const TEST_COUNT_WIDTH = u32:32;
136
140
type TestSymbol = bits[TEST_SYMBOL_WIDTH];
137
141
type TestCount = bits[TEST_COUNT_WIDTH];
138
142
type TestStimulus = (TestSymbol, TestCount);
139
- type TestDecInData = DecInData<TEST_SYMBOL_WIDTH, TEST_COUNT_WIDTH>;
140
- type TestDecOutData = DecOutData<TEST_SYMBOL_WIDTH>;
143
+ type TestDecInData = DecInData<TEST_SYMBOL_WIDTH, TEST_COUNT_WIDTH, 1 >;
144
+ type TestDecOutData = DecOutData<TEST_SYMBOL_WIDTH, 1 >;
141
145
142
146
// Check RLE decoder on a transaction
143
147
#[test_proc]
@@ -171,13 +175,13 @@ proc RunLengthDecoderTransactionTest {
171
175
in enumerate (TransactionTestStimuli) {
172
176
let last = counter == (array_size (TransactionTestStimuli) - u32:1 );
173
177
let data_in = TestDecInData{
174
- symbol: stimulus.0 ,
175
- count: stimulus.1 ,
178
+ symbols: [ stimulus.0 ] ,
179
+ counts: [ stimulus.1 ] ,
176
180
last: last
177
181
};
178
182
let tok = send (tok, dec_input_s, data_in);
179
183
trace_fmt!(" Sent {} stimuli, symbol: 0x{:x}, count:{}, last: {}" ,
180
- counter + u32:1 , data_in.symbol , data_in.count , data_in.last );
184
+ counter + u32:1 , data_in.symbols [ 0 ] , data_in.counts [ 0 ] , data_in.last );
181
185
(tok)
182
186
}(tok);
183
187
let TransationTestOutputs: TestSymbol[14 ] = [
@@ -194,13 +198,14 @@ proc RunLengthDecoderTransactionTest {
194
198
in enumerate (TransationTestOutputs) {
195
199
let last = counter == (array_size (TransationTestOutputs) - u32:1 );
196
200
let data_out = TestDecOutData{
197
- symbol: symbol,
201
+ symbols: [symbol],
202
+ symbol_valids: [bits[1 ]:1 ],
198
203
last: last
199
204
};
200
205
let (tok, dec_output) = recv (tok, dec_output_r);
201
206
trace_fmt!(
202
207
" Received {} transactions, symbol: 0x{:x}, last: {}" ,
203
- counter, dec_output.symbol , dec_output.last
208
+ counter, dec_output.symbols [ 0 ] , dec_output.last
204
209
);
205
210
assert_eq (dec_output, data_out);
206
211
(tok)
@@ -210,6 +215,81 @@ proc RunLengthDecoderTransactionTest {
210
215
}
211
216
}
212
217
218
+ // Check that RLE decoder will remove empty pairs, `count == 0`.
219
+ // Check that RLE decoder will set `symbol_valids` to 0 only in
220
+ // the last output packet.
221
+ #[test_proc]
222
+ proc RunLengthDecoderZeroCountTest {
223
+ terminator: chan<bool > out; // test termination request
224
+ dec_input_s: chan<TestDecInData> out;
225
+ dec_output_r: chan<TestDecOutData> in;
226
+
227
+ init {()}
228
+
229
+ config (terminator: chan<bool > out) {
230
+ let (dec_input_s, dec_input_r) = chan<TestDecInData>;
231
+ let (dec_output_s, dec_output_r) = chan<TestDecOutData>;
232
+
233
+ spawn RunLengthDecoder<TEST_SYMBOL_WIDTH, TEST_COUNT_WIDTH>(
234
+ dec_input_r, dec_output_s);
235
+ (terminator, dec_input_s, dec_output_r)
236
+ }
237
+
238
+ next (tok: token, state: ()) {
239
+ let ZeroCountTestStimuli: TestStimulus[6 ] =[
240
+ (TestSymbol:0xB , TestCount:0x2 ),
241
+ (TestSymbol:0x1 , TestCount:0x0 ),
242
+ (TestSymbol:0xC , TestCount:0x1 ),
243
+ (TestSymbol:0xC , TestCount:0x0 ),
244
+ (TestSymbol:0x3 , TestCount:0x3 ),
245
+ (TestSymbol:0x2 , TestCount:0x0 ),
246
+ ];
247
+ let tok = for ((counter, stimulus), tok):
248
+ ((u32, (TestSymbol, TestCount)) , token)
249
+ in enumerate (ZeroCountTestStimuli) {
250
+ let last = counter == (array_size (ZeroCountTestStimuli) - u32:1 );
251
+ let data_in = TestDecInData{
252
+ symbols: [stimulus.0 ],
253
+ counts: [stimulus.1 ],
254
+ last: last
255
+ };
256
+ let tok = send (tok, dec_input_s, data_in);
257
+ trace_fmt!(" Sent {} stimuli, symbol: 0x{:x}, count:{}, last: {}" ,
258
+ counter + u32:1 , data_in.symbols [0 ], data_in.counts [0 ], data_in.last );
259
+ (tok)
260
+ }(tok);
261
+ let ZeroCountTestOutputs: TestDecOutData[7 ] = [
262
+ TestDecOutData{symbols: [TestSymbol: 0xB ],
263
+ symbol_valids: [true ], last: false },
264
+ TestDecOutData{symbols: [TestSymbol: 0xB ],
265
+ symbol_valids: [true ], last: false },
266
+ TestDecOutData{symbols: [TestSymbol: 0xC ],
267
+ symbol_valids: [true ], last: false },
268
+ TestDecOutData{symbols: [TestSymbol: 0x3 ],
269
+ symbol_valids: [true ], last: false },
270
+ TestDecOutData{symbols: [TestSymbol: 0x3 ],
271
+ symbol_valids: [true ], last: false },
272
+ TestDecOutData{symbols: [TestSymbol: 0x3 ],
273
+ symbol_valids: [true ], last: false },
274
+ TestDecOutData{symbols: [TestSymbol: 0x2 ],
275
+ symbol_valids: [false ], last: true },
276
+ ];
277
+ let tok = for ((counter, output), tok):
278
+ ((u32, TestDecOutData) , token)
279
+ in enumerate (ZeroCountTestOutputs) {
280
+ let (tok, dec_output) = recv (tok, dec_output_r);
281
+ trace_fmt!(
282
+ " Received {} transactions, symbols: 0x{:x}, last: {}" ,
283
+ counter + u32:1 , dec_output.symbols , dec_output.last
284
+ );
285
+ assert_eq (dec_output, output);
286
+ (tok)
287
+ }(tok);
288
+ send (tok, terminator, true );
289
+ ()
290
+ }
291
+ }
292
+
213
293
// Check that RLE decoder will create 2 `last` output packets,
214
294
// when 2 `last` input packets were consumed.
215
295
#[test_proc]
@@ -232,35 +312,37 @@ proc RunLengthDecoderLastAfterLastTest {
232
312
next (tok: token, state: ()) {
233
313
let LastAfterLastTestStimuli: TestDecInData[2 ] =[
234
314
TestDecInData {
235
- symbol: TestSymbol:0x1 ,
236
- count: TestCount:0x1 ,
315
+ symbols: [ TestSymbol:0x1 ] ,
316
+ counts: [ TestCount:0x1 ] ,
237
317
last:true
238
318
},
239
319
TestDecInData {
240
- symbol: TestSymbol:0x2 ,
241
- count: TestCount:0x1 ,
320
+ symbols: [ TestSymbol:0x2 ] ,
321
+ counts: [ TestCount:0x1 ] ,
242
322
last:true
243
323
},
244
324
];
245
325
let tok = for ((counter, stimulus), tok):
246
326
((u32, TestDecInData) , token)
247
327
in enumerate (LastAfterLastTestStimuli) {
248
328
let tok = send (tok, dec_input_s, stimulus);
249
- trace_fmt!(" Sent {} stimuli, symbol : 0x{:x}, count :{}, last: {}" ,
250
- counter + u32:1 , stimulus.symbol , stimulus.count , stimulus.last );
329
+ trace_fmt!(" Sent {} stimuli, symbols : 0x{:x}, counts :{}, last: {}" ,
330
+ counter + u32:1 , stimulus.symbols , stimulus.counts , stimulus.last );
251
331
(tok)
252
332
}(tok);
253
333
let LastAfterLastTestOutputs: TestDecOutData[2 ] = [
254
- TestDecOutData{symbol: TestSymbol: 0x1 , last: true },
255
- TestDecOutData{symbol: TestSymbol: 0x2 , last: true },
334
+ TestDecOutData{symbols: [TestSymbol: 0x1 ],
335
+ symbol_valids: [true ], last: true },
336
+ TestDecOutData{symbols: [TestSymbol: 0x2 ],
337
+ symbol_valids: [true ], last: true },
256
338
];
257
339
let tok = for ((counter, output), tok):
258
340
((u32, TestDecOutData) , token)
259
341
in enumerate (LastAfterLastTestOutputs) {
260
342
let (tok, dec_output) = recv (tok, dec_output_r);
261
343
trace_fmt!(
262
- " Received {} transactions, symbol : 0x{:x}, last: {}" ,
263
- counter + u32:1 , dec_output.symbol , dec_output.last
344
+ " Received {} transactions, symbols : 0x{:x}, last: {}" ,
345
+ counter + u32:1 , dec_output.symbols , dec_output.last
264
346
);
265
347
assert_eq (dec_output, output);
266
348
(tok)
0 commit comments