-
Notifications
You must be signed in to change notification settings - Fork 1
/
bsg_fifo_shift_datapath.rs
39 lines (32 loc) · 1.26 KB
/
bsg_fifo_shift_datapath.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//! Creates an array of shift registers, with independently controller three input muxes.
//!
//! - 0: Keep value
//! - 1: Get prev value
//! - 2: Set new value
use shakeflow::*;
use shakeflow_std::*;
pub type IC<V: Signal, const N: usize> = (UniChannel<V>, UniChannel<Array<Bits<U<2>>, U<N>>>);
pub type OC<V: Signal> = UniChannel<V>;
pub fn m<V: Signal, const N: usize>() -> Module<IC<V, N>, OC<V>> {
composite::<IC<V, N>, OC<V>, _>("bsg_fifo_shift_datapath", Some("i"), Some("o"), |(input, sel), k| {
input.zip(k, sel).fsm_map::<Array<V, Sum<U<N>, U<1>>>, _, _>(k, None, Expr::x(), |input, state| {
let (input, sel) = *input;
let output = state[0];
let curr = state.clip_const::<U<N>>(0);
let prev = state.clip_const::<U<N>>(1);
let state_next = curr
.zip4(prev, sel, input.repeat())
.map(|input| {
let (curr, prev, sel, input) = *input;
select! {
sel.is_eq(0b01.into()) => prev,
sel.is_eq(0b10.into()) => input,
default => curr,
}
})
.resize();
(output, state_next)
})
})
.build()
}