diff --git a/common/kernel/command.cc b/common/kernel/command.cc index 087af5b3..17649280 100644 --- a/common/kernel/command.cc +++ b/common/kernel/command.cc @@ -397,6 +397,9 @@ po::options_description CommandHandler::getGeneralOptions() "enable experimental timing-driven ripup in router (deprecated; use --tmg-ripup instead)"); general.add_options()("router2-alt-weights", "use alternate router2 weights"); + + general.add_options()("awooter-pressure-factor", po::value(), "pressure factor for awooter"); + general.add_options()("awooter-history-factor", po::value(), "history factor for awooter"); general.add_options()("report", po::value(), "write timing and utilization report in JSON format to file"); @@ -536,8 +539,15 @@ void CommandHandler::setupContext(Context *ctx) if (vm.count("tmg-ripup") || vm.count("router2-tmg-ripup")) ctx->settings[ctx->id("router/tmg_ripup")] = true; +<<<<<<< HEAD if (vm.count("router2-alt-weights")) ctx->settings[ctx->id("router2/alt-weights")] = true; +======= + if (vm.count("awooter-pressure-factor")) + ctx->settings[ctx->id("awooter-pressure-factor")] = std::to_string(vm["awooter-pressure-factor"].as()); + if (vm.count("awooter-history-factor")) + ctx->settings[ctx->id("awooter-history-factor")] = std::to_string(vm["awooter-history-factor"].as()); +>>>>>>> a401db30 (awooter: make congestion factors configurable) // Setting default values if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end()) diff --git a/common/route/awooter.cc b/common/route/awooter.cc index 759e7da2..af16854c 100644 --- a/common/route/awooter.cc +++ b/common/route/awooter.cc @@ -311,14 +311,16 @@ extern "C" { return !(iter->current != iter->end); } - extern bool npnr_router_awooter(Context *ctx); + extern bool npnr_router_awooter(Context *ctx, float pressure, float history); } NEXTPNR_NAMESPACE_BEGIN bool router_awooter(Context *ctx) { + auto pressure = ctx->setting("awooter-pressure-factor", 5.0); + auto history = ctx->setting("awooter-history-factor", 5.0); log_info("Running Awooter...\n"); - auto result = npnr_router_awooter(ctx); + auto result = npnr_router_awooter(ctx, pressure, history); log_info("Router returned: %d\n", result); NPNR_ASSERT_FALSE_STR("I haven't implemented anything beyond this yet."); return result; diff --git a/common/route/awooter/rust/src/lib.rs b/common/route/awooter/rust/src/lib.rs index 2ab294e5..716cafc8 100644 --- a/common/route/awooter/rust/src/lib.rs +++ b/common/route/awooter/rust/src/lib.rs @@ -14,9 +14,9 @@ mod partition; mod route; #[no_mangle] -pub extern "C-unwind" fn npnr_router_awooter(ctx: Option>) -> bool { +pub extern "C-unwind" fn npnr_router_awooter(ctx: Option>, pressure: f32, history: f32) -> bool { let ctx: &mut npnr::Context = unsafe { ctx.expect("non-null context").as_mut() }; - route(ctx) + route(ctx, pressure, history) /*std::panic::catch_unwind(move || { let ctx: &mut npnr::Context = unsafe { ctx.expect("non-null context").as_mut() }; @@ -74,7 +74,7 @@ fn extract_arcs_from_nets(ctx: &npnr::Context, nets: &npnr::Nets) -> Vec bool { +fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool { log_info!( "{}{}{}{}{}{} from Rust!\n", "A".red(), @@ -207,6 +207,8 @@ fn route(ctx: &mut npnr::Context) -> bool { let time = format!("{:.2}", (Instant::now() - start).as_secs_f32()); log_info!("Partitioning took {}s\n", time.bold()); + log_info!("Using pressure factor {} and history factor {}\n", pressure, history); + let start = Instant::now(); log_info!("Routing partitioned arcs\n"); @@ -236,7 +238,7 @@ fn route(ctx: &mut npnr::Context) -> bool { ]; partitions.par_iter().for_each(|(box_ne, box_sw, arcs, id)| { - let mut router = route::Router::new(*box_ne, *box_sw); + let mut router = route::Router::new(*box_ne, *box_sw, pressure, history); router.route(ctx, &nets, wires, arcs, &progress, id); }); @@ -244,6 +246,8 @@ fn route(ctx: &mut npnr::Context) -> bool { let mut router = route::Router::new( Coord::new(0, 0), Coord::new(ctx.grid_dim_x(), ctx.grid_dim_y()), + pressure, + history ); router.route(ctx, &nets, wires, &special_arcs, &progress, "MISC"); diff --git a/common/route/awooter/rust/src/route.rs b/common/route/awooter/rust/src/route.rs index 9fa17ec8..c259bd14 100644 --- a/common/route/awooter/rust/src/route.rs +++ b/common/route/awooter/rust/src/route.rs @@ -1,6 +1,7 @@ use std::collections::{BinaryHeap, HashMap}; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; +use itertools::Itertools; use crate::{ npnr::{self, NetIndex, PipId, WireId}, @@ -125,20 +126,21 @@ struct PerWireData { pub struct Router { box_ne: partition::Coord, box_sw: partition::Coord, + pressure: f32, + history: f32, nets: Vec, wire_to_idx: HashMap, flat_wires: Vec, dirty_wires: Vec, } -const PRESSURE_FACTOR: u32 = 5; -const ACCUMULATED_OVERUSE_FACTOR: f32 = 5.0; - impl Router { - pub fn new(box_ne: partition::Coord, box_sw: partition::Coord) -> Self { + pub fn new(box_ne: partition::Coord, box_sw: partition::Coord, pressure: f32, history: f32) -> Self { Self { box_ne, box_sw, + pressure, + history, nets: Vec::new(), wire_to_idx: HashMap::new(), flat_wires: Vec::new(), @@ -174,7 +176,7 @@ impl Router { self.wire_to_idx.insert(wire, idx as u32); } - let mut delay = vec![1.0; arcs.len()]; + let mut delay = vec![1.0_f32; arcs.len()]; let mut max_delay = 1.0; loop { @@ -185,7 +187,7 @@ impl Router { .progress_chars("━╸ "), ); - for (i, arc) in arcs.iter().enumerate() { + for (i, arc) in arcs.iter().enumerate().sorted_by(|&(i, _), &(j, _)| (delay[i] / max_delay).total_cmp(&(delay[j] / max_delay))) { let net = unsafe { nets.net_from_index(arc.net).as_ref().unwrap() }; let name = ctx .name_of(nets.name_from_index(arc.net)) @@ -206,7 +208,7 @@ impl Router { for wd in &mut self.flat_wires { if wd.curr_cong > 1 { overused += 1; - wd.hist_cong += (wd.curr_cong as f32) * ACCUMULATED_OVERUSE_FACTOR; + wd.hist_cong += (wd.curr_cong as f32) * self.history; } } @@ -226,7 +228,7 @@ impl Router { fn route_arc(&mut self, ctx: &npnr::Context, nets: &npnr::Nets, arc: &Arc, criticality: f32) -> f32 { let mut queue = BinaryHeap::new(); - queue.push(QueuedWire::new(0.0, 0.0, 0.0, criticality, arc.source_wire)); + queue.push(QueuedWire::new(0.0, 0.0, ctx.estimate_delay(arc.source_wire, arc.sink_wire), criticality, arc.source_wire)); let mut found_sink = false; @@ -307,7 +309,7 @@ impl Router { let node_delay = ctx.pip_delay(pip) + ctx.wire_delay(wire) + ctx.delay_epsilon(); let delay = source.delay + node_delay; - let congest = source.congest + (node_delay + nwd.hist_cong) * (1.0 + (nwd.curr_cong * PRESSURE_FACTOR) as f32); + let congest = source.congest + (node_delay + nwd.hist_cong) * (1.0 + (nwd.curr_cong as f32 * self.pressure)); self.set_visited_fwd(sink, pip);