#![allow(unused)] #![allow(warnings)] use super::utils::*;
use super::*;
pub const MAX_SIMULTANEOUS_MATMULS: usize = 5;
pub const ID_BITS: usize = clog2(MAX_SIMULTANEOUS_MATMULS);
pub const TOTAL_ROWS: usize = BLOCK_SIZE;
const FIFO_LENGTH: usize = MAX_SIMULTANEOUS_MATMULS + 1;
pub type A = Array<Array<S<INPUT_BITS>, TILE_ROWS>, MESH_ROWS>;
pub type B = Array<Array<S<INPUT_BITS>, TILE_COLS>, MESH_COLS>;
pub type C = Array<Array<S<OUTPUT_BITS>, TILE_COLS>, MESH_COLS>;
pub type D = Array<Array<S<INPUT_BITS>, TILE_COLS>, MESH_COLS>;
pub type TagsInProgress = Array<MeshTag, FIFO_LENGTH>;
#[derive(Debug, Clone, Copy)]
pub enum TransposeFlag {
A,
B,
D,
}
#[derive(Debug, Clone, Copy)]
pub struct MeshTag {
pub rob_id: HOption<U<{ clog2(RS_ENTRIES) }>>,
pub addr: LocalAddr,
pub rows: U<{ clog2(BLOCK_SIZE + 1) }>,
pub cols: U<{ clog2(BLOCK_SIZE + 1) }>,
}
impl Default for MeshTag {
fn default() -> Self {
Self { rob_id: None, addr: LocalAddr::from(GARBAGE_ADDR.into_u()), rows: 0.into_u(), cols: 0.into_u() }
}
}
#[derive(Debug, Clone, Copy)]
pub struct MeshReq {
pub dataflow: Dataflow,
pub propagate_flip: bool,
pub shift: U<{ clog2(ACC_BITS) }>,
pub transpose_a: bool,
pub transpose_bd: bool,
pub total_rows: U<{ clog2(BLOCK_SIZE + 1) }>,
pub tag: MeshTag,
pub flush: bool,
}
#[derive(Debug, Clone, Copy)]
pub struct MeshResp {
pub total_rows: U<{ clog2(BLOCK_SIZE + 1) }>,
pub tag: MeshTag,
pub last: bool,
pub data: C,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct Config {
pub matmul_id: U<ID_BITS>,
pub propagate: Propagate,
}
impl Config {
pub fn new(matmul_id: U<ID_BITS>, propagate: Propagate) -> Self {
Self { matmul_id, propagate }
}
pub fn update(self, propagate_flip: bool) -> Self {
todo!("assignment 6")
}
}
#[derive(Debug, Clone, Copy)]
pub struct ReqExtended {
pub req: MeshReq,
pub config: Config,
}
fn fifos(
req: I<VrH<ReqExtended, TagsInProgress>, { Dep::Helpful }>,
control: Valid<PeColControl>,
) -> (Valid<MeshTag>, Valid<U<{ clog2(BLOCK_SIZE + 1) }>>) {
let (control_to_tag_fifo, control_to_total_rows_fifo) = control.lfork();
let req: I<VrH<ReqExtended, TagsInProgress>, { Dep::Helpful }> = todo!("assignment 6");
let (tag, total_rows) = req
.map_resolver_inner::<(TagsInProgress, ())>(|(tags, _)| tags)
.map(|ReqExtended { req, config }| {
let tag_id = todo!("assignment 6");
let total_rows_id = todo!("assignment 6");
((tag_id, req.tag), (total_rows_id, req.total_rows))
})
.unzip();
let tag: I<VrH<(U<ID_BITS>, MeshTag), ((), FifoS<(U<ID_BITS>, MeshTag), FIFO_LENGTH>)>, { Dep::Helpful }> =
todo!("Caculate the resolver signal `TagsInProgress` here");
let total_rows = total_rows.map_resolver_inner::<((), FifoS<(U<ID_BITS>, U<5>), FIFO_LENGTH>)>(|_| ());
let tag_fifo = tag.multi_headed_transparent_fifo().filter_map(|p| p.head());
let total_rows_fifo = total_rows.multi_headed_transparent_fifo().filter_map(|p| p.head());
let tag = (tag_fifo, control_to_tag_fifo)
.join()
.map_resolver_inner_with_p::<()>(|ip, _| {
let pop: bool = todo!("assignment 6");
((), if pop { 1.into_u() } else { 0.into_u() })
})
.filter_map::<MeshTag>(|((head_id, tag), mesh_out_control)| {
let transfer: bool = todo!("assignment 6");
if transfer {
Some(tag)
} else {
None
}
});
let total_rows = (total_rows_fifo, control_to_total_rows_fifo)
.join()
.map_resolver_inner_with_p::<()>(|ip, _| {
let pop: bool = todo!("assignment 6");
((), if pop { 1.into_u() } else { 0.into_u() })
})
.filter_map::<U<{ clog2(BLOCK_SIZE + 1) }>>(|((head_id, total_rows), mesh_out_control)| {
let transfer: bool = todo!("assignment 6");
if transfer {
Some(total_rows)
} else {
None
}
});
(tag.always_into_valid(), total_rows.always_into_valid())
}
fn transpose(data: Valid<(MeshReq, A, B, D)>) -> Valid<(A, B, D)> {
let (a_with_sel, b_with_sel, d_with_sel): (
Valid<(A, BoundedU<2>)>,
Valid<(B, BoundedU<2>)>,
Valid<(D, BoundedU<2>)>,
) = todo!("assignment 6");
let [a, a_transpose] = a_with_sel.branch();
let [b, b_transpose] = b_with_sel.branch();
let [d, d_transpose] = d_with_sel.branch();
let a_transpose = a_transpose.map(|p| (TransposeFlag::A, p));
let b_transpose = b_transpose.map(|p| (TransposeFlag::B, p));
let d_transpose = d_transpose.map(|p| (TransposeFlag::D, p.reverse()));
let (flag, transpose_target): (Valid<TransposeFlag>, Valid<A>) = todo!("assignment 6");
let transposed = transpose_target.map(|vec| vec.concat()).comb(transposer_ffi);
let [a_transposed, b_transposed, d_transposed]: [Valid<A>; 3] =
(flag, transposed).join_valid().map(|(flag, arr)| todo!("assignment 6")).branch();
let a = [a_transposed, a].merge();
let b = [b_transposed, b].merge();
let d = [d_transposed.map(|p| p.reverse()), d].merge();
(a, b, d).join_valid()
}
pub fn mesh_with_delays(
data: Vr<(A, B, D)>,
req: I<VrH<MeshReq, TagsInProgress>, { Dep::Helpful }>,
) -> Valid<MeshResp> {
let req: I<VrH<ReqExtended, TagsInProgress>, { Dep::Helpful }> = todo!("assignment 6");
let (mesh_req, fifo_req) = req.map_resolver_inner::<((), TagsInProgress)>(|(_, tags)| tags).lfork();
let mesh_req: Vr<(ReqExtended, bool)> = mesh_req.fsm_egress::<(ReqExtended, bool), U<{ clog2(BLOCK_SIZE) }>>(
U::default(),
true,
true,
|req_ext, counter| todo!("assignment 6"),
);
let [mesh_req_flush, mesh_req_matmul]: [Vr<(ReqExtended, bool)>; 2] = todo!("assignment 6");
let mesh_req_flush = mesh_req_flush.always_into_valid();
let (mesh_req_matmul, mesh_data) = (mesh_req_matmul, data)
.join_vr()
.always_into_valid()
.map(|((req_ext, last), (a, b, d))| {
let matmul_req = (req_ext, last);
let mesh_data = (req_ext.req, a, b, d);
(matmul_req, mesh_data)
})
.unzip();
let mesh_req: Valid<(ReqExtended, bool)> = todo!("assignment 6");
let mesh_data_transposed = mesh_data.comb(transpose);
let mesh_out = (mesh_data_transposed, mesh_req)
.comb(preprocess_type)
.comb(preprocess_shift)
.comb(move |(in_row, in_col)| mesh_ffi(in_row, in_col))
.comb(postprocess_shift)
.comb(postprocess_type);
let (mesh_out, mesh_out_control) = mesh_out.map(|p| (p, p.1)).unzip();
let (tag, total_rows) = fifos(fifo_req, mesh_out_control);
(tag, total_rows, mesh_out).zip_any_valid().filter_map(|(tag, total_rows, mesh_out)| todo!("assignment 6"))
}
#[synthesize]
pub fn mesh_with_delays_default(
a: Vr<A>,
b: Vr<B>,
d: Vr<D>,
req: I<VrH<MeshReq, TagsInProgress>, { Dep::Helpful }>,
) -> Valid<MeshResp> {
let data = (a, b, d).join_vr();
mesh_with_delays(data, req)
}