Skip to content

Commit

Permalink
Work on supporting backends
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanuppal committed Jul 8, 2024
1 parent 95e85da commit 3150ceb
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 17 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tools/calyx-ffi-macro/src/calyx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl CalyxComponent {
}

pub fn parse_calyx_file(
args: CalyxFFIMacroArgs,
args: &CalyxFFIMacroArgs,
) -> Result<CalyxComponent, TokenStream> {
// there has to be a better way to find lib
let home_dir = env::var("HOME").expect("user home not set");
Expand Down
29 changes: 19 additions & 10 deletions tools/calyx-ffi-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn calyx_ffi(attrs: TokenStream, item: TokenStream) -> TokenStream {
let name = item_struct.ident;

// <sorry>
let comp = calyx::parse_calyx_file(args);
let comp = calyx::parse_calyx_file(&args);
if let Err(error) = comp {
return error;
}
Expand All @@ -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::<syn::Ident>(&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??
Expand Down Expand Up @@ -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),*);
}
}
};
Expand Down
10 changes: 9 additions & 1 deletion tools/calyx-ffi-macro/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self> {
syn::custom_keyword!(src);
syn::custom_keyword!(comp);
syn::custom_keyword!(backend);

let src_ident = input.parse::<src>()?;
input.parse::<syn::Token![=]>()?;
Expand All @@ -25,10 +27,15 @@ impl Parse for CalyxFFIMacroArgs {
input.parse::<syn::Token![=]>()?;
let comp_lit = input.parse::<syn::LitStr>()?.value();

input.parse::<syn::Token![,]>()?;
input.parse::<backend>()?;
input.parse::<syn::Token![=]>()?;
let backend_path = input.parse::<syn::Path>()?;

if !input.is_empty() {
return Err(syn::Error::new_spanned(
input.parse::<TokenTree>()?,
"Invalid `calyx_ffi` attribute syntax: expected 'src = \"...\", comp = \"...\"",
"Invalid `calyx_ffi` argument syntax: expected 'src = \"...\", comp = \"...\", backend = ...",
));
}

Expand All @@ -37,6 +44,7 @@ impl Parse for CalyxFFIMacroArgs {
src: src_lit.into(),
comp_attr_span: comp_ident.span,
comp: comp_lit,
backend: backend_path,
})
}
}
31 changes: 31 additions & 0 deletions tools/calyx-ffi/src/backend.rs
Original file line number Diff line number Diff line change
@@ -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();
};
}
24 changes: 22 additions & 2 deletions tools/calyx-ffi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
use std::{any, cell::RefCell, collections::HashMap, rc::Rc};

pub mod backend;
pub mod prelude;

/// A non-combinational calyx component.
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<RefCell<dyn CalyxFFIComponent>>;
Expand All @@ -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();
}
}
}
4 changes: 3 additions & 1 deletion tools/calyx-ffi/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -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};
3 changes: 2 additions & 1 deletion tools/calyx-ffi/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions tools/tb/examples/calyx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ path = "test.rs"

[dependencies]
calyx-ffi = { path = "../../../calyx-ffi" }
interp = { path = "../../../../interp" }
calyx-ir.workspace = true
16 changes: 15 additions & 1 deletion tools/tb/examples/calyx/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,30 @@ 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;

#[calyx_ffi_tests]
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);
}
}
}
}

0 comments on commit 3150ceb

Please sign in to comment.