diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 6a989eb7e8..1c4dfefb66 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -174,7 +174,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: build - args: --workspace --features yxi --manifest-path /home/calyx/Cargo.toml + args: --workspace --manifest-path /home/calyx/Cargo.toml # - name: Source code doc tests # uses: actions-rs/cargo@v1 diff --git a/Cargo.lock b/Cargo.lock index cb35d054f4..8e45c47645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3449,6 +3449,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yxi" +version = "0.7.1" +dependencies = [ + "argh", + "calyx-frontend", + "calyx-ir", + "calyx-opt", + "calyx-utils", + "serde", + "serde_json", +] + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index fe30f5cb16..6fc18940e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ members = [ "data-conversion", "tools/btor2/btor2i", "tools/cider-data-converter", + "tools/yxi", ] exclude = ["site"] @@ -92,7 +93,6 @@ path = "src/main.rs" [features] default = [] serialize = ["calyx-ir/serialize", "serde/rc", "calyx-backend/sexp"] -yxi = ["serialize", "calyx-backend/yxi", "calyx-ir/yxi"] [build-dependencies] calyx-stdlib = { path = "calyx-stdlib", version = "0.7.1" } diff --git a/calyx-backend/Cargo.toml b/calyx-backend/Cargo.toml index 9baa5fd9ba..9ccd175e33 100644 --- a/calyx-backend/Cargo.toml +++ b/calyx-backend/Cargo.toml @@ -42,4 +42,3 @@ mlir = [] xilinx = ["dep:quick-xml"] resources = ["dep:csv"] sexp = ["dep:serde_with", "dep:serde_sexpr", "serde/rc", "calyx-ir/serialize"] -yxi = ["calyx-ir/yxi"] diff --git a/calyx-backend/src/backend_opt.rs b/calyx-backend/src/backend_opt.rs index 6a6585ed02..000e368d78 100644 --- a/calyx-backend/src/backend_opt.rs +++ b/calyx-backend/src/backend_opt.rs @@ -12,8 +12,6 @@ pub enum BackendOpt { Mlir, Resources, Sexp, - #[cfg(feature = "yxi")] - Yxi, Firrtl, PrimitiveUses, None, @@ -30,8 +28,6 @@ fn backends() -> Vec<(&'static str, BackendOpt)> { ("mlir", BackendOpt::Mlir), ("resources", BackendOpt::Resources), ("sexp", BackendOpt::Sexp), - #[cfg(feature = "yxi")] - ("yxi", BackendOpt::Yxi), ("firrtl", BackendOpt::Firrtl), ("primitive-uses", BackendOpt::PrimitiveUses), ("none", BackendOpt::None), @@ -75,8 +71,6 @@ impl ToString for BackendOpt { Self::Verilog => "verilog", Self::Xilinx => "xilinx", Self::XilinxXml => "xilinx-xml", - #[cfg(feature = "yxi")] - Self::Yxi => "yxi", Self::Calyx => "calyx", Self::Firrtl => "firrtl", Self::PrimitiveUses => "primitive-uses", diff --git a/calyx-backend/src/lib.rs b/calyx-backend/src/lib.rs index 5bcdf3c552..9e341d3dc5 100644 --- a/calyx-backend/src/lib.rs +++ b/calyx-backend/src/lib.rs @@ -11,11 +11,6 @@ pub use primitive_uses::PrimitiveUsesBackend; pub use traits::Backend; pub use verilog::VerilogBackend; -#[cfg(feature = "yxi")] -mod yxi; -#[cfg(feature = "yxi")] -pub use yxi::YxiBackend; - #[cfg(feature = "mlir")] mod mlir; #[cfg(feature = "mlir")] diff --git a/calyx-backend/src/yxi.rs b/calyx-backend/src/yxi.rs deleted file mode 100644 index d12b3fd6e3..0000000000 --- a/calyx-backend/src/yxi.rs +++ /dev/null @@ -1,81 +0,0 @@ -use crate::traits::Backend; -use calyx_ir as ir; -use calyx_ir::utils::{GetMemInfo, MemoryType}; -use calyx_utils::CalyxResult; -use serde::Serialize; -/// Backend that generates the YXI Interface Definition Language. -/// YXI aims to be a description of toplevel hardware modules that we can then consume -/// to create things like AXI wrappers on arbitrary programs -#[derive(Default)] -pub struct YxiBackend; - -#[derive(Serialize)] -struct ProgramInterface<'a> { - toplevel: &'a str, - memories: Vec>, -} - -#[derive(Serialize)] -struct Memory<'a> { - name: &'a str, - memory_type: MemoryType, - data_width: u64, - dimensions: u64, - dimension_sizes: Vec, - total_size: u64, //number of cells in memory - idx_sizes: Vec, -} - -impl Backend for YxiBackend { - fn name(&self) -> &'static str { - "yxi" - } - - fn validate(_ctx: &ir::Context) -> CalyxResult<()> { - Ok(()) - } - - fn link_externs( - _prog: &ir::Context, - _write: &mut calyx_utils::OutputFile, - ) -> CalyxResult<()> { - Ok(()) - } - - fn emit( - prog: &ir::Context, - file: &mut calyx_utils::OutputFile, - ) -> CalyxResult<()> { - let toplevel = prog - .components - .iter() - .find(|comp| comp.name == prog.entrypoint) - .unwrap(); - - let memory_names = ir::utils::external_and_ref_memories_names(toplevel); - let mem_infos = toplevel.get_mem_info(); - - let memories: Vec = memory_names - .iter() - .zip(mem_infos.iter()) - .map(|(memory_name, mem_info)| Memory { - name: memory_name, - memory_type: mem_info.memory_type, - data_width: mem_info.data_width, - dimensions: mem_info.dimensions, - dimension_sizes: mem_info.dimension_sizes.clone(), - total_size: mem_info.total_size, - idx_sizes: mem_info.idx_sizes.clone(), - }) - .collect(); - - let program_interface = ProgramInterface { - toplevel: toplevel.name.as_ref(), - memories, - }; - - serde_json::to_writer_pretty(file.get_write(), &program_interface)?; - - Ok(()) - } -} diff --git a/calyx-ir/src/utils.rs b/calyx-ir/src/utils.rs index b47fbc3a89..70f8ec2ca7 100644 --- a/calyx-ir/src/utils.rs +++ b/calyx-ir/src/utils.rs @@ -1,7 +1,7 @@ //! Helpers used to examine calyx programs. Used in Xilinx and Yxi backends among others. use super::{BoolAttr, Cell, Component, RRC}; use calyx_utils::Id; -#[cfg(feature = "yxi")] +#[cfg(feature = "serialize")] use serde::Serialize; // Returns Vec of `@external` or `ref` memory names @@ -25,7 +25,7 @@ pub fn external_and_ref_memories_cells(comp: &Component) -> Vec> { .collect() } -#[cfg_attr(feature = "yxi", derive(Serialize))] +#[cfg_attr(feature = "serialize", derive(Serialize))] #[derive(Clone, Copy)] pub enum MemoryType { Combinational, diff --git a/fud2/src/lib.rs b/fud2/src/lib.rs index db1103e319..d9f922a14d 100644 --- a/fud2/src/lib.rs +++ b/fud2/src/lib.rs @@ -282,8 +282,7 @@ pub fn build_driver(bld: &mut DriverBuilder) { e.build_cmd(&[only_refs_calyx], "external-to-ref", &[input], &[])?; // Get YXI to generate JSON for testbench generation - e.build_cmd(&[memories_json], "calyx", &[only_externals_calyx], &[])?; - e.arg("backend", "yxi")?; + e.build_cmd(&[memories_json], "yxi", &[only_externals_calyx], &[])?; // generate custom testbench e.build_cmd( &[testbench], @@ -740,15 +739,20 @@ pub fn build_driver(bld: &mut DriverBuilder) { }, ); + let yxi_setup = bld.setup("YXI setup", |e| { + e.config_var_or("yxi", "yxi", "$calyx-base/target/debug/yxi")?; + e.rule("yxi", "$yxi -l $calyx-base $in > $out")?; + Ok(()) + }); + let yxi = bld.state("yxi", &["yxi"]); bld.op( "calyx-to-yxi", - &[calyx_setup], + &[calyx_setup, yxi_setup], calyx, yxi, |e, input, output| { - e.build_cmd(&[output], "calyx", &[input], &[])?; - e.arg("backend", "yxi")?; + e.build_cmd(&[output], "yxi", &[input], &[])?; Ok(()) }, ); @@ -762,6 +766,7 @@ pub fn build_driver(bld: &mut DriverBuilder) { "$calyx-base/yxi/axi-calyx/axi-generator.py", )?; e.config_var_or("python", "python", "python3")?; + e.rule("gen-axi", "$python $axi-generator $in > $out")?; // Define a simple `combine` rule that just concatenates any numer of files. @@ -775,7 +780,7 @@ pub fn build_driver(bld: &mut DriverBuilder) { }); bld.op( "axi-wrapped", - &[calyx_setup, wrapper_setup], + &[calyx_setup, yxi_setup, wrapper_setup], calyx, calyx, |e, input, output| { @@ -790,11 +795,8 @@ pub fn build_driver(bld: &mut DriverBuilder) { .0; // Get yxi file from main compute program. - // TODO(nate): Eventually (#1952) This will be able to use the `yxi` operation - // instead of hardcoding the build cmd calyx rule with arguments let tmp_yxi = format!("{}.yxi", file_name); - e.build_cmd(&[&tmp_yxi], "calyx", &[input], &[])?; - e.arg("backend", "yxi")?; + e.build_cmd(&[&tmp_yxi], "yxi", &[input], &[])?; // Generate the AXI wrapper. let refified_calyx = format!("refified_{}.futil", file_name); diff --git a/fud2/tests/snapshots/tests__emit@calyx_firrtl_verilog-refmem.snap b/fud2/tests/snapshots/tests__emit@calyx_firrtl_verilog-refmem.snap index fc3b42190f..464045381e 100644 --- a/fud2/tests/snapshots/tests__emit@calyx_firrtl_verilog-refmem.snap +++ b/fud2/tests/snapshots/tests__emit@calyx_firrtl_verilog-refmem.snap @@ -38,8 +38,7 @@ rule add-verilog-primitives # build targets build external.futil: ref-to-external stdin build ref.futil: external-to-ref stdin -build memory-info.json: calyx external.futil - backend = yxi +build memory-info.json: yxi external.futil build tb.sv: generate-refmem-testbench memory-info.json build tmp-out.fir: calyx ref.futil backend = firrtl diff --git a/runt.toml b/runt.toml index d66bdebb00..4327933e05 100644 --- a/runt.toml +++ b/runt.toml @@ -58,12 +58,18 @@ flags=$(head -n 1 {} | cut -c 3-) ./target/debug/calyx {} $flags -l . """ -#yxi is not part of [core] [[tests]] -name = "yxi backend" -paths = ["yxi/tests/backend/*.futil"] +name = "yxi tool" +paths = ["yxi/tests/yxi-tool/*.futil"] cmd = """ -./target/debug/calyx {} -b yxi +./target/debug/yxi {} +""" + +[[tests]] +name = "fud2 yxi" +paths = ["yxi/tests/ref-mems-vec-add.futil"] +cmd = """ +fud2 {} --from calyx --to yxi """ ##### Frontend Tests ##### @@ -549,7 +555,7 @@ fud e {} -s verilog.cycle_limit 500 \ ##### Calyx AXI tests ##### [[tests]] name = "calyx-py AXI wrapper generation" -paths = ["yxi/tests/*.yxi"] +paths = ["yxi/tests/axi/*.yxi"] cmd = """ python3 yxi/axi-calyx/axi-generator.py {} """ @@ -557,23 +563,23 @@ python3 yxi/axi-calyx/axi-generator.py {} #Ignore fud2 stderr for now due to ninja nondeterminism [[tests]] name = "fud2 AXI wrapper invocation" -paths = ["yxi/tests/fud2/seq-mem-vec-add.futil"] +paths = ["yxi/tests/axi/seq-mem-vec-add.futil"] cmd = """ fud2 {} --to calyx --through axi-wrapped 2> /dev/null """ [[tests]] name = "fud2 AXI-wrapped to verilog" -paths = ["yxi/tests/fud2/seq-mem-vec-add-axi-wrapped.futil"] +paths = ["yxi/tests/axi/seq-mem-vec-add-axi-wrapped.futil"] cmd = """ fud2 {} --from calyx --to verilog-noverify 2> /dev/null """ [[tests]] name = "fud2 cocotb execution" -paths = ["yxi/tests/fud2/seq-mem-vec-add-verilog.v"] +paths = ["yxi/tests/axi/seq-mem-vec-add-verilog.v"] cmd = """ -fud2 {} --from verilog-noverify --to cocotb-axi --set sim.data=yxi/tests/fud2/vectorized-add.data 2> /dev/null +fud2 {} --from verilog-noverify --to cocotb-axi --set sim.data=yxi/tests/axi/vectorized-add.data 2> /dev/null """ ##### Xilinx Tests ###### diff --git a/src/cmdline.rs b/src/cmdline.rs index 0461823de1..108bb87107 100644 --- a/src/cmdline.rs +++ b/src/cmdline.rs @@ -2,8 +2,6 @@ use argh::FromArgs; #[cfg(feature = "serialize")] use calyx_backend::SexpBackend; -#[cfg(feature = "yxi")] -use calyx_backend::YxiBackend; use calyx_backend::{ xilinx::{XilinxInterfaceBackend, XilinxXmlBackend}, Backend, BackendOpt, FirrtlBackend, MlirBackend, PrimitiveUsesBackend, @@ -173,11 +171,6 @@ impl Opts { let backend = XilinxXmlBackend; backend.run(context, self.output) } - #[cfg(feature = "yxi")] - BackendOpt::Yxi => { - let backend = YxiBackend; - backend.run(context, self.output) - } BackendOpt::Firrtl => { let backend = FirrtlBackend; backend.run(context, self.output) diff --git a/tools/data_gen/src/main.rs b/tools/data_gen/src/main.rs index 504af86470..936f702d76 100644 --- a/tools/data_gen/src/main.rs +++ b/tools/data_gen/src/main.rs @@ -77,11 +77,7 @@ fn main() -> CalyxResult<()> { let ws = frontend::Workspace::construct(&p.file_path, &p.lib_path)?; let ctx: ir::Context = ir::from_ast::ast_to_ir(ws)?; - let comp = ctx - .components - .into_iter() - .find(|comp| comp.name == ctx.entrypoint) - .expect("No top-level component found."); + let comp = ctx.entrypoint(); let data_vec: Vec = comp.cells.iter().filter_map(get_data).collect(); diff --git a/tools/yxi/Cargo.toml b/tools/yxi/Cargo.toml new file mode 100644 index 0000000000..0d7e5ae883 --- /dev/null +++ b/tools/yxi/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "yxi" +authors.workspace = true +license-file.workspace = true +keywords.workspace = true +repository.workspace = true +readme.workspace = true +description.workspace = true +categories.workspace = true +homepage.workspace = true +edition.workspace = true +version.workspace = true +rust-version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde.workspace = true +argh.workspace = true +serde_json = "1.0.79" + +calyx-utils = { path = "../../calyx-utils" } +calyx-frontend = { path = "../../calyx-frontend" } +calyx-opt = { path = "../../calyx-opt" } + +[dependencies.calyx-ir] +path = "../../calyx-ir" +features = ["serialize"] diff --git a/tools/yxi/src/main.rs b/tools/yxi/src/main.rs new file mode 100644 index 0000000000..cb558f1287 --- /dev/null +++ b/tools/yxi/src/main.rs @@ -0,0 +1,81 @@ +use argh::FromArgs; +use calyx_frontend as frontend; +use calyx_ir as ir; +use calyx_ir::utils::{GetMemInfo, MemoryType}; +use calyx_utils::CalyxResult; +use serde::Serialize; +use std::path::{Path, PathBuf}; + +#[derive(FromArgs)] +/// Path for library and path for file to read from +struct Args { + /// file path to read data from + #[argh(positional, from_str_fn(read_path))] + file_path: Option, + + /// library path + #[argh(option, short = 'l', default = "Path::new(\".\").into()")] + pub lib_path: PathBuf, +} + +fn read_path(path: &str) -> Result { + Ok(Path::new(path).into()) +} + +/// Backend that generates the YXI Interface Definition Language. +/// YXI aims to be a description of toplevel hardware modules that we can then consume +/// to create things like AXI wrappers on arbitrary programs +#[derive(Default)] +pub struct YxiBackend; + +#[derive(Serialize)] +struct ProgramInterface<'a> { + toplevel: &'a str, + memories: Vec>, +} + +#[derive(Serialize)] +struct Memory<'a> { + name: &'a str, + memory_type: MemoryType, + data_width: u64, + dimensions: u64, + dimension_sizes: Vec, + total_size: u64, //number of cells in memory + idx_sizes: Vec, +} + +fn main() -> CalyxResult<()> { + let p: Args = argh::from_env(); + + let ws = frontend::Workspace::construct(&p.file_path, &p.lib_path)?; + let ctx: ir::Context = ir::from_ast::ast_to_ir(ws)?; + + let toplevel = ctx.entrypoint(); + + let memory_names = ir::utils::external_and_ref_memories_names(toplevel); + let mem_infos = toplevel.get_mem_info(); + + let memories: Vec = memory_names + .iter() + .zip(mem_infos.iter()) + .map(|(memory_name, mem_info)| Memory { + name: memory_name, + memory_type: mem_info.memory_type, + data_width: mem_info.data_width, + dimensions: mem_info.dimensions, + dimension_sizes: mem_info.dimension_sizes.clone(), + total_size: mem_info.total_size, + idx_sizes: mem_info.idx_sizes.clone(), + }) + .collect(); + + let program_interface = ProgramInterface { + toplevel: toplevel.name.as_ref(), + memories, + }; + + serde_json::to_writer_pretty(std::io::stdout(), &program_interface)?; + + Ok(()) +} diff --git a/yxi/tests/fud2/seq-mem-vec-add-axi-wrapped.expect b/yxi/tests/axi/seq-mem-vec-add-axi-wrapped.expect similarity index 100% rename from yxi/tests/fud2/seq-mem-vec-add-axi-wrapped.expect rename to yxi/tests/axi/seq-mem-vec-add-axi-wrapped.expect diff --git a/yxi/tests/fud2/seq-mem-vec-add-axi-wrapped.futil b/yxi/tests/axi/seq-mem-vec-add-axi-wrapped.futil similarity index 100% rename from yxi/tests/fud2/seq-mem-vec-add-axi-wrapped.futil rename to yxi/tests/axi/seq-mem-vec-add-axi-wrapped.futil diff --git a/yxi/tests/fud2/seq-mem-vec-add-verilog.expect b/yxi/tests/axi/seq-mem-vec-add-verilog.expect similarity index 100% rename from yxi/tests/fud2/seq-mem-vec-add-verilog.expect rename to yxi/tests/axi/seq-mem-vec-add-verilog.expect diff --git a/yxi/tests/fud2/seq-mem-vec-add-verilog.v b/yxi/tests/axi/seq-mem-vec-add-verilog.v similarity index 100% rename from yxi/tests/fud2/seq-mem-vec-add-verilog.v rename to yxi/tests/axi/seq-mem-vec-add-verilog.v diff --git a/yxi/tests/fud2/seq-mem-vec-add.expect b/yxi/tests/axi/seq-mem-vec-add.expect similarity index 100% rename from yxi/tests/fud2/seq-mem-vec-add.expect rename to yxi/tests/axi/seq-mem-vec-add.expect diff --git a/yxi/tests/fud2/seq-mem-vec-add.futil b/yxi/tests/axi/seq-mem-vec-add.futil similarity index 100% rename from yxi/tests/fud2/seq-mem-vec-add.futil rename to yxi/tests/axi/seq-mem-vec-add.futil diff --git a/yxi/tests/seq-vec-add.expect b/yxi/tests/axi/seq-vec-add.expect similarity index 100% rename from yxi/tests/seq-vec-add.expect rename to yxi/tests/axi/seq-vec-add.expect diff --git a/yxi/tests/seq-vec-add.yxi b/yxi/tests/axi/seq-vec-add.yxi similarity index 100% rename from yxi/tests/seq-vec-add.yxi rename to yxi/tests/axi/seq-vec-add.yxi diff --git a/yxi/tests/fud2/vectorized-add.data b/yxi/tests/axi/vectorized-add.data similarity index 100% rename from yxi/tests/fud2/vectorized-add.data rename to yxi/tests/axi/vectorized-add.data diff --git a/yxi/tests/backend/dot-product.expect b/yxi/tests/yxi-tool/dot-product.expect similarity index 100% rename from yxi/tests/backend/dot-product.expect rename to yxi/tests/yxi-tool/dot-product.expect diff --git a/yxi/tests/backend/dot-product.futil b/yxi/tests/yxi-tool/dot-product.futil similarity index 100% rename from yxi/tests/backend/dot-product.futil rename to yxi/tests/yxi-tool/dot-product.futil diff --git a/yxi/tests/backend/dyn-mem-d4-add.expect b/yxi/tests/yxi-tool/dyn-mem-d4-add.expect similarity index 100% rename from yxi/tests/backend/dyn-mem-d4-add.expect rename to yxi/tests/yxi-tool/dyn-mem-d4-add.expect diff --git a/yxi/tests/backend/dyn-mem-d4-add.futil b/yxi/tests/yxi-tool/dyn-mem-d4-add.futil similarity index 100% rename from yxi/tests/backend/dyn-mem-d4-add.futil rename to yxi/tests/yxi-tool/dyn-mem-d4-add.futil diff --git a/yxi/tests/yxi-tool/ref-mems-vec-add.expect b/yxi/tests/yxi-tool/ref-mems-vec-add.expect new file mode 100644 index 0000000000..be03947be1 --- /dev/null +++ b/yxi/tests/yxi-tool/ref-mems-vec-add.expect @@ -0,0 +1,44 @@ +{ + "toplevel": "main", + "memories": [ + { + "name": "A0", + "memory_type": "Dynamic", + "data_width": 32, + "dimensions": 1, + "dimension_sizes": [ + 8 + ], + "total_size": 8, + "idx_sizes": [ + 3 + ] + }, + { + "name": "B0", + "memory_type": "Combinational", + "data_width": 32, + "dimensions": 1, + "dimension_sizes": [ + 8 + ], + "total_size": 8, + "idx_sizes": [ + 3 + ] + }, + { + "name": "Sum0", + "memory_type": "Sequential", + "data_width": 32, + "dimensions": 1, + "dimension_sizes": [ + 8 + ], + "total_size": 8, + "idx_sizes": [ + 3 + ] + } + ] +} \ No newline at end of file diff --git a/yxi/tests/yxi-tool/ref-mems-vec-add.futil b/yxi/tests/yxi-tool/ref-mems-vec-add.futil new file mode 100644 index 0000000000..cb1c638ead --- /dev/null +++ b/yxi/tests/yxi-tool/ref-mems-vec-add.futil @@ -0,0 +1,86 @@ +import "primitives/core.futil"; +import "primitives/memories/dyn.futil"; +import "primitives/memories/seq.futil"; +import "primitives/memories/comb.futil"; +component main() -> () { + cells { + //Modified to 64 width address because XRT expects 64 bit memory addresses + ref A0 = dyn_mem_d1(32,8,3); + A_read0_0 = std_reg(32); + ref B0 = comb_mem_d1(32,8,3); + B_read0_0 = std_reg(32); + ref Sum0 = seq_mem_d1(32,8,3); + add0 = std_add(32); + add1 = std_add(4); + const0 = std_const(4,0); + const1 = std_const(4,7); + const2 = std_const(4,1); + i0 = std_reg(4); + le0 = std_le(4); + bit_slice = std_bit_slice(4,0,2,3); + } + wires { + A0.write_en = 1'b0; + B0.write_en = 1'b0; + + bit_slice.in = i0.out; + comb group cond0 { + le0.left = i0.out; + le0.right = const1.out; + } + group let0<"static"=1> { + i0.in = const0.out; + i0.write_en = 1'd1; + let0[done] = i0.done; + } + //modified upd0 and upd1 to use seq_mem correctly + group upd0<"static"=2> { + A_read0_0.write_en = A0.done; + A0.addr0 = bit_slice.out; + A0.content_en = 1'b1; + A_read0_0.in = 1'd1 ? A0.read_data; + upd0[done] = A_read0_0.done ? 1'd1; + } + //see comment for upd0 + group upd1<"static"=2> { + B_read0_0.write_en = B0.done; + B0.addr0 = bit_slice.out; + B_read0_0.in = 1'd1 ? B0.read_data; + upd1[done] = B_read0_0.done ? 1'd1; + } + group upd2<"static"=1> { + Sum0.addr0 = bit_slice.out; + Sum0.content_en = 1'd1; + Sum0.write_en = 1'd1; + B0.addr0 = bit_slice.out; + A0.addr0 = bit_slice.out; + A0.content_en = 1'b1; + add0.left = B_read0_0.out; + add0.right = A_read0_0.out; + Sum0.write_data = 1'd1 ? add0.out; + upd2[done] = Sum0.done ? 1'd1; + } + group upd3<"static"=1> { + i0.write_en = 1'd1; + add1.left = i0.out; + add1.right = const2.out; + i0.in = 1'd1 ? add1.out; + upd3[done] = i0.done ? 1'd1; + } + } + control { + seq { + let0; + while le0.out with cond0 { + seq { + par { + upd0; + upd1; + } + upd2; + upd3; + } + } + } + } +} diff --git a/yxi/tests/backend/seq-mem-d4-add.expect b/yxi/tests/yxi-tool/seq-mem-d4-add.expect similarity index 100% rename from yxi/tests/backend/seq-mem-d4-add.expect rename to yxi/tests/yxi-tool/seq-mem-d4-add.expect diff --git a/yxi/tests/backend/seq-mem-d4-add.futil b/yxi/tests/yxi-tool/seq-mem-d4-add.futil similarity index 100% rename from yxi/tests/backend/seq-mem-d4-add.futil rename to yxi/tests/yxi-tool/seq-mem-d4-add.futil