try to detect bad arcs in partitioner
This commit is contained in:
parent
000ad6d539
commit
0a570f418d
@ -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);
|
let mut new_partitions = Vec::with_capacity(partitions.len() * 4);
|
||||||
for (min, max, partition, name) in &partitions {
|
for (min, max, partition, name) in &partitions {
|
||||||
log_info!("partition {}:\n", name);
|
log_info!("partition {}:\n", name);
|
||||||
let (x_part, y_part, ne, se, sw, nw) = partition::find_partition_point_and_sanity_check(
|
let (x_part, y_part, ne, se, sw, nw, special) =
|
||||||
ctx, &nets, partition, pips, min.x, max.x, min.y, max.y,
|
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)));
|
);
|
||||||
|
special_arcs.extend(special.into_iter());
|
||||||
new_partitions.push((
|
new_partitions.push((
|
||||||
Coord::new(x_part, min.y),
|
Coord::new(x_part, min.y),
|
||||||
Coord::new(max.x, y_part),
|
Coord::new(max.x, y_part),
|
||||||
@ -220,6 +221,7 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
|
|||||||
format!("{}_SE", name),
|
format!("{}_SE", name),
|
||||||
));
|
));
|
||||||
new_partitions.push((Coord::new(x_part, y_part), *max, sw, format!("{}_SW", 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((
|
new_partitions.push((
|
||||||
Coord::new(min.x, y_part),
|
Coord::new(min.x, y_part),
|
||||||
Coord::new(x_part, max.y),
|
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());
|
let time = format!("{:.2}", (Instant::now() - start).as_secs_f32());
|
||||||
log_info!("Partitioning took {}s\n", time.bold());
|
log_info!("Partitioning took {}s\n", time.bold());
|
||||||
|
|
||||||
|
log_info!(
|
||||||
|
"now {} arcs special-cased\n",
|
||||||
|
special_arcs.len().to_string().bold()
|
||||||
|
);
|
||||||
|
|
||||||
log_info!(
|
log_info!(
|
||||||
"Using pressure factor {} and history factor {}\n",
|
"Using pressure factor {} and history factor {}\n",
|
||||||
pressure,
|
pressure,
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
route::Arc,
|
route::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Quadrant {
|
pub enum Quadrant {
|
||||||
Northeast,
|
Northeast,
|
||||||
Southeast,
|
Southeast,
|
||||||
@ -22,7 +22,7 @@ pub enum Quadrant {
|
|||||||
Northwest,
|
Northwest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Direction {
|
pub enum Direction {
|
||||||
North,
|
North,
|
||||||
South,
|
South,
|
||||||
@ -30,14 +30,14 @@ pub enum Direction {
|
|||||||
West,
|
West,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum FullSegment {
|
pub enum FullSegment {
|
||||||
Quadrant(Quadrant),
|
Quadrant(Quadrant),
|
||||||
Direction(Direction),
|
Direction(Direction),
|
||||||
Exact,
|
Exact,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Axis {
|
pub enum Axis {
|
||||||
NorthSouth,
|
NorthSouth,
|
||||||
EastWest,
|
EastWest,
|
||||||
@ -201,7 +201,7 @@ pub fn find_partition_point(
|
|||||||
x_finish: i32,
|
x_finish: i32,
|
||||||
y_start: i32,
|
y_start: i32,
|
||||||
y_finish: 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 x = ((x_finish - x_start) / 2) + x_start;
|
||||||
let mut y = ((y_finish - y_start) / 2) + y_start;
|
let mut y = ((y_finish - y_start) / 2) + y_start;
|
||||||
let mut x_diff = 0; //(x_finish - x_start) / 4;
|
let mut x_diff = 0; //(x_finish - x_start) / 4;
|
||||||
@ -244,7 +244,7 @@ pub fn find_partition_point(
|
|||||||
y_diff >>= 1;
|
y_diff >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (ne, se, sw, nw) = partition(
|
let (ne, se, sw, nw, special) = partition(
|
||||||
ctx,
|
ctx,
|
||||||
nets,
|
nets,
|
||||||
arcs,
|
arcs,
|
||||||
@ -269,7 +269,7 @@ pub fn find_partition_point(
|
|||||||
100.0 * (ne_dist + se_dist + sw_dist + nw_dist)
|
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(
|
fn approximate_partition_results(
|
||||||
@ -430,7 +430,7 @@ fn partition(
|
|||||||
y: i32,
|
y: i32,
|
||||||
x_bounds: (i32, i32),
|
x_bounds: (i32, i32),
|
||||||
y_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 min_bounds = Coord::new(x_bounds.0, y_bounds.0);
|
||||||
let max_bounds = Coord::new(x_bounds.1, y_bounds.1);
|
let max_bounds = Coord::new(x_bounds.1, y_bounds.1);
|
||||||
let partition_coords = Coord::new(x, y);
|
let partition_coords = Coord::new(x, y);
|
||||||
@ -439,6 +439,7 @@ fn partition(
|
|||||||
let mut se: Vec<Arc> = Vec::new();
|
let mut se: Vec<Arc> = Vec::new();
|
||||||
let mut sw: Vec<Arc> = Vec::new();
|
let mut sw: Vec<Arc> = Vec::new();
|
||||||
let mut nw: 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_horiz = AtomicUsize::new(0);
|
||||||
let mut part_vert = AtomicUsize::new(0);
|
let mut part_vert = AtomicUsize::new(0);
|
||||||
let mut part_diag = AtomicUsize::new(0);
|
let mut part_diag = AtomicUsize::new(0);
|
||||||
@ -467,6 +468,50 @@ fn partition(
|
|||||||
|
|
||||||
progress.set_message(format!("overused wires: {}", overused_wires));
|
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
|
let arcs = arcs
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.progress_with(progress)
|
.progress_with(progress)
|
||||||
@ -486,6 +531,12 @@ fn partition(
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
let verbose = false; //name == "soc0.processor.with_fpu.fpu_0.fpu_multiply_0.rin_CCU2C_S0_4$CCU2_FCI_INT";
|
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 {
|
if source_is_north == sink_is_north && source_is_east == sink_is_east {
|
||||||
let seg = source_coords.segment_from(&partition_coords);
|
let seg = source_coords.segment_from(&partition_coords);
|
||||||
vec![(seg, arc.clone())]
|
vec![(seg, arc.clone())]
|
||||||
@ -798,7 +849,7 @@ fn partition(
|
|||||||
dist_str(nw_dist)
|
dist_str(nw_dist)
|
||||||
);
|
);
|
||||||
|
|
||||||
(ne, se, sw, nw)
|
(ne, se, sw, nw, special.into_inner().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn partition_single_arc(
|
fn partition_single_arc(
|
||||||
@ -844,13 +895,13 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
x_finish: i32,
|
x_finish: i32,
|
||||||
y_start: i32,
|
y_start: i32,
|
||||||
y_finish: 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!(
|
println!(
|
||||||
"bounds: {:?} -> {:?}",
|
"bounds: {:?} -> {:?}",
|
||||||
(x_start, y_start),
|
(x_start, y_start),
|
||||||
(x_finish, y_finish)
|
(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);
|
find_partition_point(ctx, nets, arcs, pips, x_start, x_finish, y_start, y_finish);
|
||||||
|
|
||||||
let mut invalid_arcs_in_ne = 0;
|
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 {
|
struct PipSelector {
|
||||||
@ -1082,7 +1133,7 @@ impl PipSelector {
|
|||||||
src_has_west |= src_pip_coord.is_west_of(&partition_point.into());
|
src_has_west |= src_pip_coord.is_west_of(&partition_point.into());
|
||||||
if src_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
|
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)) {
|
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());
|
dst_has_west |= dst_pip_coord.is_west_of(&partition_point.into());
|
||||||
if dst_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
|
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)) {
|
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 {
|
if src_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
|
||||||
// yaaaaaaay, we need to everything again for this pip :)
|
// yaaaaaaay, we need to everything again for this pip :)
|
||||||
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_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());
|
dst_has_south |= dst_pip_coord.is_south_of(&partition_point.into());
|
||||||
if dst_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
|
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)) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user