From 68c0402ce8d6f355daa968ea8dfe8777beedbfec Mon Sep 17 00:00:00 2001 From: Ethan Uppal <113849268+ethanuppal@users.noreply.github.com> Date: Mon, 5 Aug 2024 18:40:39 -0400 Subject: [PATCH] I don't know how to use cider2 --- tools/calyx-ffi-macro/src/lib.rs | 14 +++-- tools/calyx-ffi/src/backend/cider.rs | 80 ++++++++++++++++---------- tools/calyx-ffi/src/backend/useless.rs | 10 ++-- tools/tb/examples/calyx/adder.futil | 12 ++-- tools/tb/examples/calyx/test.rs | 1 + 5 files changed, 73 insertions(+), 44 deletions(-) diff --git a/tools/calyx-ffi-macro/src/lib.rs b/tools/calyx-ffi-macro/src/lib.rs index e030a95604..39c29666b9 100644 --- a/tools/calyx-ffi-macro/src/lib.rs +++ b/tools/calyx-ffi-macro/src/lib.rs @@ -30,6 +30,8 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { .expect("failed to turn quoted path into string"); let backend_macro = args.backend; + let mut input_names = Vec::new(); + let mut output_names = Vec::new(); let mut field_names = vec![]; let mut fields = vec![]; let mut getters = vec![]; @@ -47,6 +49,7 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { fields.push(quote! { pub #port_name: u64 }); + input_names.push(port_name); } calyx_ir::Direction::Output => { fields.push(quote! { @@ -57,6 +60,7 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { self.#port_name } }); + output_names.push(port_name); } calyx_ir::Direction::Inout => { todo!("inout ports not supported yet") @@ -95,23 +99,23 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream { } fn init(&mut self, context: &calyx_ir::Context) { - #backend_macro!(@init self, context; #(#field_names),*); + #backend_macro!(@init self, context; #(#input_names),*; #(#output_names),*); } fn reset(&mut self) { - #backend_macro!(@reset self; #(#field_names),*); + #backend_macro!(@reset self; #(#input_names),*; #(#output_names),*); } fn can_tick(&self) -> bool { - #backend_macro!(@can_tick self; #(#field_names),*) + #backend_macro!(@can_tick self; #(#input_names),*; #(#output_names),*) } fn tick(&mut self) { - #backend_macro!(@tick self; #(#field_names),*); + #backend_macro!(@tick self; #(#input_names),*; #(#output_names),*); } fn go(&mut self) { - #backend_macro!(@go self; #(#field_names),*); + #backend_macro!(@go self; #(#input_names),*; #(#output_names),*); } } }; diff --git a/tools/calyx-ffi/src/backend/cider.rs b/tools/calyx-ffi/src/backend/cider.rs index f67fecab4e..ab6e274e46 100644 --- a/tools/calyx-ffi/src/backend/cider.rs +++ b/tools/calyx-ffi/src/backend/cider.rs @@ -1,29 +1,40 @@ use calyx_ir::Context; -use interp::flatten::structures::{ - context::Context as CiderContext, - environment::{Environment, Simulator}, +use core::panic; +use interp::{ + flatten::{ + flat_ir, + structures::{ + context::Context as CiderContext, environment::Simulator, + }, + }, + values::Value, }; -use std::{mem::MaybeUninit, rc::Rc}; +use std::rc::Rc; pub struct CiderFFIBackend { simulator: Simulator>, } impl CiderFFIBackend { - pub fn from(context: &Context, name: &'static str) -> Self { - let cider_context = CiderContext::new(); - let environment = Environment::new(Rc::new(cider_context), None); - let simulator = Simulator::new(environment); + pub fn from(ctx: &Context, name: &'static str) -> Self { + let ctx = flat_ir::translate(ctx); + let simulator = Simulator::build_simulator(Rc::new(ctx), &None) + .expect("we live on the edge"); Self { simulator } } pub fn write_port(&mut self, name: &'static str, value: u64) { - todo!("no way to set port on a component yet I think") - // self.simulator. + if name == "go" { + return; + } + self.simulator.pin_value(name, Value::from(value, 64)); } pub fn read_port(&self, name: &'static str) -> u64 { - todo!("no way to get port on a component yet I think") + self.simulator + .lookup_port_from_string(&String::from(name)) + .expect("wrong port name") + .as_u64() } pub fn step(&mut self) { @@ -31,6 +42,12 @@ impl CiderFFIBackend { "this function isn't documented so don't know what went wrong", ); } + + pub fn go(&mut self) { + self.simulator.run_program().expect("failed to run program"); + panic!(); + self.step(); // since griffin said so + } } /// Runs the component using cider2. @@ -39,42 +56,45 @@ macro_rules! cider_ffi_backend { (@user_data_type) => { $crate::backend::cider::CiderFFIBackend }; - (@init $dut:ident, $ctx:expr; $($port:ident),*) => { + (@init $dut:ident, $ctx:expr; $($input:ident),*; $($output:ident),*) => { $dut.user_data .write($crate::backend::cider::CiderFFIBackend::from( $ctx, $dut.name(), )); }; - (@reset $dut:ident; $($port:ident),*) => { - println!("cider_ffi_backend reset"); - $dut.done = 0; - $dut.reset = 1; - for i in 0..5 { - $dut.tick(); - } - $dut.reset = 0; + (@reset $dut:ident; $($input:ident),*; $($output:ident),*) => { + println!("cider_ffi_backend reset. doesn't work LOL"); + // $dut.done = 0; + // $dut.reset = 1; + // for i in 0..5 { + // $dut.tick(); + // } + // $dut.reset = 0; }; - (@can_tick $dut:ident; $($port:ident),*) => { + (@can_tick $dut:ident; $($input:ident),*; $($output:ident),*) => { true }; - (@tick $dut:ident; $($port:ident),*) => { + (@tick $dut:ident; $($input:ident),*; $($output:ident),*) => { println!("cider_ffi_backend tick"); let cider = unsafe { $dut.user_data.assume_init_mut() }; $( - cider.write_port(stringify!($port), $dut.$port); + cider.write_port(stringify!($input), $dut.$input); )* cider.step(); $( - $dut.$port = cider.read_port(stringify!($port)); + $dut.$output = cider.read_port(stringify!($output)); )* }; - (@go $dut:ident; $($port:ident),*) => { + (@go $dut:ident; $($input:ident),*; $($output:ident),*) => { println!("cider_ffi_backend go"); - $dut.go = 1; - while ($dut.done != 1) { - $dut.tick(); - } - $dut.go = 0; + let cider = unsafe { $dut.user_data.assume_init_mut() }; + $( + cider.write_port(stringify!($input), $dut.$input); + )* + cider.go(); + $( + $dut.$output = cider.read_port(stringify!($output)); + )* }; } diff --git a/tools/calyx-ffi/src/backend/useless.rs b/tools/calyx-ffi/src/backend/useless.rs index b6b472b5bd..c890fdfce2 100644 --- a/tools/calyx-ffi/src/backend/useless.rs +++ b/tools/calyx-ffi/src/backend/useless.rs @@ -4,10 +4,10 @@ macro_rules! useless_ffi_backend { (@user_data_type) => { () // unit type }; - (@init $dut:ident, $ctx:expr; $($port:ident),*) => { + (@init $dut:ident, $ctx:expr; $($input:ident),*; $($output:ident),*) => { println!("useless_ffi_backend init"); }; - (@reset $dut:ident; $($port:ident),*) => { + (@reset $dut:ident; $($input:ident),*; $($output:ident),*) => { println!("useless_ffi_backend reset"); $dut.done = 0; $dut.reset = 1; @@ -16,16 +16,16 @@ macro_rules! useless_ffi_backend { } $dut.reset = 0; }; - (@can_tick $dut:ident; $($port:ident),*) => { + (@can_tick $dut:ident; $($input:ident),*; $($output:ident),*) => { true }; - (@tick $dut:ident; $($port:ident),*) => { + (@tick $dut:ident; $($input:ident),*; $($output:ident),*) => { println!("useless_ffi_backend tick"); if $dut.done == 1 { $dut.done = 0; } }; - (@go $dut:ident; $($port:ident),*) => { + (@go $dut:ident; $($input:ident),*; $($output:ident),*) => { println!("useless_ffi_backend go"); $dut.go = 1; $dut.go = 0; diff --git a/tools/tb/examples/calyx/adder.futil b/tools/tb/examples/calyx/adder.futil index 2adfc08f72..cb1cfa8b7f 100644 --- a/tools/tb/examples/calyx/adder.futil +++ b/tools/tb/examples/calyx/adder.futil @@ -5,9 +5,13 @@ component main(lhs: 64, rhs: 64) -> (result: 64) { adder = std_add(64); } wires { - adder.left = lhs; - adder.right = rhs; - result = adder.out; + group add { + adder.left = lhs; + adder.right = rhs; + result = adder.out; + } + } + control { + add; } - control {} } diff --git a/tools/tb/examples/calyx/test.rs b/tools/tb/examples/calyx/test.rs index 66172f65dc..191cfc08c4 100644 --- a/tools/tb/examples/calyx/test.rs +++ b/tools/tb/examples/calyx/test.rs @@ -3,6 +3,7 @@ use calyx_ffi::prelude::*; use calyx_ffi::cider_ffi_backend; +// not necessary, just to show it off declare_calyx_interface! { In2Out1(lhs, rhs) -> (result) }