From 3150ceb06e0cf9a1a28baa2b2f52aec357f6f97c Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:24:08 -0400 Subject: [PATCH] Work on supporting backends --- Cargo.lock | 2 ++ tools/calyx-ffi-macro/src/calyx.rs | 2 +- tools/calyx-ffi-macro/src/lib.rs | 29 ++++++++++++++++++---------- tools/calyx-ffi-macro/src/parse.rs | 10 +++++++++- tools/calyx-ffi/src/backend.rs | 31 ++++++++++++++++++++++++++++++ tools/calyx-ffi/src/lib.rs | 24 +++++++++++++++++++++-- tools/calyx-ffi/src/prelude.rs | 4 +++- tools/calyx-ffi/tests/test.rs | 3 ++- tools/tb/examples/calyx/Cargo.toml | 2 ++ tools/tb/examples/calyx/test.rs | 16 ++++++++++++++- 10 files changed, 106 insertions(+), 17 deletions(-) create mode 100644 tools/calyx-ffi/src/backend.rs diff --git a/Cargo.lock b/Cargo.lock index 430728540f..744fea7f3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,6 +416,8 @@ name = "calyx-ffi-example" version = "0.7.1" dependencies = [ "calyx-ffi", + "calyx-ir", + "interp", ] [[package]] diff --git a/tools/calyx-ffi-macro/src/calyx.rs b/tools/calyx-ffi-macro/src/calyx.rs index 4c8654990e..aee8bbfb52 100644 --- a/tools/calyx-ffi-macro/src/calyx.rs +++ b/tools/calyx-ffi-macro/src/calyx.rs @@ -16,7 +16,7 @@ impl CalyxComponent { } pub fn parse_calyx_file( - args: CalyxFFIMacroArgs, + args: &CalyxFFIMacroArgs, ) -> Result { // there has to be a better way to find lib let home_dir = env::var("HOME").expect("user home not set"); diff --git a/tools/calyx-ffi-macro/src/lib.rs b/tools/calyx-ffi-macro/src/lib.rs index 48ce367bbe..6d0d9bd15b 100644 --- a/tools/calyx-ffi-macro/src/lib.rs +++ b/tools/calyx-ffi-macro/src/lib.rs @@ -14,7 +14,7 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { let name = item_struct.ident; // - let comp = calyx::parse_calyx_file(args); + let comp = calyx::parse_calyx_file(&args); if let Err(error) = comp { return error; } @@ -28,13 +28,16 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { )) .expect("failed to turn quoted name into string"); - let mut fields = Vec::new(); - let mut getters = Vec::new(); + let backend_macro = args.backend; + let mut field_names = vec![]; + let mut fields = vec![]; + let mut getters = vec![]; for port in comp.signature.borrow().ports() { let port_name_str = port.borrow().name.to_string(); let port_name = syn::parse_str::(&port_name_str) .expect("failed to turn port name into identifier"); + field_names.push(port_name.clone()); // let port_width = port.borrow().width; // idk why input output ports are being flipped?? @@ -76,18 +79,24 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { #comp_name } + fn init(&mut self) { + #backend_macro!(init self; #(#field_names),*); + } + + fn deinit(&mut self) { + #backend_macro!(deinit self; #(#field_names),*); + } + fn reset(&mut self) { - self.reset = 1; - for _ in 0..5 { - self.tick(); - } - self.reset = 0; + #backend_macro!(reset self; #(#field_names),*); } fn tick(&mut self) { - self.clk = 1; + #backend_macro!(tick self; #(#field_names),*); + } - self.clk = 0; + fn go(&mut self) { + #backend_macro!(go self; #(#field_names),*); } } }; diff --git a/tools/calyx-ffi-macro/src/parse.rs b/tools/calyx-ffi-macro/src/parse.rs index 692ef86555..5796d085ba 100644 --- a/tools/calyx-ffi-macro/src/parse.rs +++ b/tools/calyx-ffi-macro/src/parse.rs @@ -8,12 +8,14 @@ pub struct CalyxFFIMacroArgs { pub src: PathBuf, pub comp_attr_span: Span, pub comp: String, + pub backend: syn::Path, } impl Parse for CalyxFFIMacroArgs { fn parse(input: ParseStream) -> syn::Result { syn::custom_keyword!(src); syn::custom_keyword!(comp); + syn::custom_keyword!(backend); let src_ident = input.parse::()?; input.parse::()?; @@ -25,10 +27,15 @@ impl Parse for CalyxFFIMacroArgs { input.parse::()?; let comp_lit = input.parse::()?.value(); + input.parse::()?; + input.parse::()?; + input.parse::()?; + let backend_path = input.parse::()?; + if !input.is_empty() { return Err(syn::Error::new_spanned( input.parse::()?, - "Invalid `calyx_ffi` attribute syntax: expected 'src = \"...\", comp = \"...\"", + "Invalid `calyx_ffi` argument syntax: expected 'src = \"...\", comp = \"...\", backend = ...", )); } @@ -37,6 +44,7 @@ impl Parse for CalyxFFIMacroArgs { src: src_lit.into(), comp_attr_span: comp_ident.span, comp: comp_lit, + backend: backend_path, }) } } diff --git a/tools/calyx-ffi/src/backend.rs b/tools/calyx-ffi/src/backend.rs new file mode 100644 index 0000000000..7134483db4 --- /dev/null +++ b/tools/calyx-ffi/src/backend.rs @@ -0,0 +1,31 @@ +#[macro_export] +macro_rules! useless_ffi_backend { + (init $dut:ident; $($port:ident),*) => { + println!("useless_ffi_backend init"); + }; + (deinit $dut:ident; $($port:ident),*) => { + println!("useless_ffi_backend deinit"); + }; + (reset $dut:ident; $($port:ident),*) => { + println!("useless_ffi_backend reset"); + $dut.done = 0; + $dut.reset = 1; + for i in 0..5 { + $dut.tick(); + } + $dut.reset = 0; + }; + (tick $dut:ident; $($port:ident),*) => { + println!("useless_ffi_backend tick"); + if $dut.done == 1 { + $dut.done = 0; + } + }; + (go $dut:ident; $($port:ident),*) => { + println!("useless_ffi_backend go"); + $dut.go = 1; + $dut.go = 0; + $dut.done = 1; + $dut.tick(); + }; +} diff --git a/tools/calyx-ffi/src/lib.rs b/tools/calyx-ffi/src/lib.rs index 07e56cd3f4..e791d1673b 100644 --- a/tools/calyx-ffi/src/lib.rs +++ b/tools/calyx-ffi/src/lib.rs @@ -1,5 +1,6 @@ use std::{any, cell::RefCell, collections::HashMap, rc::Rc}; +pub mod backend; pub mod prelude; /// A non-combinational calyx component. @@ -7,11 +8,20 @@ pub trait CalyxFFIComponent: any::Any { /// The in-source name of this component. fn name(&self) -> &'static str; + /// Internal initialization routine. Do not call! + fn init(&mut self); + + /// Internal deinitialization routine. Do not call! + fn deinit(&mut self); + // Resets this component. fn reset(&mut self); - // Advances this component by one clock cycle. + // Advances this component by one clock cycle. May not always be available. fn tick(&mut self); + + /// Calls this component. + fn go(&mut self); } pub type CalyxFFIComponentRef = Rc>; @@ -31,8 +41,18 @@ impl CalyxFFI { ) -> CalyxFFIComponentRef { let name = T::default().name(); if !self.comps.contains_key(name) { - self.comps.insert(name, Rc::new(RefCell::new(T::default()))); + let comp_ref = Rc::new(RefCell::new(T::default())); + comp_ref.borrow_mut().init(); + self.comps.insert(name, comp_ref); } self.comps.get(name).unwrap().clone() } } + +impl Drop for CalyxFFI { + fn drop(&mut self) { + for (_, comp) in &self.comps { + comp.borrow_mut().deinit(); + } + } +} diff --git a/tools/calyx-ffi/src/prelude.rs b/tools/calyx-ffi/src/prelude.rs index 80281ce750..9b2fe48836 100644 --- a/tools/calyx-ffi/src/prelude.rs +++ b/tools/calyx-ffi/src/prelude.rs @@ -1,2 +1,4 @@ -pub use super::{CalyxFFI, CalyxFFIComponent, CalyxFFIComponentRef}; +pub use super::{ + useless_ffi_backend, CalyxFFI, CalyxFFIComponent, CalyxFFIComponentRef, +}; pub use calyx_ffi_macro::{calyx_ffi, calyx_ffi_test, calyx_ffi_tests}; diff --git a/tools/calyx-ffi/tests/test.rs b/tools/calyx-ffi/tests/test.rs index ba389daf77..8a223db05c 100644 --- a/tools/calyx-ffi/tests/test.rs +++ b/tools/calyx-ffi/tests/test.rs @@ -2,7 +2,8 @@ use calyx_ffi::prelude::*; #[calyx_ffi( src = "/Users/ethan/Documents/GitHub/calyx/tools/calyx-ffi/tests/file.futil", - comp = "main" + comp = "main", + backend = useless_ffi_backend )] struct Main; diff --git a/tools/tb/examples/calyx/Cargo.toml b/tools/tb/examples/calyx/Cargo.toml index a5db5e055b..a0ac39f852 100644 --- a/tools/tb/examples/calyx/Cargo.toml +++ b/tools/tb/examples/calyx/Cargo.toml @@ -17,3 +17,5 @@ path = "test.rs" [dependencies] calyx-ffi = { path = "../../../calyx-ffi" } +interp = { path = "../../../../interp" } +calyx-ir.workspace = true diff --git a/tools/tb/examples/calyx/test.rs b/tools/tb/examples/calyx/test.rs index f9721e170d..b31352a55a 100644 --- a/tools/tb/examples/calyx/test.rs +++ b/tools/tb/examples/calyx/test.rs @@ -2,7 +2,8 @@ use calyx_ffi::prelude::*; #[calyx_ffi( src = "/Users/ethan/Documents/GitHub/calyx/tools/tb/examples/calyx/adder.futil", - comp = "main" + comp = "main", + backend = useless_ffi_backend )] struct Adder; @@ -10,8 +11,21 @@ struct Adder; mod tests { use super::*; + fn add(adder: &mut Adder, lhs: u64, rhs: u64) -> u64 { + adder.lhs = lhs; + adder.rhs = rhs; + adder.go(); + adder.result() + } + #[calyx_ffi_test] fn test(adder: &mut Adder) { println!("testing adder"); + adder.reset(); + for i in 0..10 { + for j in 0..10 { + assert!(add(adder, i, j) == i + j); + } + } } }