use crate::frontend::{CallArgument, Callable, Type}; use crate::rtlil; use crate::rtlil::SigSpec; fn instantiate_unop(celltype: &str, id: &str, args: &[SigSpec], ret: &SigSpec) -> rtlil::Cell { let a = args .get(0) .expect("wrong argcount slipped through type check"); assert_eq!(args.len(), 1); let mut cell = rtlil::Cell::new(id, celltype); cell.add_param("\\A_SIGNED", "0"); cell.add_param("\\A_WIDTH", "1"); cell.add_param("\\Y_WIDTH", "1"); cell.add_connection("\\A", a); cell.add_connection("\\Y", ret); cell } fn instantiate_binop(celltype: &str, id: &str, args: &[SigSpec], ret: &SigSpec) -> rtlil::Cell { let a = args .get(0) .expect("wrong argcount slipped through type check"); let b = args .get(1) .expect("wrong argcount slipped through type check"); assert_eq!(args.len(), 2); let mut cell = rtlil::Cell::new(id, celltype); cell.add_param("\\A_SIGNED", "0"); cell.add_param("\\A_WIDTH", "1"); cell.add_param("\\B_SIGNED", "0"); cell.add_param("\\B_WIDTH", "1"); cell.add_param("\\Y_WIDTH", "1"); cell.add_connection("\\A", a); cell.add_connection("\\B", b); cell.add_connection("\\Y", ret); cell } fn make_binop_callable(name: &str, celltype: &'static str) -> Callable { let args = vec![ CallArgument { name: "A".to_owned(), atype: Type::wire(), }, CallArgument { name: "B".to_owned(), atype: Type::wire(), }, ]; Callable { name: name.to_owned(), args, ret: Type::wire(), instantiate: Box::new(move |id, args, ret| instantiate_binop(celltype, id, args, ret)), } } fn make_unnop_callable(name: &str, celltype: &'static str) -> Callable { let args = vec![CallArgument { name: "A".to_owned(), atype: Type::wire(), }]; Callable { name: name.to_owned(), args, ret: Type::wire(), instantiate: Box::new(move |id, args, ret| instantiate_unop(celltype, id, args, ret)), } } pub fn get_builtins() -> Vec { vec![ make_binop_callable("and", "$and"), make_binop_callable("or", "$or"), make_binop_callable("xor", "$xor"), make_binop_callable("xnor", "$xnor"), make_unnop_callable("not", "$not"), ] }