use cmtc::ehdl::*;
use cmtrs::*;
itfc_declare! {
param T;
struct Counter {
set_val: input param T,
count: output param T,
}
method read() -> (count);
method set(set_val);
}
#[module]
fn make_counter(lim: usize, ty: &Type) -> Counter {
let io = io! {
T: ty
};
let reg_i = instance!(stl::reg(ty));
let inc = always! {
[reg_i.read().lt(literal(lim as i32, ty))]
() {
reg_i.write(reg_i.read() + literal(1, ty));
}
};
let rst = always! {
[reg_i.read().ge(literal(lim as i32, ty))]
() {
reg_i.write(literal(0, ty));
}
};
let set = method!(
(io.set_val) {
reg_i.write(io.set_val);
}
);
let read = method! {
() -> (io.count) {
reg_i.read().ast();
}
};
method_rel!(set C set);
schedule!(read, set, inc, rst);
}
fn main() -> anyhow::Result<()> {
let ty = Type::UInt(4);
let counter = make_counter(10, &ty);
elaborate(counter, sv_config("counter.sv"))?;
Ok(())
}