awooter: single-thread pathfinding
This commit is contained in:
parent
7ef4be49dc
commit
879b6e6691
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user