don't route to sinks that have already been routed to

This commit is contained in:
SpaceCat-Chan 2022-12-04 08:15:43 +01:00 committed by Lofty
parent 7484bd34dc
commit f1d51287ea

View File

@ -83,13 +83,22 @@ struct QueuedWire {
impl QueuedWire {
pub fn new(delay: f32, congest: f32, togo: f32, criticality: f32, wire: npnr::WireId) -> Self {
Self { delay, congest, togo, criticality, wire }
Self {
delay,
congest,
togo,
criticality,
wire,
}
}
}
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
self.delay == other.delay
&& self.congest == other.congest
&& self.togo == other.togo
&& self.wire == other.wire
}
}
@ -97,8 +106,11 @@ impl Eq for QueuedWire {}
impl Ord for QueuedWire {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let me = (self.criticality * self.delay) + ((1.0 - self.criticality) * self.congest) + self.togo;
let other = (other.criticality * other.delay) + ((1.0 - other.criticality) * other.congest) + other.togo;
let me =
(self.criticality * self.delay) + ((1.0 - self.criticality) * self.congest) + self.togo;
let other = (other.criticality * other.delay)
+ ((1.0 - other.criticality) * other.congest)
+ other.togo;
other.total_cmp(&me)
}
}
@ -111,6 +123,7 @@ impl PartialOrd for QueuedWire {
struct PerNetData {
wires: HashMap<WireId, (PipId, u32)>,
done_sinks: HashMap<WireId, f32>,
}
struct PerWireData {
@ -135,7 +148,12 @@ pub struct Router {
}
impl Router {
pub fn new(box_ne: partition::Coord, box_sw: partition::Coord, pressure: f32, history: f32) -> Self {
pub fn new(
box_ne: partition::Coord,
box_sw: partition::Coord,
pressure: f32,
history: f32,
) -> Self {
Self {
box_ne,
box_sw,
@ -160,6 +178,7 @@ impl Router {
for _ in 0..nets.len() {
self.nets.push(PerNetData {
wires: HashMap::new(),
done_sinks: HashMap::new(),
});
}
@ -187,12 +206,11 @@ impl Router {
.progress_chars("━╸ "),
);
for (i, arc) in arcs.iter().enumerate().sorted_by(|&(i, _), &(j, _)| (delay[i] / max_delay).total_cmp(&(delay[j] / max_delay))) {
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))
.to_str()
.unwrap();
let name = ctx.name_of(nets.name_from_index(arc.net)).to_str().unwrap();
if net.is_global() {
continue;
@ -219,6 +237,9 @@ impl Router {
for arc in arcs {
self.ripup_arc(ctx, arc);
}
for net in &mut self.nets {
net.done_sinks.clear();
}
max_delay = delay.iter().copied().reduce(f32::max).unwrap();
@ -226,11 +247,24 @@ impl Router {
}
}
fn route_arc(&mut self, ctx: &npnr::Context, nets: &npnr::Nets, arc: &Arc, criticality: f32) -> f32 {
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, ctx.estimate_delay(arc.source_wire, arc.sink_wire), 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;
let nd = &mut self.nets[arc.net().into_inner() as usize];
let name = ctx
.name_of(nets.name_from_index(arc.net))
@ -240,7 +274,20 @@ impl Router {
let verbose = false; //name == "soc0.processor.with_fpu.fpu_0.fpu_multiply_0.rin_CCU2C_S0_4$CCU2_FCI_INT";
let mut delay = 0.0;
if let Some(old_delay) = nd.done_sinks.get(&arc.get_sink_wire()) {
found_sink = true;
delay = *old_delay;
let source = arc.get_source_wire();
let mut wire = arc.get_sink_wire();
while wire != source {
let nd = &mut self.nets[arc.net().into_inner() as usize];
let (driver, _) = nd.wires.get(&wire).unwrap();
let driver = *driver;
self.set_visited_fwd(self.wire_to_idx[&wire], driver);
wire = ctx.pip_src_wire(driver);
}
} else {
while let Some(source) = queue.pop() {
if source.wire == arc.sink_wire {
found_sink = true;
@ -307,16 +354,26 @@ impl Router {
continue;
}
let node_delay = ctx.pip_delay(pip) + ctx.wire_delay(wire) + ctx.delay_epsilon();
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 as f32 * self.pressure));
let congest = source.congest
+ (node_delay + nwd.hist_cong)
* (1.0 + (nwd.curr_cong as f32 * self.pressure));
self.set_visited_fwd(sink, pip);
let qw = QueuedWire::new(delay, congest, ctx.estimate_delay(wire, arc.sink_wire), criticality, wire);
let qw = QueuedWire::new(
delay,
congest,
ctx.estimate_delay(wire, arc.sink_wire),
criticality,
wire,
);
queue.push(qw);
}
}
}
assert!(
found_sink,
@ -342,10 +399,12 @@ impl Router {
self.bind_pip_internal(arc.net(), wire, pip);
wire = *self.wire_to_idx.get(&ctx.pip_src_wire(pip)).unwrap();
}
let nd = &mut self.nets[arc.net().into_inner() as usize];
nd.done_sinks.insert(arc.get_sink_wire(), delay);
self.reset_wires();
return delay;
delay
}
fn was_visited_fwd(&self, wire: u32) -> bool {