awooter: single-thread pathfinding

This commit is contained in:
Lofty 2022-11-29 03:08:54 +00:00
parent 7ef4be49dc
commit 879b6e6691
4 changed files with 56 additions and 16 deletions

View File

@ -1,3 +1,5 @@
#![feature(c_unwind)]
use std::{ptr::NonNull, time::Instant}; use std::{ptr::NonNull, time::Instant};
use colored::Colorize; use colored::Colorize;
@ -10,8 +12,11 @@ mod partition;
mod route; mod route;
#[no_mangle] #[no_mangle]
pub extern "C" fn npnr_router_awooter(ctx: Option<NonNull<npnr::Context>>) -> bool { pub extern "C-unwind" fn npnr_router_awooter(ctx: Option<NonNull<npnr::Context>>) -> bool {
std::panic::catch_unwind(move || { let ctx: &mut npnr::Context = unsafe { ctx.expect("non-null context").as_mut() };
route(ctx)
/*std::panic::catch_unwind(move || {
let ctx: &mut npnr::Context = unsafe { ctx.expect("non-null context").as_mut() }; let ctx: &mut npnr::Context = unsafe { ctx.expect("non-null context").as_mut() };
route(ctx) route(ctx)
}) })
@ -20,7 +25,7 @@ pub extern "C" fn npnr_router_awooter(ctx: Option<NonNull<npnr::Context>>) -> bo
log_error!("caught panic: {}", x); log_error!("caught panic: {}", x);
} }
false false
}) })*/
} }
fn extract_arcs_from_nets(ctx: &npnr::Context, nets: &npnr::Nets) -> Vec<route::Arc> { fn extract_arcs_from_nets(ctx: &npnr::Context, nets: &npnr::Nets) -> Vec<route::Arc> {
@ -152,7 +157,7 @@ fn route(ctx: &mut npnr::Context) -> bool {
let arcs = extract_arcs_from_nets(ctx, &nets); let arcs = extract_arcs_from_nets(ctx, &nets);
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, misc) = partition::find_partition_point_and_sanity_check(
ctx, ctx,
&nets, &nets,
&arcs[..], &arcs[..],
@ -168,7 +173,17 @@ fn route(ctx: &mut npnr::Context) -> bool {
log_info!("Partitioning took {:.2}s\n", time.as_secs_f32()); log_info!("Partitioning took {:.2}s\n", time.as_secs_f32());
let mut router = route::Router::new(Coord::new(0, 0), Coord::new(x_part, y_part)); let mut router = route::Router::new(Coord::new(0, 0), Coord::new(x_part, y_part));
log_info!("Routing northeast arcs");
router.route(ctx, &nets, &ne); router.route(ctx, &nets, &ne);
log_info!("Routing southeast arcs");
router.route(ctx, &nets, &se);
log_info!("Routing southwest arcs");
router.route(ctx, &nets, &sw);
log_info!("Routing northwest arcs");
router.route(ctx, &nets, &nw);
log_info!("Routing miscellaneous arcs");
router.route(ctx, &nets, &misc);
//let mut router = route::Router::new(Coord::new(0, 0), Coord::new(x_part, y_part));
/*log_info!("=== level 2 NE:\n"); /*log_info!("=== level 2 NE:\n");
let _ = find_partition_point(&ne, x_start, x, y_start, y); let _ = find_partition_point(&ne, x_start, x, y_start, y);

View File

@ -291,7 +291,7 @@ impl Context {
} }
} }
extern "C" { extern "C-unwind" {
pub fn npnr_log_info(format: *const c_char); pub fn npnr_log_info(format: *const c_char);
pub fn npnr_log_error(format: *const c_char); pub fn npnr_log_error(format: *const c_char);

View File

@ -78,7 +78,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 = (x_finish - x_start) / 4; let mut x_diff = (x_finish - x_start) / 4;
@ -88,9 +88,10 @@ pub fn find_partition_point(
let mut se; let mut se;
let mut sw; let mut sw;
let mut nw; let mut nw;
let mut misc;
while x_diff != 0 { while x_diff != 0 {
(ne, se, sw, nw) = partition( (ne, se, sw, nw, misc) = partition(
ctx, ctx,
nets, nets,
arcs, arcs,
@ -114,7 +115,7 @@ pub fn find_partition_point(
// Stop early if Good Enough. // Stop early if Good Enough.
if distortion <= 5.0 { if distortion <= 5.0 {
return (x, y, ne, se, sw, nw); return (x, y, ne, se, sw, nw, misc);
} }
x += match north.cmp(&south) { x += match north.cmp(&south) {
@ -135,7 +136,7 @@ pub fn find_partition_point(
y_diff >>= 1; y_diff >>= 1;
} }
(ne, se, sw, nw) = partition( (ne, se, sw, nw, misc) = partition(
ctx, ctx,
nets, nets,
arcs, arcs,
@ -160,7 +161,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, misc)
} }
/// finds the y location a line would be split at if you split it at a certain x location /// finds the y location a line would be split at if you split it at a certain x location
@ -357,6 +358,19 @@ fn partition<R: RangeBounds<i32>>(
.progress_chars("━╸ "), .progress_chars("━╸ "),
); );
let is_special_case = |arc: &Arc| {
let src_wire = arc.get_source_wire();
let dst_wire = arc.get_sink_wire();
let src_name = ctx.name_of_wire(arc.get_source_wire()).to_str().unwrap();
let dst_name = ctx.name_of_wire(arc.get_sink_wire()).to_str().unwrap();
if src_name.contains("FCO_SLICE") {
return true;
}
false
};
let find_best_pip = |pips: &Vec<std::sync::Arc<(npnr::PipId, AtomicUsize)>>, arc: &Arc| { let find_best_pip = |pips: &Vec<std::sync::Arc<(npnr::PipId, AtomicUsize)>>, arc: &Arc| {
let (selected_pip, pip_uses) = pips let (selected_pip, pip_uses) = pips
.iter() .iter()
@ -374,9 +388,16 @@ fn partition<R: RangeBounds<i32>>(
let mut explored_pips = AtomicUsize::new(0); let mut explored_pips = AtomicUsize::new(0);
for arc in arcs {
if is_special_case(arc) {
misc.push(arc.clone());
}
}
let arcs = arcs let arcs = arcs
.into_par_iter() .into_par_iter()
.progress_with(progress) .progress_with(progress)
.filter(|arc| !is_special_case(arc))
.flat_map(|arc| { .flat_map(|arc| {
let source_loc = arc.get_source_loc(); let source_loc = arc.get_source_loc();
let source_coords: Coord = source_loc.into(); let source_coords: Coord = source_loc.into();
@ -658,8 +679,12 @@ fn partition<R: RangeBounds<i32>>(
}), }),
dist_str(nw_dist) dist_str(nw_dist)
); );
log_info!(
" {} arcs special-cased\n",
misc.len().to_string().bold()
);
(ne, se, sw, nw) (ne, se, sw, nw, misc)
} }
pub fn find_partition_point_and_sanity_check( pub fn find_partition_point_and_sanity_check(
@ -671,8 +696,8 @@ 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>) {
let (x_part, y_part, ne, se, sw, nw) = let (x_part, y_part, ne, se, sw, nw, misc) =
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;
@ -738,5 +763,5 @@ pub fn find_partition_point_and_sanity_check(
println!("count in nw: {}", invalid_arcs_in_nw.to_string().bold()); println!("count in nw: {}", invalid_arcs_in_nw.to_string().bold());
} }
(x_part, y_part, ne, se, sw, nw) (x_part, y_part, ne, se, sw, nw, misc)
} }

View File

@ -169,8 +169,8 @@ impl Router {
.to_str() .to_str()
.unwrap() .unwrap()
.to_string(); .to_string();
let verbose = let verbose = false;
name == "decode_to_execute_IS_RS2_SIGNED_LUT4_D_1_Z_CCU2C_B1_S0_CCU2C_S0_3_B1"; //name == "decode_to_execute_IS_RS2_SIGNED_LUT4_D_1_Z_CCU2C_B1_S0_CCU2C_S0_3_B1";
while let Some(source) = queue.pop() { while let Some(source) = queue.pop() {
if source.wire == arc.sink_wire { if source.wire == arc.sink_wire {