diff --git a/common/route/awooter/rust/src/lib.rs b/common/route/awooter/rust/src/lib.rs index 5fdf3dc8..982533c6 100644 --- a/common/route/awooter/rust/src/lib.rs +++ b/common/route/awooter/rust/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(c_unwind)] + use std::{ptr::NonNull, time::Instant}; use colored::Colorize; @@ -10,8 +12,11 @@ mod partition; mod route; #[no_mangle] -pub extern "C" fn npnr_router_awooter(ctx: Option>) -> bool { - std::panic::catch_unwind(move || { +pub extern "C-unwind" fn npnr_router_awooter(ctx: Option>) -> bool { + 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() }; route(ctx) }) @@ -20,7 +25,7 @@ pub extern "C" fn npnr_router_awooter(ctx: Option>) -> bo log_error!("caught panic: {}", x); } false - }) + })*/ } fn extract_arcs_from_nets(ctx: &npnr::Context, nets: &npnr::Nets) -> Vec { @@ -152,7 +157,7 @@ fn route(ctx: &mut npnr::Context) -> bool { 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, &nets, &arcs[..], @@ -168,7 +173,17 @@ fn route(ctx: &mut npnr::Context) -> bool { 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)); + log_info!("Routing northeast arcs"); 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"); let _ = find_partition_point(&ne, x_start, x, y_start, y); diff --git a/common/route/awooter/rust/src/npnr.rs b/common/route/awooter/rust/src/npnr.rs index c7facc89..9bf88711 100644 --- a/common/route/awooter/rust/src/npnr.rs +++ b/common/route/awooter/rust/src/npnr.rs @@ -291,7 +291,7 @@ impl Context { } } -extern "C" { +extern "C-unwind" { pub fn npnr_log_info(format: *const c_char); pub fn npnr_log_error(format: *const c_char); diff --git a/common/route/awooter/rust/src/partition.rs b/common/route/awooter/rust/src/partition.rs index cd23747a..903a5a51 100644 --- a/common/route/awooter/rust/src/partition.rs +++ b/common/route/awooter/rust/src/partition.rs @@ -78,7 +78,7 @@ pub fn find_partition_point( x_finish: i32, y_start: i32, y_finish: i32, -) -> (i32, i32, Vec, Vec, Vec, Vec) { +) -> (i32, i32, Vec, Vec, Vec, Vec, Vec) { let mut x = ((x_finish - x_start) / 2) + x_start; let mut y = ((y_finish - y_start) / 2) + y_start; let mut x_diff = (x_finish - x_start) / 4; @@ -88,9 +88,10 @@ pub fn find_partition_point( let mut se; let mut sw; let mut nw; + let mut misc; while x_diff != 0 { - (ne, se, sw, nw) = partition( + (ne, se, sw, nw, misc) = partition( ctx, nets, arcs, @@ -114,7 +115,7 @@ pub fn find_partition_point( // Stop early if Good Enough. if distortion <= 5.0 { - return (x, y, ne, se, sw, nw); + return (x, y, ne, se, sw, nw, misc); } x += match north.cmp(&south) { @@ -135,7 +136,7 @@ pub fn find_partition_point( y_diff >>= 1; } - (ne, se, sw, nw) = partition( + (ne, se, sw, nw, misc) = partition( ctx, nets, arcs, @@ -160,7 +161,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, misc) } /// 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>( .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>, arc: &Arc| { let (selected_pip, pip_uses) = pips .iter() @@ -374,9 +388,16 @@ fn partition>( let mut explored_pips = AtomicUsize::new(0); + for arc in arcs { + if is_special_case(arc) { + misc.push(arc.clone()); + } + } + let arcs = arcs .into_par_iter() .progress_with(progress) + .filter(|arc| !is_special_case(arc)) .flat_map(|arc| { let source_loc = arc.get_source_loc(); let source_coords: Coord = source_loc.into(); @@ -658,8 +679,12 @@ fn partition>( }), 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( @@ -671,8 +696,8 @@ pub fn find_partition_point_and_sanity_check( x_finish: i32, y_start: i32, y_finish: i32, -) -> (i32, i32, Vec, Vec, Vec, Vec) { - let (x_part, y_part, ne, se, sw, nw) = +) -> (i32, i32, Vec, Vec, Vec, Vec, Vec) { + 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); 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()); } - (x_part, y_part, ne, se, sw, nw) + (x_part, y_part, ne, se, sw, nw, misc) } diff --git a/common/route/awooter/rust/src/route.rs b/common/route/awooter/rust/src/route.rs index bb57073d..31b50747 100644 --- a/common/route/awooter/rust/src/route.rs +++ b/common/route/awooter/rust/src/route.rs @@ -169,8 +169,8 @@ impl Router { .to_str() .unwrap() .to_string(); - let verbose = - name == "decode_to_execute_IS_RS2_SIGNED_LUT4_D_1_Z_CCU2C_B1_S0_CCU2C_S0_3_B1"; + let verbose = false; + //name == "decode_to_execute_IS_RS2_SIGNED_LUT4_D_1_Z_CCU2C_B1_S0_CCU2C_S0_3_B1"; while let Some(source) = queue.pop() { if source.wire == arc.sink_wire {