nextpnr/common/route/awooter/rust/src/route.rs

677 lines
20 KiB
Rust
Raw Normal View History

2022-12-11 23:12:01 +08:00
use std::{
collections::{BinaryHeap, HashMap, HashSet},
2022-11-29 05:15:04 +08:00
sync::RwLock,
time::Instant,
2022-12-11 23:12:01 +08:00
};
2022-11-29 05:15:04 +08:00
2022-12-07 16:36:00 +08:00
use colored::Colorize;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use itertools::Itertools;
2022-11-28 03:27:33 +08:00
2022-11-28 03:47:16 +08:00
use crate::{
2022-11-29 05:15:04 +08:00
npnr::{self, IdString, Loc, NetIndex, PipId, WireId},
2022-11-28 03:47:16 +08:00
partition,
};
2022-11-27 23:28:59 +08:00
2022-12-07 16:36:00 +08:00
#[derive(Clone, Hash, PartialEq, Eq)]
2022-11-27 23:28:59 +08:00
pub struct Arc {
source_wire: WireId,
2022-12-17 00:30:59 +08:00
source_loc: Loc,
sink_wire: WireId,
2022-12-17 00:30:59 +08:00
sink_loc: Loc,
net: NetIndex,
name: IdString,
2022-11-27 23:28:59 +08:00
}
impl Arc {
2022-11-28 03:47:16 +08:00
pub fn new(
2022-12-17 00:30:59 +08:00
source_wire: WireId,
source_loc: Loc,
sink_wire: WireId,
sink_loc: Loc,
2022-11-28 03:47:16 +08:00
net: NetIndex,
name: IdString,
2022-11-28 03:47:16 +08:00
) -> Self {
2022-11-27 23:28:59 +08:00
Self {
2022-11-28 03:47:16 +08:00
source_wire,
2022-12-17 00:30:59 +08:00
source_loc,
2022-11-28 03:47:16 +08:00
sink_wire,
2022-12-17 00:30:59 +08:00
sink_loc,
2022-11-28 03:47:16 +08:00
net,
name,
2022-11-27 23:28:59 +08:00
}
}
2022-11-28 00:26:17 +08:00
2022-11-28 03:47:16 +08:00
pub fn split(&self, ctx: &npnr::Context, pip: npnr::PipId) -> (Self, Self) {
2022-11-28 00:26:17 +08:00
let pip_src = ctx.pip_src_wire(pip);
let pip_dst = ctx.pip_dst_wire(pip);
2022-11-28 03:47:16 +08:00
(
Self {
source_wire: self.source_wire,
2022-12-17 00:30:59 +08:00
source_loc: self.source_loc,
2022-11-28 03:47:16 +08:00
sink_wire: pip_src,
2022-12-17 00:30:59 +08:00
sink_loc: ctx.pip_location(pip),
2022-11-28 03:47:16 +08:00
net: self.net,
name: self.name,
2022-11-28 03:47:16 +08:00
},
Self {
source_wire: pip_dst,
2022-12-17 00:30:59 +08:00
source_loc: ctx.pip_location(pip),
2022-11-28 03:47:16 +08:00
sink_wire: self.sink_wire,
2022-12-17 00:30:59 +08:00
sink_loc: self.sink_loc,
2022-11-28 03:47:16 +08:00
net: self.net,
name: self.name,
2022-11-28 03:47:16 +08:00
},
)
}
pub fn source_wire(&self) -> npnr::WireId {
2022-11-28 03:47:16 +08:00
self.source_wire
}
pub fn sink_wire(&self) -> npnr::WireId {
2022-11-28 03:47:16 +08:00
self.sink_wire
2022-11-28 00:26:17 +08:00
}
2022-11-29 05:15:04 +08:00
pub fn net(&self) -> npnr::NetIndex {
self.net
}
2022-12-17 00:30:59 +08:00
pub fn get_source_loc(&self) -> Loc {
self.source_loc
}
pub fn get_sink_loc(&self) -> Loc {
self.sink_loc
}
2022-11-27 23:28:59 +08:00
}
2022-11-28 03:27:33 +08:00
#[derive(Copy, Clone)]
struct QueuedWire {
delay: f32,
congest: f32,
2022-11-28 03:27:33 +08:00
togo: f32,
2022-12-04 10:24:34 +08:00
criticality: f32,
2022-11-28 03:27:33 +08:00
wire: npnr::WireId,
2022-12-14 22:32:11 +08:00
from_pip: Option<npnr::PipId>,
2022-11-28 03:27:33 +08:00
}
impl QueuedWire {
2022-12-14 22:32:11 +08:00
pub fn new(
delay: f32,
congest: f32,
togo: f32,
criticality: f32,
wire: npnr::WireId,
from_pip: Option<npnr::PipId>,
) -> Self {
Self {
delay,
congest,
togo,
criticality,
wire,
2022-12-14 22:32:11 +08:00
from_pip,
}
2022-11-28 03:27:33 +08:00
}
fn score(&self) -> f32 {
(self.criticality * self.delay) + ((1.0 - self.criticality) * self.congest)
}
2022-11-28 03:27:33 +08:00
}
impl PartialEq for QueuedWire {
fn eq(&self, other: &Self) -> bool {
self.delay == other.delay
&& self.congest == other.congest
&& self.togo == other.togo
&& self.wire == other.wire
2022-11-28 03:27:33 +08:00
}
}
impl Eq for QueuedWire {}
impl Ord for QueuedWire {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let me = self.score() + self.togo;
let other = other.score() + other.togo;
2022-11-28 03:27:33 +08:00
other.total_cmp(&me)
}
}
impl PartialOrd for QueuedWire {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
struct PerNetData {
wires: HashMap<WireId, (PipId, u32)>,
2022-12-12 22:57:57 +08:00
done_sinks: HashSet<WireId>,
}
struct PerWireData {
wire: WireId,
curr_cong: u32,
hist_cong: f32,
unavailable: bool,
reserved_net: Option<NetIndex>,
pip_fwd: PipId,
visited_fwd: bool,
2022-12-11 23:38:57 +08:00
pip_bwd: PipId,
visited_bwd: bool,
}
pub struct RouterThread<'a> {
2022-11-28 03:27:33 +08:00
box_ne: partition::Coord,
box_sw: partition::Coord,
arcs: &'a [Arc],
id: &'a str,
progress: &'a MultiProgress,
2022-12-17 00:30:59 +08:00
dirty_wires: Vec<u32>,
2022-11-28 03:27:33 +08:00
}
impl<'a> RouterThread<'a> {
pub fn new(
box_ne: partition::Coord,
box_sw: partition::Coord,
arcs: &'a [Arc],
id: &'a str,
progress: &'a MultiProgress,
) -> Self {
2022-11-28 03:27:33 +08:00
Self {
box_ne,
box_sw,
arcs,
id,
progress,
2022-12-17 00:30:59 +08:00
dirty_wires: Vec::new(),
2022-11-28 03:27:33 +08:00
}
}
}
pub struct Router {
pressure: f32,
history: f32,
2022-12-17 00:30:59 +08:00
nets: RwLock<Vec<PerNetData>>,
wire_to_idx: HashMap<WireId, u32>,
2022-12-17 00:30:59 +08:00
flat_wires: Vec<RwLock<PerWireData>>,
}
impl Router {
pub fn new(nets: &npnr::Nets, wires: &[npnr::WireId], pressure: f32, history: f32) -> Self {
let mut net_vec = Vec::new();
let mut flat_wires = Vec::new();
let mut wire_to_idx = HashMap::new();
2022-11-28 03:27:33 +08:00
for _ in 0..nets.len() {
net_vec.push(PerNetData {
wires: HashMap::new(),
2022-12-12 22:57:57 +08:00
done_sinks: HashSet::new(),
});
}
for (idx, &wire) in wires.iter().enumerate() {
2022-12-17 00:30:59 +08:00
flat_wires.push(RwLock::new(PerWireData {
wire,
curr_cong: 0,
hist_cong: 0.0,
unavailable: false,
reserved_net: None,
pip_fwd: PipId::null(),
visited_fwd: false,
2022-12-11 23:38:57 +08:00
pip_bwd: PipId::null(),
visited_bwd: false,
2022-12-17 00:30:59 +08:00
}));
wire_to_idx.insert(wire, idx as u32);
}
Self {
pressure,
history,
2022-12-17 00:30:59 +08:00
nets: RwLock::new(net_vec),
wire_to_idx,
flat_wires,
}
}
2022-12-17 00:30:59 +08:00
pub fn route(&self, ctx: &npnr::Context, nets: &npnr::Nets, this: &mut RouterThread) {
2022-12-07 16:36:00 +08:00
let mut delay = HashMap::new();
for arc in this.arcs {
2022-12-07 16:36:00 +08:00
delay.insert(arc, 1.0_f32);
}
let start = Instant::now();
2022-12-04 10:24:34 +08:00
let mut max_delay = 1.0;
2022-12-07 16:36:00 +08:00
let mut least_overuse = usize::MAX;
let mut iters_since_improvement = 0;
let mut route_arcs = Vec::from_iter(this.arcs.iter());
let progress = this.progress.add(ProgressBar::new(0));
progress.set_style(
ProgressStyle::with_template("[{elapsed}] [{bar:40.magenta/red}] {msg:30!}")
.unwrap()
.progress_chars("━╸ "),
);
2022-12-04 10:24:34 +08:00
let mut iterations = 0;
loop {
iterations += 1;
progress.set_position(0);
progress.set_length(route_arcs.len() as u64);
2022-12-07 16:36:00 +08:00
for arc in route_arcs.iter().sorted_by(|&i, &j| {
(delay.get(j).unwrap() / max_delay).total_cmp(&(delay.get(i).unwrap() / max_delay))
}) {
let name = ctx.name_of(arc.name).to_str().unwrap();
progress.inc(1);
let criticality = (delay.get(arc).unwrap() / max_delay).min(0.99).powf(2.5) + 0.1;
progress.set_message(format!("{} @ {}: {}", this.id, iterations, name));
2022-12-07 16:36:00 +08:00
*delay.get_mut(arc).unwrap() = self.route_arc(ctx, nets, arc, criticality);
}
2022-11-29 05:15:04 +08:00
2022-12-07 16:36:00 +08:00
let mut overused = HashSet::new();
2022-12-17 00:30:59 +08:00
for wd in self.flat_wires.iter() {
let mut wd = wd.write().unwrap();
if wd.curr_cong > 1 {
overused.insert(wd.wire);
wd.hist_cong += (wd.curr_cong as f32) * self.history;
}
}
2022-11-29 05:15:04 +08:00
2022-12-07 16:36:00 +08:00
if overused.is_empty() {
break;
2022-12-07 16:36:00 +08:00
} else if overused.len() < least_overuse {
least_overuse = overused.len();
iters_since_improvement = 0;
2022-12-11 23:12:01 +08:00
progress.println(format!(
"{} @ {}: {} wires overused {}",
this.id,
2022-12-11 23:12:01 +08:00
iterations,
overused.len(),
"(new best)".bold()
));
2022-12-07 16:36:00 +08:00
} else {
iters_since_improvement += 1;
2022-12-11 23:12:01 +08:00
progress.println(format!(
"{} @ {}: {} wires overused",
this.id,
2022-12-11 23:12:01 +08:00
iterations,
overused.len()
));
2022-11-29 05:15:04 +08:00
}
2022-12-07 16:36:00 +08:00
let mut next_arcs = Vec::new();
for arc in this.arcs {
2022-11-29 05:15:04 +08:00
for wire in self.nets.read().unwrap()[arc.net.into_inner() as usize]
.wires
.keys()
{
2022-12-07 16:36:00 +08:00
if overused.contains(wire) {
next_arcs.push(arc);
}
}
}
for &arc in &route_arcs {
2022-12-04 10:24:34 +08:00
self.ripup_arc(ctx, arc);
}
2022-12-17 00:30:59 +08:00
for net in self.nets.write().unwrap().iter_mut() {
net.done_sinks.clear();
}
2022-12-11 23:12:01 +08:00
2022-12-07 16:36:00 +08:00
if iters_since_improvement > 50 {
iters_since_improvement = 0;
least_overuse = usize::MAX;
2022-12-11 23:12:01 +08:00
progress.println(format!(
"{} @ {}: {}",
this.id,
2022-12-11 23:12:01 +08:00
iterations,
"bored; rerouting everything".bold()
));
route_arcs = Vec::from_iter(this.arcs.iter());
2022-12-07 16:36:00 +08:00
} else {
route_arcs = next_arcs;
}
2022-12-04 10:24:34 +08:00
max_delay = this
.arcs
2022-12-11 23:12:01 +08:00
.iter()
.map(|arc| *delay.get(arc).unwrap())
.reduce(f32::max)
.unwrap();
2022-11-28 03:27:33 +08:00
}
let now = (Instant::now() - start).as_secs_f32();
progress.println(format!(
"{} @ {}: {} in {:.0}m{:.03}s",
this.id,
iterations,
"routing complete".green(),
now / 60.0,
now % 60.0
));
progress.finish_and_clear();
}
fn can_visit_pip(&self, ctx: &npnr::Context, nets: &npnr::Nets, arc: &Arc, pip: PipId) -> bool {
let wire = ctx.pip_dst_wire(pip);
let sink = *self.wire_to_idx.get(&wire).unwrap();
2022-12-17 00:30:59 +08:00
let nd = &self.nets.read().unwrap()[arc.net().into_inner() as usize];
let nwd = &self.flat_wires[sink as usize].read().unwrap();
/*let pip_coord = partition::Coord::from(ctx.pip_location(pip));
if pip_coord.is_north_of(&self.box_ne) || pip_coord.is_east_of(&self.box_ne) {
return false;
}
if pip_coord.is_south_of(&self.box_sw) || pip_coord.is_west_of(&self.box_sw) {
return false;
}*/
if !ctx.pip_avail_for_net(pip, nets.net_from_index(arc.net())) {
return false;
}
if nwd.unavailable {
return false;
}
if let Some(net) = nwd.reserved_net && net != arc.net() {
return false;
}
// Don't allow the same wire to be bound to the same net with a different driving pip
if let Some((found_pip, _)) = nd.wires.get(&wire) && *found_pip != pip {
return false;
}
true
}
2022-12-17 00:30:59 +08:00
#[allow(clippy::too_many_arguments)]
fn step<'b, 'a: 'b, I>(
&'a self,
ctx: &'b npnr::Context,
nets: &npnr::Nets,
arc: &Arc,
criticality: f32,
queue: &mut BinaryHeap<QueuedWire>,
midpoint: &mut Option<u32>,
target: WireId,
2022-12-17 00:30:59 +08:00
dirty_wires: &mut Vec<u32>,
was_visited: impl Fn(&Self, u32) -> bool,
set_visited: impl Fn(&Self, u32, PipId, &mut Vec<u32>),
is_done: impl Fn(&Self, u32) -> bool,
pip_iter: impl Fn(&'b npnr::Context, WireId) -> I,
pip_wire: impl Fn(&npnr::Context, PipId) -> WireId,
) -> bool
where
I: Iterator<Item = PipId>,
{
if let Some(source) = queue.pop() {
let source_idx = *self.wire_to_idx.get(&source.wire).unwrap();
if was_visited(self, source_idx) {
return true;
}
if let Some(pip) = source.from_pip {
2022-12-17 00:30:59 +08:00
set_visited(self, source_idx, pip, dirty_wires);
}
if is_done(self, source_idx) {
*midpoint = Some(source_idx);
return false;
}
for pip in pip_iter(ctx, source.wire) {
if !self.can_visit_pip(ctx, nets, arc, pip) {
continue;
}
let wire = pip_wire(ctx, pip);
let sink = *self.wire_to_idx.get(&wire).unwrap();
if was_visited(self, sink) {
continue;
}
2022-12-17 00:30:59 +08:00
let nwd = &self.flat_wires[sink as usize].read().unwrap();
let node_delay = ctx.pip_delay(pip) + ctx.wire_delay(wire) + ctx.delay_epsilon();
let sum_delay = source.delay + node_delay;
let congest = source.congest
+ (node_delay + nwd.hist_cong) * (1.0 + (nwd.curr_cong as f32 * self.pressure));
let qw = QueuedWire::new(
sum_delay,
congest,
ctx.estimate_delay(wire, target),
criticality,
wire,
Some(pip),
);
queue.push(qw);
}
return true;
}
false
2022-11-28 03:27:33 +08:00
}
fn route_arc(
2022-12-17 00:30:59 +08:00
&self,
ctx: &npnr::Context,
nets: &npnr::Nets,
arc: &Arc,
criticality: f32,
) -> f32 {
if arc.source_wire == arc.sink_wire {
return 0.0;
}
2022-12-11 23:38:57 +08:00
let mut fwd_queue = BinaryHeap::new();
fwd_queue.push(QueuedWire::new(
0.0,
0.0,
ctx.estimate_delay(arc.source_wire, arc.sink_wire),
criticality,
arc.source_wire,
2022-12-14 22:32:11 +08:00
None,
));
2022-12-11 23:38:57 +08:00
let mut bwd_queue = BinaryHeap::new();
bwd_queue.push(QueuedWire::new(
0.0,
0.0,
ctx.estimate_delay(arc.source_wire, arc.sink_wire),
criticality,
arc.sink_wire,
2022-12-14 22:32:11 +08:00
None,
2022-12-11 23:38:57 +08:00
));
2022-11-28 03:27:33 +08:00
let mut midpoint = None;
2022-11-29 05:15:04 +08:00
2022-12-11 23:38:57 +08:00
let source_wire = *self.wire_to_idx.get(&arc.source_wire).unwrap();
let sink_wire = *self.wire_to_idx.get(&arc.sink_wire).unwrap();
2022-12-17 00:30:59 +08:00
let mut dirty_wires = Vec::new();
2022-12-11 23:38:57 +08:00
2022-12-17 00:30:59 +08:00
dirty_wires.push(source_wire);
dirty_wires.push(sink_wire);
2022-11-29 05:15:04 +08:00
let already_done = self.nets.read().unwrap()[arc.net().into_inner() as usize]
.done_sinks
.contains(&arc.sink_wire);
2022-12-17 00:30:59 +08:00
if already_done {
midpoint = Some(*self.wire_to_idx.get(&arc.sink_wire).unwrap());
2022-12-04 10:24:34 +08:00
let mut wire = arc.sink_wire();
while wire != arc.source_wire() {
2022-12-17 00:30:59 +08:00
let nd = &self.nets.read().unwrap()[arc.net().into_inner() as usize];
let driver = nd.wires.get(&wire).unwrap().0;
2022-12-17 00:30:59 +08:00
self.set_visited_fwd(self.wire_to_idx[&wire], driver, &mut dirty_wires);
wire = ctx.pip_src_wire(driver);
2022-11-29 05:15:04 +08:00
}
} else {
while midpoint.is_none() {
// Step forward
if !self.step(
ctx,
nets,
arc,
criticality,
&mut fwd_queue,
&mut midpoint,
arc.sink_wire,
2022-12-17 00:30:59 +08:00
&mut dirty_wires,
Self::was_visited_fwd,
Self::set_visited_fwd,
Self::was_visited_bwd,
npnr::Context::get_downhill_pips,
npnr::Context::pip_dst_wire,
) {
2022-12-11 23:38:57 +08:00
break;
}
// Step backward
2022-12-17 00:30:59 +08:00
/*if !self.step(
ctx,
nets,
arc,
criticality,
&mut bwd_queue,
&mut midpoint,
arc.source_wire,
2022-12-17 00:30:59 +08:00
&mut dirty_wires,
Self::was_visited_bwd,
Self::set_visited_bwd,
Self::was_visited_fwd,
npnr::Context::get_uphill_pips,
npnr::Context::pip_src_wire,
) {
break;
2022-12-17 00:30:59 +08:00
}*/
2022-11-29 05:15:04 +08:00
self.flat_wires[source_wire as usize]
.write()
.unwrap()
.visited_fwd = true;
self.flat_wires[sink_wire as usize]
.write()
.unwrap()
.visited_bwd = true;
2022-11-28 03:27:33 +08:00
}
}
2022-11-29 09:55:24 +08:00
assert!(
midpoint.is_some(),
"didn't find sink wire for net {} between {} and {}",
ctx.name_of(arc.name).to_str().unwrap(),
2022-11-29 09:55:24 +08:00
ctx.name_of_wire(arc.source_wire).to_str().unwrap(),
2022-12-11 23:38:57 +08:00
ctx.name_of_wire(arc.sink_wire).to_str().unwrap(),
2022-11-29 09:55:24 +08:00
);
2022-11-29 05:15:04 +08:00
let mut wire = midpoint.unwrap();
2022-12-11 23:38:57 +08:00
2022-12-12 22:57:57 +08:00
let mut calculated_delay = 0.0;
while wire != source_wire {
2022-12-17 00:30:59 +08:00
let (pip, wireid) = {
let nwd = self.flat_wires[wire as usize].read().unwrap();
(nwd.pip_fwd, nwd.wire)
};
assert!(pip != PipId::null());
2022-12-12 22:57:57 +08:00
2022-11-29 05:15:04 +08:00
let node_delay = ctx.pip_delay(pip) + ctx.wire_delay(wireid) + ctx.delay_epsilon();
2022-12-12 22:57:57 +08:00
calculated_delay += node_delay;
self.bind_pip_internal(arc.net(), wire, pip);
wire = *self.wire_to_idx.get(&ctx.pip_src_wire(pip)).unwrap();
}
let mut wire = midpoint.unwrap();
2022-12-11 23:38:57 +08:00
while wire != sink_wire {
2022-12-17 00:30:59 +08:00
let (pip, wireid) = {
let nwd = self.flat_wires[wire as usize].read().unwrap();
(nwd.pip_bwd, nwd.wire)
};
2022-12-11 23:38:57 +08:00
assert!(pip != PipId::null());
// do note that the order is inverted from the fwd loop
wire = *self.wire_to_idx.get(&ctx.pip_dst_wire(pip)).unwrap();
2022-12-12 22:57:57 +08:00
2022-11-29 05:15:04 +08:00
let node_delay = ctx.pip_delay(pip) + ctx.wire_delay(wireid) + ctx.delay_epsilon();
2022-12-12 22:57:57 +08:00
calculated_delay += node_delay;
2022-12-11 23:38:57 +08:00
self.bind_pip_internal(arc.net(), wire, pip);
}
2022-11-29 05:15:04 +08:00
self.nets.write().unwrap()[arc.net().into_inner() as usize]
.done_sinks
.insert(arc.sink_wire);
2022-12-17 00:30:59 +08:00
self.reset_wires(&dirty_wires);
2022-12-04 10:24:34 +08:00
2022-12-12 22:57:57 +08:00
calculated_delay
}
fn was_visited_fwd(&self, wire: u32) -> bool {
2022-12-17 00:30:59 +08:00
self.flat_wires[wire as usize].read().unwrap().visited_fwd
}
2022-12-11 23:38:57 +08:00
fn was_visited_bwd(&self, wire: u32) -> bool {
2022-12-17 00:30:59 +08:00
self.flat_wires[wire as usize].read().unwrap().visited_bwd
2022-12-11 23:38:57 +08:00
}
2022-12-17 00:30:59 +08:00
fn set_visited_fwd(&self, wire: u32, pip: PipId, dirty_wires: &mut Vec<u32>) {
let mut wd = self.flat_wires[wire as usize].write().unwrap();
if !wd.visited_fwd {
2022-12-17 00:30:59 +08:00
dirty_wires.push(wire);
2022-11-28 03:27:33 +08:00
}
wd.pip_fwd = pip;
wd.visited_fwd = true;
2022-11-28 03:27:33 +08:00
}
2022-12-17 00:30:59 +08:00
fn set_visited_bwd(&self, wire: u32, pip: PipId, dirty_wires: &mut Vec<u32>) {
let mut wd = self.flat_wires[wire as usize].write().unwrap();
2022-12-11 23:38:57 +08:00
if !wd.visited_bwd {
2022-12-17 00:30:59 +08:00
dirty_wires.push(wire);
2022-12-11 23:38:57 +08:00
}
wd.pip_bwd = pip;
wd.visited_bwd = true;
}
2022-12-17 00:30:59 +08:00
fn bind_pip_internal(&self, netindex: NetIndex, wire: u32, pip: PipId) {
let wireid = self.flat_wires[wire as usize].read().unwrap().wire;
let net = &mut self.nets.write().unwrap()[netindex.into_inner() as usize];
if let Some((bound_pip, usage)) = net.wires.get_mut(&wireid) {
assert!(*bound_pip == pip);
*usage += 1;
} else {
net.wires.insert(wireid, (pip, 1));
2022-12-17 00:30:59 +08:00
self.flat_wires[wire as usize].write().unwrap().curr_cong += 1;
}
}
2022-12-17 00:30:59 +08:00
fn unbind_pip_internal(&self, net: NetIndex, wire: WireId) {
2022-12-04 10:24:34 +08:00
let net = net.into_inner() as usize;
let wireidx = *self.wire_to_idx.get(&wire).unwrap() as usize;
2022-12-17 00:30:59 +08:00
let nd = &mut self.nets.write().unwrap()[net];
let (_pip, usage) = nd.wires.get_mut(&wire).unwrap();
2022-12-04 10:24:34 +08:00
*usage -= 1;
if *usage == 0 {
2022-12-17 00:30:59 +08:00
self.flat_wires[wireidx].write().unwrap().curr_cong -= 1;
nd.wires.remove(&wire);
2022-12-04 10:24:34 +08:00
}
}
2022-12-17 00:30:59 +08:00
fn ripup_arc(&self, ctx: &npnr::Context, arc: &Arc) {
2022-12-04 10:24:34 +08:00
let net = arc.net().into_inner() as usize;
let source_wire = arc.source_wire;
let mut wire = arc.sink_wire;
while wire != source_wire {
2022-12-17 00:30:59 +08:00
let pip = self.nets.read().unwrap()[net].wires.get(&wire).unwrap().0;
2022-12-04 10:24:34 +08:00
assert!(pip != PipId::null());
self.unbind_pip_internal(arc.net(), wire);
wire = ctx.pip_src_wire(pip);
}
2022-12-04 10:24:34 +08:00
}
2022-12-17 00:30:59 +08:00
fn reset_wires(&self, dirty_wires: &Vec<u32>) {
for &wire in dirty_wires {
let mut nwd = self.flat_wires[wire as usize].write().unwrap();
nwd.pip_fwd = PipId::null();
nwd.visited_fwd = false;
nwd.pip_bwd = PipId::null();
nwd.visited_bwd = false;
}
}
2022-11-28 00:26:17 +08:00
}