use cmtir::to_fir::cmtir_type_to_firrtl_type;
use cmtir::IRDump;
use itertools::chain;
use crate as cmtrs;
use crate::gen_ir::AST;
use crate::*;
pub mod reg;
pub use reg::*;
pub mod fifo;
pub use fifo::*;
pub mod mem;
pub use mem::*;
pub mod sim;
pub use sim::*;
itfc_declare! {
param T;
pub struct Wire{
#[name("in")]
in_: input param T,
out: output param T,
}
method write(in_);
method read() -> (out);
}
impl Wire {
pub fn new(t: &Type) -> Wire { wire(t) }
}
impl CmtAST for &Wire {
fn ast(self) -> AST { self.read().ast() }
}
impl<T: CmtAST> std::ops::RemAssign<T> for Wire {
fn rem_assign(&mut self, rhs: T) { self.write(rhs); }
}
impl ToPrintItem for Wire {
fn to_print_item(&self, __cmt_gen: ContextItfc<impl Itfc>) -> PrintItem { self.read().to_print_item(__cmt_gen) }
}
#[module]
pub fn wire(t: &Type) -> Wire {
let io = io! {
T: t
};
anno!("synthesis": "true");
let fir_str = r#"
module Wire_{ctype T}:
input a: {ftype T}
output out: {ftype T}
connect out, a"#;
let ir_ty: cmtir::Type = t.clone().into();
let fir_str = fir_str.replace("{ctype T}", &ir_ty.ir_dump());
let fir_str = fir_str.replace("{ftype T}", &cmtir_type_to_firrtl_type(ir_ty).to_string());
external!(["a".to_string()], ["out".to_string()], None, None, fir_str.to_string(),);
let write = ext_method!(
None; None; true;
(io.in_) {}
);
let read = ext_method!(
None; None; false;
() -> (io.out) {}
);
method_rel!(write C write);
schedule!(write, read);
}
#[test]
fn test_wire() {
use utils::setup_logger;
setup_logger();
let wire = wire(&Type::SInt(16));
println!("{}", wire.to_cmtir().ir_dump());
}
itfc_declare!(
#[doc = r"A general module interface to be dynamically generated, can add arbitraty ios and methods into it"]
pub struct GeneratedModule {}
);