Files
Akhil Velagapudi ac8434ff42 Board-level configuration (#188)
* Add `builtin.add_board_config`

Sets constraints

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Enable json extension

Useful for debugging

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* More compact config mapping

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Add predefined sizes support to board config

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Make all board config fields optional, add merging

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Add netclass support to board config

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Add stackup support, sexpr library

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Patch stackup on `pcb layout`

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Sync board config by default

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Fix deep_merge

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Document board config feature

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Flatten netclasses

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Add base configurations

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Remove unused _is_new_board

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Move board_config.zen to examples/

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Use pcb-sexpr

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

* Replace --dont-sync with --sync (default true)

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>

---------

Signed-off-by: akhilles <akhilvelagapudi@gmail.com>
2025-09-29 15:57:15 -04:00

82 lines
2.8 KiB
Rust

use anyhow::Result;
use assert_fs::prelude::*;
use assert_fs::TempDir;
use pcb_layout::process_layout;
use serial_test::serial;
mod helpers;
use helpers::*;
macro_rules! layout_test {
($name:expr, $board_name:expr) => {
paste::paste! {
#[test]
#[serial]
fn [<test_layout_generation_with_ $name:snake>]() -> Result<()> {
// Create a temp directory and copy the test resources
let temp = TempDir::new()?.into_persistent();
let resource_path = get_resource_path($name);
temp.copy_from(&resource_path, &["**/*", "!.pcb/cache/**/*"])?;
// Find and evaluate the board zen file
let zen_file = temp.path().join(format!("{}.zen", $board_name));
assert!(zen_file.exists(), "{}.zen should exist", $board_name);
// Evaluate the Zen file to generate a schematic
let (output, diagnostics) = pcb_zen::run(&zen_file, pcb_zen::EvalConfig::default()).unpack();
// Check for errors in evaluation
if !diagnostics.is_empty() {
eprintln!("Zen evaluation diagnostics:");
for diag in diagnostics {
eprintln!(" {:?}", diag);
}
}
let schematic = output.expect("Zen evaluation should produce a schematic");
// Process the layout
let result = process_layout(&schematic, &zen_file, false)?;
// Verify the layout was created
assert!(result.pcb_file.exists(), "PCB file should exist");
assert!(result.netlist_file.exists(), "Netlist file should exist");
assert!(result.snapshot_file.exists(), "Snapshot file should exist");
assert!(result.log_file.exists(), "Log file should exist");
// Print the log file contents
let log_contents = std::fs::read_to_string(&result.log_file)?;
println!("Layout log file contents:");
println!("========================");
println!("{}", log_contents);
println!("========================");
// Check the snapshot matches
assert_file_snapshot!(
format!("{}.layout.json", $name),
result.snapshot_file
);
Ok(())
}
}
};
}
// Schematic: A couple BMI270 modules in Starlark.
layout_test!("simple", "MyBoard");
layout_test!("module_layout", "Main");
layout_test!("component_side_sync", "Board");
layout_test!("multi_pads", "MultiPads");
layout_test!("dnp", "MyBoard");
layout_test!("zones", "Board");
layout_test!("graphics", "Board");
layout_test!("complex", "Board");