test: test the number of navmesh vertices

This commit is contained in:
Mikolaj Wielgus 2024-12-07 05:38:45 +01:00
parent ac2b664901
commit df1578a094
3 changed files with 95 additions and 35 deletions

View File

@ -8,19 +8,28 @@ use topola::{
Autorouter, Autorouter,
}, },
board::{mesadata::AccessMesadata, Board}, board::{mesadata::AccessMesadata, Board},
drawing::graph::{GetLayer, GetMaybeNet}, drawing::{
geometry::shape::MeasureLength, dot::FixedDotIndex,
graph::{GetLayer, GetMaybeNet},
},
geometry::{shape::MeasureLength, GenericNode},
graph::{GetPetgraphIndex, MakeRef}, graph::{GetPetgraphIndex, MakeRef},
layout::LayoutEdit, layout::LayoutEdit,
router::{navmesh::Navmesh, RouterOptions},
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata}, specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
}; };
pub fn load_design_and_assert(filename: &str) -> Invoker<SpecctraMesadata> { pub fn load_design(filename: &str) -> Autorouter<SpecctraMesadata> {
let design_file = File::open(filename).unwrap(); let design_file = File::open(filename).unwrap();
let design_bufread = BufReader::new(design_file); let design_bufread = BufReader::new(design_file);
let design = SpecctraDesign::load(design_bufread).unwrap(); let design = SpecctraDesign::load(design_bufread).unwrap();
let mut invoker = Autorouter::new(design.make_board(&mut LayoutEdit::new())).unwrap()
Invoker::new(Autorouter::new(design.make_board(&mut LayoutEdit::new())).unwrap()); }
pub fn create_invoker_and_assert(
autorouter: Autorouter<SpecctraMesadata>,
) -> Invoker<SpecctraMesadata> {
let mut invoker = Invoker::new(autorouter);
assert!(matches!( assert!(matches!(
invoker.undo(), invoker.undo(),
@ -60,6 +69,50 @@ pub fn replay_and_assert(invoker: &mut Invoker<SpecctraMesadata>, filename: &str
); );
} }
pub fn assert_navvertex_count(
autorouter: &mut Autorouter<SpecctraMesadata>,
origin_pin: &str,
destination_pin: &str,
expected_count: usize,
) {
let (origin, destination) = autorouter
.ratsnest()
.graph()
.edge_indices()
.collect::<Vec<_>>()
.iter()
.find_map(|ratline| {
let (candidate_origin, candidate_destination) = autorouter.ratline_endpoints(*ratline);
let candidate_origin_pin = autorouter
.board()
.node_pinname(&GenericNode::Primitive(candidate_origin.into()))
.unwrap();
let candidate_destination_pin = autorouter
.board()
.node_pinname(&GenericNode::Primitive(candidate_destination.into()))
.unwrap();
((candidate_origin_pin == origin_pin && candidate_destination_pin == destination_pin)
|| (candidate_origin_pin == destination_pin
&& candidate_destination_pin == origin_pin))
.then_some((candidate_origin, candidate_destination))
})
.unwrap();
let navmesh = Navmesh::new(
autorouter.board().layout(),
origin,
destination,
RouterOptions {
wrap_around_bands: true,
squeeze_through_under_bands: false,
routed_band_width: 100.0,
},
)
.unwrap();
assert_eq!(navmesh.graph().node_count(), expected_count);
}
pub fn assert_single_layer_groundless_autoroute( pub fn assert_single_layer_groundless_autoroute(
autorouter: &mut Autorouter<impl AccessMesadata>, autorouter: &mut Autorouter<impl AccessMesadata>,
layername: &str, layername: &str,
@ -67,64 +120,64 @@ pub fn assert_single_layer_groundless_autoroute(
let unionfind = unionfind(autorouter); let unionfind = unionfind(autorouter);
for ratline in autorouter.ratsnest().graph().edge_indices() { for ratline in autorouter.ratsnest().graph().edge_indices() {
let (source_dot, target_dot) = autorouter.ratline_endpoints(ratline); let (origin_dot, destination_dot) = autorouter.ratline_endpoints(ratline);
let source_layer = autorouter let origin_layer = autorouter
.board() .board()
.layout() .layout()
.drawing() .drawing()
.primitive(source_dot) .primitive(origin_dot)
.layer(); .layer();
let target_layer = autorouter let destination_layer = autorouter
.board() .board()
.layout() .layout()
.drawing() .drawing()
.primitive(target_dot) .primitive(destination_dot)
.layer(); .layer();
if let (Some(source_layername), Some(target_layername)) = ( if let (Some(origin_layername), Some(destination_layername)) = (
autorouter autorouter
.board() .board()
.layout() .layout()
.rules() .rules()
.layer_layername(source_layer), .layer_layername(origin_layer),
autorouter autorouter
.board() .board()
.layout() .layout()
.rules() .rules()
.layer_layername(target_layer), .layer_layername(destination_layer),
) { ) {
assert_eq!(source_layername, target_layername); assert_eq!(origin_layername, destination_layername);
if source_layername != layername { if origin_layername != layername {
continue; continue;
} }
} else { } else {
assert!(false); assert!(false);
} }
let source_net = autorouter let origin_net = autorouter
.board() .board()
.layout() .layout()
.drawing() .drawing()
.primitive(source_dot) .primitive(origin_dot)
.maybe_net(); .maybe_net();
let target_net = autorouter let destination_net = autorouter
.board() .board()
.layout() .layout()
.drawing() .drawing()
.primitive(target_dot) .primitive(destination_dot)
.maybe_net(); .maybe_net();
assert_eq!(source_net, target_net); assert_eq!(origin_net, destination_net);
let net = source_net.unwrap(); let net = origin_net.unwrap();
if let Some(netname) = autorouter.board().layout().rules().net_netname(net) { if let Some(netname) = autorouter.board().layout().rules().net_netname(net) {
// We don't route ground. // We don't route ground.
if netname != "GND" { if netname != "GND" {
assert_eq!( assert_eq!(
unionfind.find(source_dot.petgraph_index()), unionfind.find(origin_dot.petgraph_index()),
unionfind.find(target_dot.petgraph_index()) unionfind.find(destination_dot.petgraph_index())
); );
} }
} }
@ -145,12 +198,12 @@ pub fn assert_single_layer_groundless_autoroute(
pub fn assert_band_length( pub fn assert_band_length(
board: &Board<impl AccessMesadata>, board: &Board<impl AccessMesadata>,
source: &str, source_pin: &str,
target: &str, target_pin: &str,
expected_length: f64, expected_length: f64,
rel_err: f64, rel_err: f64,
) { ) {
let band = board.band_between_pins(source, target).unwrap(); let band = board.band_between_pins(source_pin, target_pin).unwrap();
let band_length = band.0.ref_(board.layout().drawing()).length(); let band_length = band.0.ref_(board.layout().drawing()).length();
assert!( assert!(
(band_length - expected_length).abs() < expected_length * rel_err, (band_length - expected_length).abs() < expected_length * rel_err,

View File

@ -9,9 +9,9 @@ mod common;
#[test] #[test]
fn test_unrouted_lm317_breakout() { fn test_unrouted_lm317_breakout() {
let mut invoker = common::load_design_and_assert( let mut invoker = common::create_invoker_and_assert(common::load_design(
"tests/multilayer/prerouted_lm317_breakout/unrouted_lm317_breakout.dsn", "tests/multilayer/prerouted_lm317_breakout/unrouted_lm317_breakout.dsn",
); ));
let result = invoker.execute(Command::PlaceVia(ViaWeight { let result = invoker.execute(Command::PlaceVia(ViaWeight {
from_layer: 0, from_layer: 0,
@ -32,9 +32,9 @@ fn test_unrouted_lm317_breakout() {
#[test] #[test]
fn test_signal_integrity_test() { fn test_signal_integrity_test() {
let invoker = common::load_design_and_assert( let invoker = common::create_invoker_and_assert(common::load_design(
"tests/multilayer/signal_integrity_test/signal_integrity_test.dsn", "tests/multilayer/signal_integrity_test/signal_integrity_test.dsn",
); ));
assert_eq!( assert_eq!(
invoker invoker

View File

@ -12,8 +12,9 @@ mod common;
#[test] #[test]
fn test_0603_breakout() { fn test_0603_breakout() {
let mut invoker = let mut autorouter = common::load_design("tests/single_layer/0603_breakout/0603_breakout.dsn");
common::load_design_and_assert("tests/single_layer/0603_breakout/0603_breakout.dsn"); common::assert_navvertex_count(&mut autorouter, "R1-2", "J1-2", 50);
let mut invoker = common::create_invoker_and_assert(autorouter);
common::replay_and_assert( common::replay_and_assert(
&mut invoker, &mut invoker,
"tests/single_layer/0603_breakout/autoroute_all.cmd", "tests/single_layer/0603_breakout/autoroute_all.cmd",
@ -27,9 +28,11 @@ fn test_0603_breakout() {
#[test] #[test]
fn test_tht_diode_bridge_rectifier() { fn test_tht_diode_bridge_rectifier() {
let mut invoker = common::load_design_and_assert( let mut autorouter = common::load_design(
"tests/single_layer/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn", "tests/single_layer/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn",
); );
common::assert_navvertex_count(&mut autorouter, "J2-2", "D4-2", 56);
let mut invoker = common::create_invoker_and_assert(autorouter);
common::replay_and_assert( common::replay_and_assert(
&mut invoker, &mut invoker,
"tests/single_layer/tht_diode_bridge_rectifier/autoroute_all.cmd", "tests/single_layer/tht_diode_bridge_rectifier/autoroute_all.cmd",
@ -61,9 +64,11 @@ fn test_tht_diode_bridge_rectifier() {
#[test] #[test]
fn test_4x_3rd_order_smd_lc_filters() { fn test_4x_3rd_order_smd_lc_filters() {
let mut invoker = common::load_design_and_assert( let mut autorouter = common::load_design(
"tests/single_layer/4x_3rd_order_smd_lc_filters/4x_3rd_order_smd_lc_filters.dsn", "tests/single_layer/4x_3rd_order_smd_lc_filters/4x_3rd_order_smd_lc_filters.dsn",
); );
common::assert_navvertex_count(&mut autorouter, "J1-1", "L1-1", 1954);
let mut invoker = common::create_invoker_and_assert(autorouter);
common::replay_and_assert( common::replay_and_assert(
&mut invoker, &mut invoker,
"tests/single_layer/4x_3rd_order_smd_lc_filters/autoroute_signals.cmd", "tests/single_layer/4x_3rd_order_smd_lc_filters/autoroute_signals.cmd",
@ -79,9 +84,11 @@ fn test_4x_3rd_order_smd_lc_filters() {
// NOTE: Disabled until determinism is fixed. // NOTE: Disabled until determinism is fixed.
//#[test] //#[test]
fn test_tht_3pin_xlr_to_tht_3pin_xlr() { fn test_tht_3pin_xlr_to_tht_3pin_xlr() {
let mut invoker = common::load_design_and_assert( let mut autorouter = common::load_design(
"tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/tht_3pin_xlr_to_tht_3pin_xlr.dsn", "tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/tht_3pin_xlr_to_tht_3pin_xlr.dsn",
); );
//common::assert_navvertex_count(&mut autorouter, "R1-2", "J1-2", ?);
let mut invoker = common::create_invoker_and_assert(autorouter);
common::replay_and_assert( common::replay_and_assert(
&mut invoker, &mut invoker,
"tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/autoroute_all.cmd", "tests/single_layer/tht_3pin_xlr_to_tht_3pin_xlr/autoroute_all.cmd",