use super::*;
pub type Regfile = Array<u32, REGS>;
#[derive(Debug, Clone, Copy)]
pub struct Register {
pub addr: U<{ clog2(REGS) }>,
pub data: u32,
}
impl Register {
pub fn new(addr: U<{ clog2(REGS) }>, data: u32) -> Self {
Self { addr, data }
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct WbR {
pub bypass_from_wb: HOption<Register>,
pub rf: Regfile,
}
impl WbR {
pub fn new(bypass_from_wb: HOption<Register>, rf: Regfile) -> Self {
Self { bypass_from_wb, rf }
}
}
pub fn wb(i: I<VrH<MemEP, WbR>, { Dep::Demanding }>) {
i.map_resolver_inner::<(HOption<MemEP>, Regfile)>(|(p, rf)| WbR::new(p.and_then(|p| p.wb_info), rf))
.reg_fwd(true)
.sink_fsm_map(Regfile::default(), |ip, rf| {
let ir = Ready::valid((ip, rf));
let rf_next = match ip {
Some(MemEP { wb_info: Some(r), .. }) => rf.set(r.addr, r.data),
_ => rf,
};
if let Some(p) = ip {
match p.wb_info {
Some(r) => {
display!(
"retire=[1] pc=[%x] inst=[%x] write=[r%d=%x]",
ip.map(|x| x.debug_pc).unwrap_or(0),
ip.map(|x| x.debug_inst).unwrap_or(0),
r.addr,
r.data
);
}
None => {
display!(
"retire=[1] pc=[%x] inst=[%x]",
ip.map(|x| x.debug_pc).unwrap_or(0),
ip.map(|x| x.debug_inst).unwrap_or(0)
);
}
}
} else {
display!("retire=[0]");
}
(ir, rf_next)
})
}