Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spade): Improve docs and API #11

Merged
merged 3 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 70 additions & 1 deletion docs/testing_spade.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,73 @@ dumbname. You can find the full source code for this tutorial [here](../spade-su

I'll be assuming you've read the [tutorial on testing Verilog projects](./testing_verilog.md); if not, read that first and come back.

TODO
If you don't already have Spade installed, [make sure to do that](https://docs.spade-lang.org/installation.html).
You can either integrate dumbname into an existing [Swim](https://docs.spade-lang.org/swim/index.html) project at no effort or (in this case) make a new Swim project from scratch with an eye to dumbname.

```shell
swim init tutorial-project
cd tutorial-project
git init # optional, if using git
```

In `main.spade` we'll write some simple Spade code:

```rust
// file: src/main.spade
#[no_mangle(all)]
entity main(out: inv &int<8>) {
set out = 42;
}}
```

You can read the [Spade book](https://docs.spade-lang.org/introduction.html) for an
introduction to Spade; this tutorial will not focus on teaching the language.
Nonetheless, the essence of the above code is to expose an inverted wire which
we pin to the value `42` (think of `assign`ing to an `output` in Verilog).

Then, we'll make a new crate to use dumbname:

```shell
cargo init --bin --name swim_tests test
vi test/main.rs
```

In the `Cargo.toml`, we'll add the `spade` dependency:

```toml
[dependencies]
# other dependencies...
spade = { git = "https://github.com/ethanuppal/dumbname" }
snafu = "0.8.5" # optional, whatever version
colog = "1.3.0" # optional, whatever version
```

Our testing code will be similar to the Verilog code:

```rust
// test/src/main.rs
use snafu::Whatever;
use spade::{spade, SpadeRuntime};

#[spade(src = "src/main.spade", name = "main")]
struct Main;

#[snafu::report]
fn main() -> Result<(), Whatever> {
colog::init();

// the first `true` says we want to automatically compile the Spade
// the second `true` says we want debug logging
let mut runtime = SpadeRuntime::new(true, true)?;

let mut main = runtime.create_model::<Main>()?;

main.eval();
println!("{}", main.out);
assert_eq!(main.out, 42); // hardcoded into Spade source

Ok(())
}
```

A `cargo run` from the project root lets us test our Spade!
2 changes: 1 addition & 1 deletion spade-support/example-project/test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct Main;
fn main() -> Result<(), Whatever> {
colog::init();

let mut runtime = SpadeRuntime::new("artifacts".into(), true, true)?;
let mut runtime = SpadeRuntime::new(true, true)?;

let mut main = runtime.create_model::<Main>()?;

Expand Down
25 changes: 11 additions & 14 deletions spade-support/spade/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub use verilog::__reexports;

use std::{env::current_dir, process::Command};

use camino::{Utf8Path, Utf8PathBuf};
use camino::Utf8PathBuf;
use snafu::{whatever, ResultExt, Whatever};
use verilog::{VerilatorRuntime, __reexports::verilator::VerilatedModel};

Expand All @@ -22,11 +22,7 @@ pub struct SpadeRuntime {
}

impl SpadeRuntime {
pub fn new(
artifact_directory: &Utf8Path,
call_swim_build: bool,
verbose: bool,
) -> Result<Self, Whatever> {
pub fn new(call_swim_build: bool, verbose: bool) -> Result<Self, Whatever> {
if verbose {
log::info!("Searching for swim project root");
}
Expand All @@ -38,18 +34,20 @@ impl SpadeRuntime {
"Failed to convert current directory to UTF-8",
)?,
) else {
whatever!("Failed to find swim.toml");
whatever!(
"Failed to find swim.toml searching from current directory"
);
};
let mut swim_project_path = swim_toml_path;
swim_project_path.pop();

if call_swim_build {
if verbose {
log::info!("Invoking `swim build` (this may take a while)");
}
let mut swim_project_path = swim_toml_path.clone();
swim_project_path.pop();
let swim_output = Command::new("swim")
.arg("build")
.current_dir(swim_project_path)
.current_dir(&swim_project_path)
.output()
.whatever_context("Invocation of swim failed")?;

Expand All @@ -63,13 +61,12 @@ impl SpadeRuntime {
}
}

let mut spade_sv_path = swim_toml_path;
spade_sv_path.pop();
spade_sv_path.push("build/spade.sv");
let spade_sv_path = swim_project_path.join("build/spade.sv");

Ok(Self {
verilator_runtime: VerilatorRuntime::new(
artifact_directory,
// https://discord.com/channels/962274366043873301/962296357018828822/1332274022280466503
&swim_project_path.join("build/thirdparty"),
&[&spade_sv_path],
verbose,
)?,
Expand Down
Loading