-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbsg_8b10b_shift_decoder.rs
63 lines (52 loc) · 2.19 KB
/
bsg_8b10b_shift_decoder.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
57
58
59
60
61
62
63
use shakeflow::*;
use shakeflow_std::*;
#[derive(Debug, Clone, Signal)]
pub struct E {
data: Valid<Bits<U<8>>>,
k: bool,
frame_align: bool,
}
pub type IC = UniChannel<bool>;
pub type EC = UniChannel<E>;
#[derive(Debug, Clone, Signal)]
pub struct S {
decode_rd: bool,
shift_reg: Bits<U<10>>,
frame_counter: Bits<U<4>>,
}
impl S {
/// Creates new expr.
pub fn new_expr() -> Expr<S> {
SProj { decode_rd: false.into(), shift_reg: 0.into(), frame_counter: 0.into() }.into()
}
}
pub fn m() -> Module<IC, EC> {
composite::<IC, EC, _>("bsg_8b10b_shift_decoder", Some("i"), Some("o"), |input, k| {
input.fsm_map::<S, E, _>(k, None, S::new_expr(), |input, state| {
// Input Shift Register
let shift_reg_next = state.shift_reg.clip_const::<U<9>>(1).append(input.repr()).resize();
// Comma code detection and Frame alignment
let comma_code_rdn = state.shift_reg.clip_const::<U<7>>(0).is_eq(0b1111100.into());
let comma_code_rdp = state.shift_reg.clip_const::<U<7>>(0).is_eq(0b0000011.into());
let frame_align = comma_code_rdn | comma_code_rdp;
// Frame counter
let frame_recv = state.frame_counter.is_eq(9.into());
let frame_counter_next =
(frame_recv | frame_align).cond(0.into(), (state.frame_counter + 1.into()).resize());
// 8b/10b decoder
let decoder_output = super::bsg_8b10b_decode_comb::logic(
super::bsg_8b10b_decode_comb::IProj { data: state.shift_reg, rd: state.decode_rd }.into(),
);
let valid = frame_recv & !(decoder_output.data_err | decoder_output.rd_err);
let decode_rd_next = frame_align.cond(comma_code_rdn, valid.cond(decoder_output.rd, state.decode_rd));
let output =
EProj { data: Expr::<Valid<_>>::new(valid, decoder_output.data), k: decoder_output.k, frame_align }
.into();
let state_next =
SProj { decode_rd: decode_rd_next, shift_reg: shift_reg_next, frame_counter: frame_counter_next }
.into();
(output, state_next)
})
})
.build()
}