don't route to sinks that have already been routed to
This commit is contained in:
parent
7484bd34dc
commit
f1d51287ea
@ -83,13 +83,22 @@ struct QueuedWire {
|
|||||||
|
|
||||||
impl QueuedWire {
|
impl QueuedWire {
|
||||||
pub fn new(delay: f32, congest: f32, togo: f32, criticality: f32, wire: npnr::WireId) -> Self {
|
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 {
|
impl PartialEq for QueuedWire {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
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 {
|
impl Ord for QueuedWire {
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
let me = (self.criticality * self.delay) + ((1.0 - self.criticality) * self.congest) + self.togo;
|
let me =
|
||||||
let other = (other.criticality * other.delay) + ((1.0 - other.criticality) * other.congest) + other.togo;
|
(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)
|
other.total_cmp(&me)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,6 +123,7 @@ impl PartialOrd for QueuedWire {
|
|||||||
|
|
||||||
struct PerNetData {
|
struct PerNetData {
|
||||||
wires: HashMap<WireId, (PipId, u32)>,
|
wires: HashMap<WireId, (PipId, u32)>,
|
||||||
|
done_sinks: HashMap<WireId, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PerWireData {
|
struct PerWireData {
|
||||||
@ -135,7 +148,12 @@ pub struct Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
Self {
|
||||||
box_ne,
|
box_ne,
|
||||||
box_sw,
|
box_sw,
|
||||||
@ -160,6 +178,7 @@ impl Router {
|
|||||||
for _ in 0..nets.len() {
|
for _ in 0..nets.len() {
|
||||||
self.nets.push(PerNetData {
|
self.nets.push(PerNetData {
|
||||||
wires: HashMap::new(),
|
wires: HashMap::new(),
|
||||||
|
done_sinks: HashMap::new(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,12 +206,11 @@ impl Router {
|
|||||||
.progress_chars("━╸ "),
|
.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 net = unsafe { nets.net_from_index(arc.net).as_ref().unwrap() };
|
||||||
let name = ctx
|
let name = ctx.name_of(nets.name_from_index(arc.net)).to_str().unwrap();
|
||||||
.name_of(nets.name_from_index(arc.net))
|
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if net.is_global() {
|
if net.is_global() {
|
||||||
continue;
|
continue;
|
||||||
@ -219,6 +237,9 @@ impl Router {
|
|||||||
for arc in arcs {
|
for arc in arcs {
|
||||||
self.ripup_arc(ctx, arc);
|
self.ripup_arc(ctx, arc);
|
||||||
}
|
}
|
||||||
|
for net in &mut self.nets {
|
||||||
|
net.done_sinks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
max_delay = delay.iter().copied().reduce(f32::max).unwrap();
|
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();
|
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 mut found_sink = false;
|
||||||
|
let nd = &mut self.nets[arc.net().into_inner() as usize];
|
||||||
|
|
||||||
let name = ctx
|
let name = ctx
|
||||||
.name_of(nets.name_from_index(arc.net))
|
.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 verbose = false; //name == "soc0.processor.with_fpu.fpu_0.fpu_multiply_0.rin_CCU2C_S0_4$CCU2_FCI_INT";
|
||||||
|
|
||||||
let mut delay = 0.0;
|
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() {
|
while let Some(source) = queue.pop() {
|
||||||
if source.wire == arc.sink_wire {
|
if source.wire == arc.sink_wire {
|
||||||
found_sink = true;
|
found_sink = true;
|
||||||
@ -307,16 +354,26 @@ impl Router {
|
|||||||
continue;
|
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 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);
|
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);
|
queue.push(qw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
found_sink,
|
found_sink,
|
||||||
@ -342,10 +399,12 @@ impl Router {
|
|||||||
self.bind_pip_internal(arc.net(), wire, pip);
|
self.bind_pip_internal(arc.net(), wire, pip);
|
||||||
wire = *self.wire_to_idx.get(&ctx.pip_src_wire(pip)).unwrap();
|
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();
|
self.reset_wires();
|
||||||
|
|
||||||
return delay;
|
delay
|
||||||
}
|
}
|
||||||
|
|
||||||
fn was_visited_fwd(&self, wire: u32) -> bool {
|
fn was_visited_fwd(&self, wire: u32) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user