mirror of https://codeberg.org/topola/topola.git
test: test the number of navmesh vertices
This commit is contained in:
parent
ac2b664901
commit
df1578a094
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue