Skip to content

Commit cdb9de4

Browse files
committed
valid block collector
1 parent 429b3d4 commit cdb9de4

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

primitives/reshape.fil

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,45 @@ comp DecimateTime[W, N]<'G: 1>(
187187
out = in;
188188
valid = eq.out;
189189
}
190+
191+
// Takes a stream of signals with a valid tag and produces a block of size
192+
// N where all the signals are valid.
193+
//
194+
// `block_valid` is only asserted the unit at collected `N` valid signals after
195+
// which it resets.
196+
comp CollectValid[W, N]<'G:1>(
197+
en: interface['G],
198+
in: ['G, 'G+1] W,
199+
valid: ['G, 'G+1] 1
200+
) -> (
201+
out[N]: ['G, 'G+1] W,
202+
block_valid: ['G, 'G+1] 1
203+
) where W > 0 {
204+
let Bits = log2(N)+1; assume Bits > 0;
205+
206+
// Increment the index if the value on the stream is valid
207+
idx := new Prev[Bits, 1]<'G>(mux.out);
208+
one := new Const[Bits, 1]<'G>();
209+
add := new Add[Bits]<'G>(idx.prev, one.out);
210+
mux := new Mux[Bits]<'G>(valid, add.out, idx.prev);
211+
212+
// Are all the blocks valid?
213+
n := new Const[Bits, N]<'G>();
214+
n_sub_1 := new Sub[Bits]<'G>(n.out, one.out);
215+
max_reached := new Eq[Bits]<'G>(n_sub_1.out, idx.prev);
216+
block_valid = max_reached.out;
217+
218+
// Take the location index points to within the output block and assign the
219+
// value to it (which then gets latched).
220+
zero := new Const[W, 0]<'G>();
221+
for i in 0..N {
222+
p := new Prev[W, 1]<'G>(next.out);
223+
v := new Const[Bits, i]<'G>();
224+
eq := new Eq[Bits]<'G>(v.out, idx.prev);
225+
eq_and_valid := new And[1]<'G>(eq.out, valid);
226+
assign_mux := new Mux[W]<'G>(eq_and_valid.out, in, p.prev);
227+
// max ? 0 : eq ? in : p;
228+
next := new Mux[W]<'G>(max_reached.out, zero.out, assign_mux.out);
229+
out{i} = p.prev;
230+
}
231+
}

0 commit comments

Comments
 (0)