awooter: router correctness fixes

This commit is contained in:
Lofty 2022-12-04 02:24:34 +00:00
parent ec65ec3484
commit d0231fc67e

View File

@ -76,12 +76,13 @@ struct QueuedWire {
delay: f32,
congest: f32,
togo: f32,
criticality: f32,
wire: npnr::WireId,
}
impl QueuedWire {
pub fn new(delay: f32, congest: f32, togo: f32, wire: npnr::WireId) -> Self {
Self { delay, congest, togo, wire }
pub fn new(delay: f32, congest: f32, togo: f32, criticality: f32, wire: npnr::WireId) -> Self {
Self { delay, congest, togo, criticality, wire }
}
}
@ -95,8 +96,8 @@ impl Eq for QueuedWire {}
impl Ord for QueuedWire {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let me = (0.9 * self.delay) + (0.1 * self.congest) + self.togo;
let other = (0.9 * other.delay) + (0.1 * 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)
}
}
@ -173,6 +174,9 @@ impl Router {
self.wire_to_idx.insert(wire, idx as u32);
}
let mut delay = vec![1.0; arcs.len()];
let mut max_delay = 1.0;
loop {
let progress = progress.add(ProgressBar::new(arcs.len() as u64));
progress.set_style(
@ -181,7 +185,7 @@ impl Router {
.progress_chars("━╸ "),
);
for arc in arcs {
for (i, arc) in arcs.iter().enumerate() {
let net = unsafe { nets.net_from_index(arc.net).as_ref().unwrap() };
let name = ctx
.name_of(nets.name_from_index(arc.net))
@ -194,7 +198,7 @@ impl Router {
progress.inc(1);
progress.set_message(format!("{} @ {}", id, name));
self.route_arc(ctx, nets, arc);
delay[i] = self.route_arc(ctx, nets, arc, delay[i] / max_delay);
}
progress.finish_and_clear();
@ -204,20 +208,25 @@ impl Router {
overused += 1;
wd.hist_cong += (wd.curr_cong as f32) * ACCUMULATED_OVERUSE_FACTOR;
}
wd.curr_cong = 0;
}
if overused == 0 {
break;
}
for arc in arcs {
self.ripup_arc(ctx, arc);
}
max_delay = delay.iter().copied().reduce(f32::max).unwrap();
progress.println(format!("{}: {} wires overused", id, overused));
}
}
fn route_arc(&mut self, ctx: &npnr::Context, nets: &npnr::Nets, arc: &Arc) {
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, arc.source_wire));
queue.push(QueuedWire::new(0.0, 0.0, 0.0, criticality, arc.source_wire));
let mut found_sink = false;
@ -228,9 +237,12 @@ impl Router {
.to_string();
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;
while let Some(source) = queue.pop() {
if source.wire == arc.sink_wire {
found_sink = true;
delay = source.delay;
break;
}
@ -299,7 +311,7 @@ impl Router {
self.set_visited_fwd(sink, pip);
let qw = QueuedWire::new(delay, congest, ctx.estimate_delay(wire, arc.sink_wire), wire);
let qw = QueuedWire::new(delay, congest, ctx.estimate_delay(wire, arc.sink_wire), criticality, wire);
queue.push(qw);
}
}
@ -330,6 +342,8 @@ impl Router {
}
self.reset_wires();
return delay;
}
fn was_visited_fwd(&self, wire: u32) -> bool {
@ -357,6 +371,29 @@ impl Router {
}
}
fn unbind_pip_internal(&mut self, net: NetIndex, wire: WireId) {
let net = net.into_inner() as usize;
let wireidx = *self.wire_to_idx.get(&wire).unwrap() as usize;
let (_pip, usage) = self.nets[net].wires.get_mut(&wire).unwrap();
*usage -= 1;
if *usage == 0 {
self.flat_wires[wireidx].curr_cong -= 1;
self.nets[net].wires.remove(&wire);
}
}
fn ripup_arc(&mut self, ctx: &npnr::Context, arc: &Arc) {
let net = arc.net().into_inner() as usize;
let source_wire = arc.source_wire;
let mut wire = arc.sink_wire;
while wire != source_wire {
let pip = self.nets[net].wires.get(&wire).unwrap().0;
assert!(pip != PipId::null());
self.unbind_pip_internal(arc.net(), wire);
wire = ctx.pip_src_wire(pip);
}
}
fn reset_wires(&mut self) {
for &wire in &self.dirty_wires {
self.flat_wires[wire as usize].pip_fwd = PipId::null();
@ -364,17 +401,4 @@ impl Router {
}
self.dirty_wires.clear();
}
/*
void unbind_pip_internal(PerNetData &net, store_index<PortRef> user, WireId wire)
{
auto &wd = wire_data(wire);
auto &b = net.wires.at(wd.w);
--b.second;
if (b.second == 0) {
// No remaining arcs of this net bound to this wire
--wd.curr_cong;
net.wires.erase(wd.w);
}
}
*/
}