-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbsg_channel_tunnel_in.rs
56 lines (48 loc) · 2.06 KB
/
bsg_channel_tunnel_in.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use shakeflow::*;
use shakeflow_std::*;
use super::bsg_channel_tunnel_out::IC as EC;
pub type IC<Width: Num, const N: usize> = VrChannel<(Bits<Width>, Bits<Log2<U<N>>>)>;
pub fn m<Width: Num, const N: usize, const REMOTE_CREDITS: usize>() -> Module<IC<Width, N>, EC<Width, N, REMOTE_CREDITS>>
where
[(); 1 << N]:,
[(); N + 1]:,
{
composite::<IC<Width, N>, EC<Width, N, REMOTE_CREDITS>, _>(
"bsg_channel_tunnel_in",
Some("i"),
Some("o"),
|input, k| {
let (input, tag) = input.clone_uni(k);
let input = input.map(k, |input| input.0);
let tag = tag.map(k, |input| input.inner.1.resize());
let mut demuxed =
(input, tag)
.comb_inline(
k,
super::bsg_1_to_n_tagged_fifo::m::<
Bits<Width>,
{ N + 1 },
REMOTE_CREDITS,
{ 1 << N },
false,
false,
>(),
)
.into_iter();
let credit = demuxed.next_back().unwrap().into_uni(k, false);
let outgoing: [VrChannel<Bits<Width>>; N] = demuxed.collect::<Vec<_>>().try_into().unwrap();
// XXX: We assume that input has bit-representable signal?
let credit_local_return = credit.map_inner(k, |input| {
input.resize::<Prod<Log2<U<REMOTE_CREDITS>>, U<N>>>().chunk::<Log2<U<REMOTE_CREDITS>>>().resize()
});
let (outgoing, sent) = outgoing.array_map(k, "sent", |ch, k| ch.fire(k)).unzip();
let credit_remote_return = sent
.array_map(k, "credit_remote_return", |ch, k| ch.counter(k).map(k, |input| input.0))
.concat(k)
.into_deq(k)
.fsm_map(k, ().into(), |input, state| (input, state, true.into()));
EC { data: outgoing, credit_local_return, credit_remote_return }
},
)
.build()
}