try to detect bad arcs in partitioner

This commit is contained in:
SpaceCat-Chan 2022-12-11 14:09:24 +01:00 committed by Lofty
parent 000ad6d539
commit 0a570f418d
2 changed files with 78 additions and 20 deletions

View File

@ -209,10 +209,11 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
let mut new_partitions = Vec::with_capacity(partitions.len() * 4);
for (min, max, partition, name) in &partitions {
log_info!("partition {}:\n", name);
let (x_part, y_part, ne, se, sw, nw) = partition::find_partition_point_and_sanity_check(
ctx, &nets, partition, pips, min.x, max.x, min.y, max.y,
);
new_partitions.push((*min, Coord::new(x_part, y_part), ne, format!("{}_NE", name)));
let (x_part, y_part, ne, se, sw, nw, special) =
partition::find_partition_point_and_sanity_check(
ctx, &nets, partition, pips, min.x, max.x, min.y, max.y,
);
special_arcs.extend(special.into_iter());
new_partitions.push((
Coord::new(x_part, min.y),
Coord::new(max.x, y_part),
@ -220,6 +221,7 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
format!("{}_SE", name),
));
new_partitions.push((Coord::new(x_part, y_part), *max, sw, format!("{}_SW", name)));
new_partitions.push((*min, Coord::new(x_part, y_part), ne, format!("{}_NE", name)));
new_partitions.push((
Coord::new(min.x, y_part),
Coord::new(x_part, max.y),
@ -233,6 +235,11 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
let time = format!("{:.2}", (Instant::now() - start).as_secs_f32());
log_info!("Partitioning took {}s\n", time.bold());
log_info!(
"now {} arcs special-cased\n",
special_arcs.len().to_string().bold()
);
log_info!(
"Using pressure factor {} and history factor {}\n",
pressure,

View File

@ -14,7 +14,7 @@ use crate::{
route::Arc,
};
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Quadrant {
Northeast,
Southeast,
@ -22,7 +22,7 @@ pub enum Quadrant {
Northwest,
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Direction {
North,
South,
@ -30,14 +30,14 @@ pub enum Direction {
West,
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FullSegment {
Quadrant(Quadrant),
Direction(Direction),
Exact,
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Axis {
NorthSouth,
EastWest,
@ -201,7 +201,7 @@ pub fn find_partition_point(
x_finish: i32,
y_start: i32,
y_finish: i32,
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
let mut x = ((x_finish - x_start) / 2) + x_start;
let mut y = ((y_finish - y_start) / 2) + y_start;
let mut x_diff = 0; //(x_finish - x_start) / 4;
@ -244,7 +244,7 @@ pub fn find_partition_point(
y_diff >>= 1;
}
let (ne, se, sw, nw) = partition(
let (ne, se, sw, nw, special) = partition(
ctx,
nets,
arcs,
@ -269,7 +269,7 @@ pub fn find_partition_point(
100.0 * (ne_dist + se_dist + sw_dist + nw_dist)
);
(x, y, ne, se, sw, nw)
(x, y, ne, se, sw, nw, special)
}
fn approximate_partition_results(
@ -430,7 +430,7 @@ fn partition(
y: i32,
x_bounds: (i32, i32),
y_bounds: (i32, i32),
) -> (Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
) -> (Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
let min_bounds = Coord::new(x_bounds.0, y_bounds.0);
let max_bounds = Coord::new(x_bounds.1, y_bounds.1);
let partition_coords = Coord::new(x, y);
@ -439,6 +439,7 @@ fn partition(
let mut se: Vec<Arc> = Vec::new();
let mut sw: Vec<Arc> = Vec::new();
let mut nw: Vec<Arc> = Vec::new();
let special = Mutex::new(Vec::new());
let mut part_horiz = AtomicUsize::new(0);
let mut part_vert = AtomicUsize::new(0);
let mut part_diag = AtomicUsize::new(0);
@ -467,6 +468,50 @@ fn partition(
progress.set_message(format!("overused wires: {}", overused_wires));
let mut bad_nets = std::collections::HashSet::new();
let is_general_routing = |wire: &str| {
wire.contains("H00")
|| wire.contains("V00")
|| wire.contains("H01")
|| wire.contains("V01")
|| wire.contains("H02")
|| wire.contains("V02")
|| wire.contains("H06")
|| wire.contains("V06")
};
for arc in arcs {
if bad_nets.contains(&arc.net()) {
continue;
}
let source_loc = arc.get_source_loc();
let source_coords: Coord = source_loc.into();
let sink_loc = arc.get_sink_loc();
let sink_coords: Coord = sink_loc.into();
// test for annoying special case
let mut have_any_in_same_segment = false;
for pip in ctx.get_downhill_pips(arc.get_source_wire()) {
let pip_coord: Coord = ctx.pip_location(pip).into();
let pip_seg = pip_coord.segment_from(&partition_coords);
have_any_in_same_segment |= pip_seg == source_coords.segment_from(&partition_coords)
}
if !have_any_in_same_segment {
bad_nets.insert(arc.net());
}
let mut have_any_in_same_segment = false;
for pip in ctx.get_uphill_pips(arc.get_sink_wire()) {
let pip_coord: Coord = ctx.pip_location(pip).into();
let pip_seg = pip_coord.segment_from(&partition_coords);
have_any_in_same_segment |= pip_seg == sink_coords.segment_from(&partition_coords)
}
if !have_any_in_same_segment {
bad_nets.insert(arc.net());
}
}
let arcs = arcs
.into_par_iter()
.progress_with(progress)
@ -486,6 +531,12 @@ fn partition(
.unwrap()
.to_string();
let verbose = false; //name == "soc0.processor.with_fpu.fpu_0.fpu_multiply_0.rin_CCU2C_S0_4$CCU2_FCI_INT";
if bad_nets.contains(&arc.net()) {
special.lock().unwrap().push(arc.clone());
return vec![];
}
if source_is_north == sink_is_north && source_is_east == sink_is_east {
let seg = source_coords.segment_from(&partition_coords);
vec![(seg, arc.clone())]
@ -798,7 +849,7 @@ fn partition(
dist_str(nw_dist)
);
(ne, se, sw, nw)
(ne, se, sw, nw, special.into_inner().unwrap())
}
fn partition_single_arc(
@ -844,13 +895,13 @@ pub fn find_partition_point_and_sanity_check(
x_finish: i32,
y_start: i32,
y_finish: i32,
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
println!(
"bounds: {:?} -> {:?}",
(x_start, y_start),
(x_finish, y_finish)
);
let (x_part, y_part, ne, se, sw, nw) =
let (x_part, y_part, ne, se, sw, nw, special) =
find_partition_point(ctx, nets, arcs, pips, x_start, x_finish, y_start, y_finish);
let mut invalid_arcs_in_ne = 0;
@ -986,7 +1037,7 @@ pub fn find_partition_point_and_sanity_check(
);
}
(x_part, y_part, ne, se, sw, nw)
(x_part, y_part, ne, se, sw, nw, special)
}
struct PipSelector {
@ -1082,7 +1133,7 @@ impl PipSelector {
src_has_west |= src_pip_coord.is_west_of(&partition_point.into());
if src_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
pips.push((src_pip, depth + 1));
//pips.push((src_pip, depth + 1));
}
}
}
@ -1101,7 +1152,7 @@ impl PipSelector {
dst_has_west |= dst_pip_coord.is_west_of(&partition_point.into());
if dst_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
pips.push((dst_pip, depth + 1));
//pips.push((dst_pip, depth + 1));
}
}
}
@ -1149,7 +1200,7 @@ impl PipSelector {
if src_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
// yaaaaaaay, we need to everything again for this pip :)
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
pips.push((src_pip, depth + 1));
//pips.push((src_pip, depth + 1));
}
}
}
@ -1168,7 +1219,7 @@ impl PipSelector {
dst_has_south |= dst_pip_coord.is_south_of(&partition_point.into());
if dst_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
pips.push((dst_pip, depth + 1));
//pips.push((dst_pip, depth + 1));
}
}
}