awooter: it compiles but is broken
This commit is contained in:
parent
8b8abc2aac
commit
181d76772a
@ -1,4 +1,5 @@
|
|||||||
#![feature(c_unwind)]
|
#![feature(c_unwind)]
|
||||||
|
#![feature(let_chains)]
|
||||||
|
|
||||||
use std::{ptr::NonNull, time::Instant};
|
use std::{ptr::NonNull, time::Instant};
|
||||||
|
|
||||||
@ -60,7 +61,9 @@ fn extract_arcs_from_nets(ctx: &npnr::Context, nets: &npnr::Nets) -> Vec<route::
|
|||||||
for sink_wire in ctx.sink_wires(net, *sink_ref) {
|
for sink_wire in ctx.sink_wires(net, *sink_ref) {
|
||||||
arcs.push(route::Arc::new(
|
arcs.push(route::Arc::new(
|
||||||
source_wire,
|
source_wire,
|
||||||
|
source,
|
||||||
sink_wire,
|
sink_wire,
|
||||||
|
sink,
|
||||||
net.index(),
|
net.index(),
|
||||||
nets.name_from_index(net.index()),
|
nets.name_from_index(net.index()),
|
||||||
));
|
));
|
||||||
@ -252,16 +255,16 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
|
|||||||
|
|
||||||
let progress = MultiProgress::new();
|
let progress = MultiProgress::new();
|
||||||
|
|
||||||
let mut router = route::Router::new(&nets, wires, pressure, history);
|
let router = route::Router::new(&nets, wires, pressure, history);
|
||||||
partitions
|
partitions
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.for_each(|(box_ne, box_sw, arcs, id)| {
|
.for_each(|(box_ne, box_sw, arcs, id)| {
|
||||||
let thread = route::RouterThread::new(*box_ne, *box_sw, arcs, id, &progress);
|
let mut thread = route::RouterThread::new(*box_ne, *box_sw, arcs, id, &progress);
|
||||||
router.route(ctx, &nets, &thread);
|
router.route(ctx, &nets, &mut thread);
|
||||||
});
|
});
|
||||||
|
|
||||||
log_info!("Routing miscellaneous arcs\n");
|
log_info!("Routing miscellaneous arcs\n");
|
||||||
let thread = route::RouterThread::new(
|
let mut thread = route::RouterThread::new(
|
||||||
Coord::new(0, 0),
|
Coord::new(0, 0),
|
||||||
Coord::new(ctx.grid_dim_x(), ctx.grid_dim_y()),
|
Coord::new(ctx.grid_dim_x(), ctx.grid_dim_y()),
|
||||||
&special_arcs,
|
&special_arcs,
|
||||||
@ -269,7 +272,7 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
|
|||||||
&progress,
|
&progress,
|
||||||
);
|
);
|
||||||
|
|
||||||
router.route(ctx, &nets, &thread);
|
router.route(ctx, &nets, &mut thread);
|
||||||
|
|
||||||
let time = format!("{:.2}", (Instant::now() - start).as_secs_f32());
|
let time = format!("{:.2}", (Instant::now() - start).as_secs_f32());
|
||||||
log_info!("Routing took {}s\n", time.bold());
|
log_info!("Routing took {}s\n", time.bold());
|
||||||
|
@ -148,12 +148,12 @@ pub struct Context {
|
|||||||
impl Context {
|
impl Context {
|
||||||
/// Get grid X dimension. All bels and pips must have X coordinates in the range `0 .. getGridDimX()-1` (inclusive).
|
/// Get grid X dimension. All bels and pips must have X coordinates in the range `0 .. getGridDimX()-1` (inclusive).
|
||||||
pub fn grid_dim_x(&self) -> i32 {
|
pub fn grid_dim_x(&self) -> i32 {
|
||||||
unsafe { npnr_context_get_grid_dim_x(self) as i32 }
|
unsafe { npnr_context_get_grid_dim_x(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get grid Y dimension. All bels and pips must have Y coordinates in the range `0 .. getGridDimY()-1` (inclusive).
|
/// Get grid Y dimension. All bels and pips must have Y coordinates in the range `0 .. getGridDimY()-1` (inclusive).
|
||||||
pub fn grid_dim_y(&self) -> i32 {
|
pub fn grid_dim_y(&self) -> i32 {
|
||||||
unsafe { npnr_context_get_grid_dim_y(self) as i32 }
|
unsafe { npnr_context_get_grid_dim_y(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind a given bel to a given cell with the given strength.
|
/// Bind a given bel to a given cell with the given strength.
|
||||||
@ -208,7 +208,7 @@ impl Context {
|
|||||||
|
|
||||||
// TODO: Should this be a Duration? Does that even make sense?
|
// TODO: Should this be a Duration? Does that even make sense?
|
||||||
pub fn estimate_delay(&self, src: WireId, dst: WireId) -> f32 {
|
pub fn estimate_delay(&self, src: WireId, dst: WireId) -> f32 {
|
||||||
unsafe { npnr_context_estimate_delay(self, src, dst) as f32 }
|
unsafe { npnr_context_estimate_delay(self, src, dst) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pip_delay(&self, pip: PipId) -> f32 {
|
pub fn pip_delay(&self, pip: PipId) -> f32 {
|
||||||
|
@ -282,10 +282,10 @@ fn approximate_partition_results(
|
|||||||
let mut count_nw = 0;
|
let mut count_nw = 0;
|
||||||
for arc in arcs {
|
for arc in arcs {
|
||||||
// TODO(SpaceCat~Chan): stop being lazy and merge Loc and Coord already
|
// TODO(SpaceCat~Chan): stop being lazy and merge Loc and Coord already
|
||||||
let source_is_north = arc.source_loc().x < partition_point.0;
|
let source_is_north = arc.get_source_loc().x < partition_point.0;
|
||||||
let source_is_east = arc.source_loc().y < partition_point.1;
|
let source_is_east = arc.get_source_loc().y < partition_point.1;
|
||||||
let sink_is_north = arc.sink_loc().x < partition_point.0;
|
let sink_is_north = arc.get_sink_loc().x < partition_point.0;
|
||||||
let sink_is_east = arc.sink_loc().y < partition_point.1;
|
let sink_is_east = arc.get_sink_loc().y < partition_point.1;
|
||||||
if source_is_north == sink_is_north && source_is_east == sink_is_east {
|
if source_is_north == sink_is_north && source_is_east == sink_is_east {
|
||||||
match (source_is_north, source_is_east) {
|
match (source_is_north, source_is_east) {
|
||||||
(true, true) => count_ne += 1,
|
(true, true) => count_ne += 1,
|
||||||
@ -314,11 +314,11 @@ fn approximate_partition_results(
|
|||||||
// but i can't be bothered (yes this is all copy-pasted from the actual partitioner)
|
// but i can't be bothered (yes this is all copy-pasted from the actual partitioner)
|
||||||
let mut middle_horiz = (
|
let mut middle_horiz = (
|
||||||
partition_point.0,
|
partition_point.0,
|
||||||
split_line_over_x((arc.source_loc(), arc.sink_loc()), partition_point.0),
|
split_line_over_x((arc.get_source_loc(), arc.get_sink_loc()), partition_point.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut middle_vert = (
|
let mut middle_vert = (
|
||||||
split_line_over_y((arc.source_loc(), arc.sink_loc()), partition_point.1),
|
split_line_over_y((arc.get_source_loc(), arc.get_sink_loc()), partition_point.1),
|
||||||
partition_point.1,
|
partition_point.1,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ fn partition(
|
|||||||
|
|
||||||
let mut bad_nets = std::collections::HashSet::new();
|
let mut bad_nets = std::collections::HashSet::new();
|
||||||
|
|
||||||
let is_general_routing = |wire: &str| {
|
let _is_general_routing = |wire: &str| {
|
||||||
wire.contains("H00")
|
wire.contains("H00")
|
||||||
|| wire.contains("V00")
|
|| wire.contains("V00")
|
||||||
|| wire.contains("H01")
|
|| wire.contains("H01")
|
||||||
@ -517,20 +517,20 @@ fn partition(
|
|||||||
.progress_with(progress)
|
.progress_with(progress)
|
||||||
.flat_map(|arc| {
|
.flat_map(|arc| {
|
||||||
let raw_net = nets.net_from_index(arc.net());
|
let raw_net = nets.net_from_index(arc.net());
|
||||||
let source_loc = arc.source_loc();
|
let source_loc = arc.get_source_loc();
|
||||||
let source_coords: Coord = source_loc.into();
|
let source_coords: Coord = source_loc.into();
|
||||||
let source_is_north = source_coords.is_north_of(&partition_coords);
|
let source_is_north = source_coords.is_north_of(&partition_coords);
|
||||||
let source_is_east = source_coords.is_east_of(&partition_coords);
|
let source_is_east = source_coords.is_east_of(&partition_coords);
|
||||||
let sink_loc = arc.sink_loc();
|
let sink_loc = arc.get_sink_loc();
|
||||||
let sink_coords: Coord = sink_loc.into();
|
let sink_coords: Coord = sink_loc.into();
|
||||||
let sink_is_north = sink_coords.is_north_of(&partition_coords);
|
let sink_is_north = sink_coords.is_north_of(&partition_coords);
|
||||||
let sink_is_east = sink_coords.is_east_of(&partition_coords);
|
let sink_is_east = sink_coords.is_east_of(&partition_coords);
|
||||||
let name = ctx
|
let _name = ctx
|
||||||
.name_of(nets.name_from_index(arc.net()))
|
.name_of(nets.name_from_index(arc.net()))
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
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";
|
||||||
|
|
||||||
if bad_nets.contains(&arc.net()) {
|
if bad_nets.contains(&arc.net()) {
|
||||||
special.lock().unwrap().push(arc.clone());
|
special.lock().unwrap().push(arc.clone());
|
||||||
@ -862,8 +862,8 @@ fn partition_single_arc(
|
|||||||
max_bounds: &Coord,
|
max_bounds: &Coord,
|
||||||
segments: &[Quadrant],
|
segments: &[Quadrant],
|
||||||
) -> Option<Vec<(Quadrant, Arc)>> {
|
) -> Option<Vec<(Quadrant, Arc)>> {
|
||||||
let start_coord: Coord = arc.source_loc().into();
|
let start_coord: Coord = arc.get_source_loc().into();
|
||||||
let end_coord: Coord = arc.sink_loc().into();
|
let end_coord: Coord = arc.get_sink_loc().into();
|
||||||
let mut current_arc = arc.clone();
|
let mut current_arc = arc.clone();
|
||||||
let mut arcs = vec![];
|
let mut arcs = vec![];
|
||||||
for (from_quad, to_quad) in segments.iter().tuple_windows() {
|
for (from_quad, to_quad) in segments.iter().tuple_windows() {
|
||||||
@ -874,7 +874,7 @@ fn partition_single_arc(
|
|||||||
let pip = pip_selector.find_pip(
|
let pip = pip_selector.find_pip(
|
||||||
ctx,
|
ctx,
|
||||||
intersection.into(),
|
intersection.into(),
|
||||||
current_arc.source_loc(),
|
current_arc.get_source_loc(),
|
||||||
current_arc.net(),
|
current_arc.net(),
|
||||||
raw_net,
|
raw_net,
|
||||||
)?;
|
)?;
|
||||||
@ -916,73 +916,73 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
|
|
||||||
println!("\nne:");
|
println!("\nne:");
|
||||||
for arc in &ne {
|
for arc in &ne {
|
||||||
if arc.source_loc().x > x_part
|
if arc.get_source_loc().x > x_part
|
||||||
|| arc.source_loc().y > y_part
|
|| arc.get_source_loc().y > y_part
|
||||||
|| arc.sink_loc().x > x_part
|
|| arc.get_sink_loc().x > x_part
|
||||||
|| arc.sink_loc().y > y_part
|
|| arc.get_sink_loc().y > y_part
|
||||||
{
|
{
|
||||||
invalid_arcs_in_ne += 1;
|
invalid_arcs_in_ne += 1;
|
||||||
}
|
}
|
||||||
if arc.source_loc().x <= x_start
|
if arc.get_source_loc().x <= x_start
|
||||||
|| arc.source_loc().y <= y_start
|
|| arc.get_source_loc().y <= y_start
|
||||||
|| arc.sink_loc().x <= x_start
|
|| arc.get_sink_loc().x <= x_start
|
||||||
|| arc.sink_loc().y <= y_start
|
|| arc.get_sink_loc().y <= y_start
|
||||||
{
|
{
|
||||||
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
println!("oob: {:?} -> {:?}", arc.get_source_loc(), arc.get_sink_loc());
|
||||||
out_of_bound_arcs_in_ne += 1;
|
out_of_bound_arcs_in_ne += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("\nse:");
|
println!("\nse:");
|
||||||
for arc in &se {
|
for arc in &se {
|
||||||
if arc.source_loc().x < x_part
|
if arc.get_source_loc().x < x_part
|
||||||
|| arc.source_loc().y > y_part
|
|| arc.get_source_loc().y > y_part
|
||||||
|| arc.sink_loc().x < x_part
|
|| arc.get_sink_loc().x < x_part
|
||||||
|| arc.sink_loc().y > y_part
|
|| arc.get_sink_loc().y > y_part
|
||||||
{
|
{
|
||||||
invalid_arcs_in_se += 1;
|
invalid_arcs_in_se += 1;
|
||||||
}
|
}
|
||||||
if arc.source_loc().x >= x_finish
|
if arc.get_source_loc().x >= x_finish
|
||||||
|| arc.source_loc().y <= y_start
|
|| arc.get_source_loc().y <= y_start
|
||||||
|| arc.sink_loc().x >= x_finish
|
|| arc.get_sink_loc().x >= x_finish
|
||||||
|| arc.sink_loc().y <= y_start
|
|| arc.get_sink_loc().y <= y_start
|
||||||
{
|
{
|
||||||
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
println!("oob: {:?} -> {:?}", arc.get_source_loc(), arc.get_sink_loc());
|
||||||
out_of_bound_arcs_in_se += 1;
|
out_of_bound_arcs_in_se += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("\nsw:");
|
println!("\nsw:");
|
||||||
for arc in &sw {
|
for arc in &sw {
|
||||||
if arc.source_loc().x < x_part
|
if arc.get_source_loc().x < x_part
|
||||||
|| arc.source_loc().y < y_part
|
|| arc.get_source_loc().y < y_part
|
||||||
|| arc.sink_loc().x < x_part
|
|| arc.get_sink_loc().x < x_part
|
||||||
|| arc.sink_loc().y < y_part
|
|| arc.get_sink_loc().y < y_part
|
||||||
{
|
{
|
||||||
invalid_arcs_in_sw += 1;
|
invalid_arcs_in_sw += 1;
|
||||||
}
|
}
|
||||||
if arc.source_loc().x >= x_finish
|
if arc.get_source_loc().x >= x_finish
|
||||||
|| arc.source_loc().y >= y_finish
|
|| arc.get_source_loc().y >= y_finish
|
||||||
|| arc.sink_loc().x >= x_finish
|
|| arc.get_sink_loc().x >= x_finish
|
||||||
|| arc.sink_loc().y >= y_finish
|
|| arc.get_sink_loc().y >= y_finish
|
||||||
{
|
{
|
||||||
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
println!("oob: {:?} -> {:?}", arc.get_source_loc(), arc.get_sink_loc());
|
||||||
out_of_bound_arcs_in_sw += 1;
|
out_of_bound_arcs_in_sw += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("\nnw:");
|
println!("\nnw:");
|
||||||
for arc in &nw {
|
for arc in &nw {
|
||||||
if arc.source_loc().x > x_part
|
if arc.get_source_loc().x > x_part
|
||||||
|| arc.source_loc().y < y_part
|
|| arc.get_source_loc().y < y_part
|
||||||
|| arc.sink_loc().x > x_part
|
|| arc.get_sink_loc().x > x_part
|
||||||
|| arc.sink_loc().y < y_part
|
|| arc.get_sink_loc().y < y_part
|
||||||
{
|
{
|
||||||
invalid_arcs_in_nw += 1;
|
invalid_arcs_in_nw += 1;
|
||||||
}
|
}
|
||||||
if arc.source_loc().x <= x_start
|
if arc.get_source_loc().x <= x_start
|
||||||
|| arc.source_loc().y >= y_finish
|
|| arc.get_source_loc().y >= y_finish
|
||||||
|| arc.sink_loc().x <= x_start
|
|| arc.get_sink_loc().x <= x_start
|
||||||
|| arc.sink_loc().y >= y_finish
|
|| arc.get_sink_loc().y >= y_finish
|
||||||
{
|
{
|
||||||
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
println!("oob: {:?} -> {:?}", arc.get_source_loc(), arc.get_sink_loc());
|
||||||
out_of_bound_arcs_in_nw += 1;
|
out_of_bound_arcs_in_nw += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1116,9 +1116,9 @@ impl PipSelector {
|
|||||||
if loc.y == partition_point.y {
|
if loc.y == partition_point.y {
|
||||||
// pip is on east-west border
|
// pip is on east-west border
|
||||||
|
|
||||||
let (mut src_has_east, mut src_has_west, mut src_has_middle) =
|
let (mut src_has_east, mut src_has_west, src_has_middle) =
|
||||||
(false, false, false);
|
(false, false, false);
|
||||||
let (mut dst_has_east, mut dst_has_west, mut dst_has_middle) =
|
let (mut dst_has_east, mut dst_has_west, dst_has_middle) =
|
||||||
(false, false, false);
|
(false, false, false);
|
||||||
|
|
||||||
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(pip)) {
|
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(pip)) {
|
||||||
@ -1132,7 +1132,7 @@ impl PipSelector {
|
|||||||
src_has_east |= src_pip_coord.is_east_of(&partition_point.into());
|
src_has_east |= src_pip_coord.is_east_of(&partition_point.into());
|
||||||
src_has_west |= src_pip_coord.is_west_of(&partition_point.into());
|
src_has_west |= src_pip_coord.is_west_of(&partition_point.into());
|
||||||
if src_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
|
if src_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
|
||||||
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
|
for _src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
|
||||||
//pips.push((src_pip, depth + 1));
|
//pips.push((src_pip, depth + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1151,7 +1151,7 @@ impl PipSelector {
|
|||||||
dst_has_east |= dst_pip_coord.is_east_of(&partition_point.into());
|
dst_has_east |= dst_pip_coord.is_east_of(&partition_point.into());
|
||||||
dst_has_west |= dst_pip_coord.is_west_of(&partition_point.into());
|
dst_has_west |= dst_pip_coord.is_west_of(&partition_point.into());
|
||||||
if dst_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
|
if dst_pip_coord.y == loc.y && depth < MAX_PIP_SEARCH_DEPTH {
|
||||||
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
|
for _dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
|
||||||
//pips.push((dst_pip, depth + 1));
|
//pips.push((dst_pip, depth + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1181,9 +1181,9 @@ impl PipSelector {
|
|||||||
} else {
|
} else {
|
||||||
// pip is on south-north border
|
// pip is on south-north border
|
||||||
|
|
||||||
let (mut src_has_north, mut src_has_south, mut src_has_middle) =
|
let (mut src_has_north, mut src_has_south, src_has_middle) =
|
||||||
(false, false, false);
|
(false, false, false);
|
||||||
let (mut dst_has_north, mut dst_has_south, mut dst_has_middle) =
|
let (mut dst_has_north, mut dst_has_south, dst_has_middle) =
|
||||||
(false, false, false);
|
(false, false, false);
|
||||||
|
|
||||||
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(pip)) {
|
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(pip)) {
|
||||||
@ -1199,7 +1199,7 @@ impl PipSelector {
|
|||||||
src_has_south |= src_pip_coord.is_south_of(&partition_point.into());
|
src_has_south |= src_pip_coord.is_south_of(&partition_point.into());
|
||||||
if src_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
|
if src_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
|
||||||
// yaaaaaaay, we need to everything again for this pip :)
|
// yaaaaaaay, we need to everything again for this pip :)
|
||||||
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
|
for _src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
|
||||||
//pips.push((src_pip, depth + 1));
|
//pips.push((src_pip, depth + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1218,7 +1218,7 @@ impl PipSelector {
|
|||||||
dst_has_north |= dst_pip_coord.is_north_of(&partition_point.into());
|
dst_has_north |= dst_pip_coord.is_north_of(&partition_point.into());
|
||||||
dst_has_south |= dst_pip_coord.is_south_of(&partition_point.into());
|
dst_has_south |= dst_pip_coord.is_south_of(&partition_point.into());
|
||||||
if dst_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
|
if dst_pip_coord.x == loc.x && depth < MAX_PIP_SEARCH_DEPTH {
|
||||||
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
|
for _dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
|
||||||
//pips.push((dst_pip, depth + 1));
|
//pips.push((dst_pip, depth + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1383,7 +1383,7 @@ impl PipSelector {
|
|||||||
let source = ctx.pip_src_wire(*pip);
|
let source = ctx.pip_src_wire(*pip);
|
||||||
let sink = ctx.pip_dst_wire(*pip);
|
let sink = ctx.pip_dst_wire(*pip);
|
||||||
|
|
||||||
let (mut source, mut sink) = match sink.cmp(&source) {
|
let (source, sink) = match sink.cmp(&source) {
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
let source = self.used_wires.get(&source).unwrap().lock().unwrap();
|
let source = self.used_wires.get(&source).unwrap().lock().unwrap();
|
||||||
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
|
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
|
||||||
@ -1397,7 +1397,7 @@ impl PipSelector {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut candidate = self.used_pips.get(pip).unwrap().lock().unwrap();
|
let candidate = self.used_pips.get(pip).unwrap().lock().unwrap();
|
||||||
if candidate.map(|other| other != net).unwrap_or(false) {
|
if candidate.map(|other| other != net).unwrap_or(false) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -1485,8 +1485,6 @@ impl PipSelector {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
// cursed iterator magic :3
|
// cursed iterator magic :3
|
||||||
// (rust, can we please have generators yet?)
|
// (rust, can we please have generators yet?)
|
||||||
(0..=times_up)
|
(0..=times_up)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::{BinaryHeap, HashMap, HashSet},
|
collections::{BinaryHeap, HashMap, HashSet},
|
||||||
time::Instant,
|
time::Instant, sync::RwLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
@ -8,28 +8,34 @@ use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
npnr::{self, IdString, NetIndex, PipId, WireId},
|
npnr::{self, IdString, NetIndex, PipId, WireId, Loc},
|
||||||
partition,
|
partition,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Hash, PartialEq, Eq)]
|
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct Arc {
|
pub struct Arc {
|
||||||
source_wire: WireId,
|
source_wire: WireId,
|
||||||
|
source_loc: Loc,
|
||||||
sink_wire: WireId,
|
sink_wire: WireId,
|
||||||
|
sink_loc: Loc,
|
||||||
net: NetIndex,
|
net: NetIndex,
|
||||||
name: IdString,
|
name: IdString,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arc {
|
impl Arc {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
source_wire: npnr::WireId,
|
source_wire: WireId,
|
||||||
sink_wire: npnr::WireId,
|
source_loc: Loc,
|
||||||
|
sink_wire: WireId,
|
||||||
|
sink_loc: Loc,
|
||||||
net: NetIndex,
|
net: NetIndex,
|
||||||
name: IdString,
|
name: IdString,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source_wire,
|
source_wire,
|
||||||
|
source_loc,
|
||||||
sink_wire,
|
sink_wire,
|
||||||
|
sink_loc,
|
||||||
net,
|
net,
|
||||||
name,
|
name,
|
||||||
}
|
}
|
||||||
@ -41,13 +47,17 @@ impl Arc {
|
|||||||
(
|
(
|
||||||
Self {
|
Self {
|
||||||
source_wire: self.source_wire,
|
source_wire: self.source_wire,
|
||||||
|
source_loc: self.source_loc,
|
||||||
sink_wire: pip_src,
|
sink_wire: pip_src,
|
||||||
|
sink_loc: ctx.pip_location(pip),
|
||||||
net: self.net,
|
net: self.net,
|
||||||
name: self.name,
|
name: self.name,
|
||||||
},
|
},
|
||||||
Self {
|
Self {
|
||||||
source_wire: pip_dst,
|
source_wire: pip_dst,
|
||||||
|
source_loc: ctx.pip_location(pip),
|
||||||
sink_wire: self.sink_wire,
|
sink_wire: self.sink_wire,
|
||||||
|
sink_loc: self.sink_loc,
|
||||||
net: self.net,
|
net: self.net,
|
||||||
name: self.name,
|
name: self.name,
|
||||||
},
|
},
|
||||||
@ -63,6 +73,12 @@ impl Arc {
|
|||||||
pub fn net(&self) -> npnr::NetIndex {
|
pub fn net(&self) -> npnr::NetIndex {
|
||||||
self.net
|
self.net
|
||||||
}
|
}
|
||||||
|
pub fn get_source_loc(&self) -> Loc {
|
||||||
|
self.source_loc
|
||||||
|
}
|
||||||
|
pub fn get_sink_loc(&self) -> Loc {
|
||||||
|
self.sink_loc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -147,6 +163,7 @@ pub struct RouterThread<'a> {
|
|||||||
arcs: &'a [Arc],
|
arcs: &'a [Arc],
|
||||||
id: &'a str,
|
id: &'a str,
|
||||||
progress: &'a MultiProgress,
|
progress: &'a MultiProgress,
|
||||||
|
dirty_wires: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RouterThread<'a> {
|
impl<'a> RouterThread<'a> {
|
||||||
@ -163,6 +180,7 @@ impl<'a> RouterThread<'a> {
|
|||||||
arcs,
|
arcs,
|
||||||
id,
|
id,
|
||||||
progress,
|
progress,
|
||||||
|
dirty_wires: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,10 +188,9 @@ impl<'a> RouterThread<'a> {
|
|||||||
pub struct Router {
|
pub struct Router {
|
||||||
pressure: f32,
|
pressure: f32,
|
||||||
history: f32,
|
history: f32,
|
||||||
nets: Vec<PerNetData>,
|
nets: RwLock<Vec<PerNetData>>,
|
||||||
wire_to_idx: HashMap<WireId, u32>,
|
wire_to_idx: HashMap<WireId, u32>,
|
||||||
flat_wires: Vec<PerWireData>,
|
flat_wires: Vec<RwLock<PerWireData>>,
|
||||||
dirty_wires: Vec<u32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Router {
|
impl Router {
|
||||||
@ -190,7 +207,7 @@ impl Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (idx, &wire) in wires.iter().enumerate() {
|
for (idx, &wire) in wires.iter().enumerate() {
|
||||||
flat_wires.push(PerWireData {
|
flat_wires.push(RwLock::new(PerWireData {
|
||||||
wire,
|
wire,
|
||||||
curr_cong: 0,
|
curr_cong: 0,
|
||||||
hist_cong: 0.0,
|
hist_cong: 0.0,
|
||||||
@ -200,21 +217,20 @@ impl Router {
|
|||||||
visited_fwd: false,
|
visited_fwd: false,
|
||||||
pip_bwd: PipId::null(),
|
pip_bwd: PipId::null(),
|
||||||
visited_bwd: false,
|
visited_bwd: false,
|
||||||
});
|
}));
|
||||||
wire_to_idx.insert(wire, idx as u32);
|
wire_to_idx.insert(wire, idx as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pressure,
|
pressure,
|
||||||
history,
|
history,
|
||||||
nets: net_vec,
|
nets: RwLock::new(net_vec),
|
||||||
wire_to_idx: HashMap::new(),
|
wire_to_idx,
|
||||||
flat_wires: Vec::new(),
|
flat_wires,
|
||||||
dirty_wires: Vec::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn route(&mut self, ctx: &npnr::Context, nets: &npnr::Nets, this: &RouterThread) {
|
pub fn route(&self, ctx: &npnr::Context, nets: &npnr::Nets, this: &mut RouterThread) {
|
||||||
let mut delay = HashMap::new();
|
let mut delay = HashMap::new();
|
||||||
|
|
||||||
for arc in this.arcs {
|
for arc in this.arcs {
|
||||||
@ -255,9 +271,12 @@ impl Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut overused = HashSet::new();
|
let mut overused = HashSet::new();
|
||||||
for wd in self.flat_wires.iter_mut().filter(|wd| wd.curr_cong > 1) {
|
for wd in self.flat_wires.iter() {
|
||||||
overused.insert(wd.wire);
|
let mut wd = wd.write().unwrap();
|
||||||
wd.hist_cong += (wd.curr_cong as f32) * self.history;
|
if wd.curr_cong > 1 {
|
||||||
|
overused.insert(wd.wire);
|
||||||
|
wd.hist_cong += (wd.curr_cong as f32) * self.history;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if overused.is_empty() {
|
if overused.is_empty() {
|
||||||
@ -284,7 +303,7 @@ impl Router {
|
|||||||
|
|
||||||
let mut next_arcs = Vec::new();
|
let mut next_arcs = Vec::new();
|
||||||
for arc in this.arcs {
|
for arc in this.arcs {
|
||||||
for wire in self.nets[arc.net.into_inner() as usize].wires.keys() {
|
for wire in self.nets.read().unwrap()[arc.net.into_inner() as usize].wires.keys() {
|
||||||
if overused.contains(wire) {
|
if overused.contains(wire) {
|
||||||
next_arcs.push(arc);
|
next_arcs.push(arc);
|
||||||
}
|
}
|
||||||
@ -294,7 +313,7 @@ impl Router {
|
|||||||
for &arc in &route_arcs {
|
for &arc in &route_arcs {
|
||||||
self.ripup_arc(ctx, arc);
|
self.ripup_arc(ctx, arc);
|
||||||
}
|
}
|
||||||
for net in &mut self.nets {
|
for net in self.nets.write().unwrap().iter_mut() {
|
||||||
net.done_sinks.clear();
|
net.done_sinks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,8 +355,8 @@ impl Router {
|
|||||||
fn can_visit_pip(&self, ctx: &npnr::Context, nets: &npnr::Nets, arc: &Arc, pip: PipId) -> bool {
|
fn can_visit_pip(&self, ctx: &npnr::Context, nets: &npnr::Nets, arc: &Arc, pip: PipId) -> bool {
|
||||||
let wire = ctx.pip_dst_wire(pip);
|
let wire = ctx.pip_dst_wire(pip);
|
||||||
let sink = *self.wire_to_idx.get(&wire).unwrap();
|
let sink = *self.wire_to_idx.get(&wire).unwrap();
|
||||||
let nd = &self.nets[arc.net().into_inner() as usize];
|
let nd = &self.nets.read().unwrap()[arc.net().into_inner() as usize];
|
||||||
let nwd = &self.flat_wires[sink as usize];
|
let nwd = &self.flat_wires[sink as usize].read().unwrap();
|
||||||
/*let pip_coord = partition::Coord::from(ctx.pip_location(pip));
|
/*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) {
|
if pip_coord.is_north_of(&self.box_ne) || pip_coord.is_east_of(&self.box_ne) {
|
||||||
return false;
|
return false;
|
||||||
@ -361,27 +380,24 @@ impl Router {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step<F1, F2, F3, F4, F5, I>(
|
#[allow(clippy::too_many_arguments)]
|
||||||
&mut self,
|
fn step<'b, 'a: 'b, I>(
|
||||||
ctx: &npnr::Context,
|
&'a self,
|
||||||
|
ctx: &'b npnr::Context,
|
||||||
nets: &npnr::Nets,
|
nets: &npnr::Nets,
|
||||||
arc: &Arc,
|
arc: &Arc,
|
||||||
criticality: f32,
|
criticality: f32,
|
||||||
queue: &mut BinaryHeap<QueuedWire>,
|
queue: &mut BinaryHeap<QueuedWire>,
|
||||||
midpoint: &mut Option<u32>,
|
midpoint: &mut Option<u32>,
|
||||||
target: WireId,
|
target: WireId,
|
||||||
was_visited: F1,
|
dirty_wires: &mut Vec<u32>,
|
||||||
set_visited: F2,
|
was_visited: impl Fn(&Self, u32) -> bool,
|
||||||
is_done: F3,
|
set_visited: impl Fn(&Self, u32, PipId, &mut Vec<u32>),
|
||||||
pip_iter: F4,
|
is_done: impl Fn(&Self, u32) -> bool,
|
||||||
pip_wire: F5,
|
pip_iter: impl Fn(&'b npnr::Context, WireId) -> I,
|
||||||
|
pip_wire: impl Fn(&npnr::Context, PipId) -> WireId,
|
||||||
) -> bool
|
) -> bool
|
||||||
where
|
where
|
||||||
F1: Fn(&Self, u32) -> bool,
|
|
||||||
F2: Fn(&mut Self, u32, PipId),
|
|
||||||
F3: Fn(&Self, u32) -> bool,
|
|
||||||
F4: Fn(&npnr::Context, WireId) -> I,
|
|
||||||
F5: Fn(&npnr::Context, PipId) -> WireId,
|
|
||||||
I: Iterator<Item = PipId>,
|
I: Iterator<Item = PipId>,
|
||||||
{
|
{
|
||||||
if let Some(source) = queue.pop() {
|
if let Some(source) = queue.pop() {
|
||||||
@ -390,7 +406,7 @@ impl Router {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let Some(pip) = source.from_pip {
|
if let Some(pip) = source.from_pip {
|
||||||
set_visited(self, source_idx, pip);
|
set_visited(self, source_idx, pip, dirty_wires);
|
||||||
}
|
}
|
||||||
if is_done(self, source_idx) {
|
if is_done(self, source_idx) {
|
||||||
*midpoint = Some(source_idx);
|
*midpoint = Some(source_idx);
|
||||||
@ -407,8 +423,9 @@ impl Router {
|
|||||||
if was_visited(self, sink) {
|
if was_visited(self, sink) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set_visited(self, sink, pip);
|
|
||||||
let nwd = &self.flat_wires[sink as usize];
|
set_visited(self, sink, pip, dirty_wires);
|
||||||
|
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 node_delay = ctx.pip_delay(pip) + ctx.wire_delay(wire) + ctx.delay_epsilon();
|
||||||
let sum_delay = source.delay + node_delay;
|
let sum_delay = source.delay + node_delay;
|
||||||
let congest = source.congest
|
let congest = source.congest
|
||||||
@ -432,7 +449,7 @@ impl Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn route_arc(
|
fn route_arc(
|
||||||
&mut self,
|
&self,
|
||||||
ctx: &npnr::Context,
|
ctx: &npnr::Context,
|
||||||
nets: &npnr::Nets,
|
nets: &npnr::Nets,
|
||||||
arc: &Arc,
|
arc: &Arc,
|
||||||
@ -466,17 +483,20 @@ impl Router {
|
|||||||
let source_wire = *self.wire_to_idx.get(&arc.source_wire).unwrap();
|
let source_wire = *self.wire_to_idx.get(&arc.source_wire).unwrap();
|
||||||
let sink_wire = *self.wire_to_idx.get(&arc.sink_wire).unwrap();
|
let sink_wire = *self.wire_to_idx.get(&arc.sink_wire).unwrap();
|
||||||
|
|
||||||
self.dirty_wires.push(source_wire);
|
let mut dirty_wires = Vec::new();
|
||||||
self.dirty_wires.push(sink_wire);
|
|
||||||
|
|
||||||
let nd = &self.nets[arc.net().into_inner() as usize];
|
dirty_wires.push(source_wire);
|
||||||
if nd.done_sinks.contains(&arc.sink_wire()) {
|
dirty_wires.push(sink_wire);
|
||||||
|
|
||||||
|
let already_done = self.nets.read().unwrap()[arc.net().into_inner() as usize].done_sinks.contains(&arc.sink_wire);
|
||||||
|
if already_done {
|
||||||
midpoint = Some(*self.wire_to_idx.get(&arc.sink_wire).unwrap());
|
midpoint = Some(*self.wire_to_idx.get(&arc.sink_wire).unwrap());
|
||||||
|
|
||||||
let mut wire = arc.sink_wire();
|
let mut wire = arc.sink_wire();
|
||||||
while wire != arc.source_wire() {
|
while wire != arc.source_wire() {
|
||||||
|
let nd = &self.nets.read().unwrap()[arc.net().into_inner() as usize];
|
||||||
let driver = nd.wires.get(&wire).unwrap().0;
|
let driver = nd.wires.get(&wire).unwrap().0;
|
||||||
self.set_visited_fwd(self.wire_to_idx[&wire], driver);
|
self.set_visited_fwd(self.wire_to_idx[&wire], driver, &mut dirty_wires);
|
||||||
wire = ctx.pip_src_wire(driver);
|
wire = ctx.pip_src_wire(driver);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -490,6 +510,7 @@ impl Router {
|
|||||||
&mut fwd_queue,
|
&mut fwd_queue,
|
||||||
&mut midpoint,
|
&mut midpoint,
|
||||||
arc.sink_wire,
|
arc.sink_wire,
|
||||||
|
&mut dirty_wires,
|
||||||
Self::was_visited_fwd,
|
Self::was_visited_fwd,
|
||||||
Self::set_visited_fwd,
|
Self::set_visited_fwd,
|
||||||
Self::was_visited_bwd,
|
Self::was_visited_bwd,
|
||||||
@ -499,7 +520,7 @@ impl Router {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Step backward
|
// Step backward
|
||||||
if !self.step(
|
/*if !self.step(
|
||||||
ctx,
|
ctx,
|
||||||
nets,
|
nets,
|
||||||
arc,
|
arc,
|
||||||
@ -507,6 +528,7 @@ impl Router {
|
|||||||
&mut bwd_queue,
|
&mut bwd_queue,
|
||||||
&mut midpoint,
|
&mut midpoint,
|
||||||
arc.source_wire,
|
arc.source_wire,
|
||||||
|
&mut dirty_wires,
|
||||||
Self::was_visited_bwd,
|
Self::was_visited_bwd,
|
||||||
Self::set_visited_bwd,
|
Self::set_visited_bwd,
|
||||||
Self::was_visited_fwd,
|
Self::was_visited_fwd,
|
||||||
@ -514,9 +536,9 @@ impl Router {
|
|||||||
npnr::Context::pip_src_wire,
|
npnr::Context::pip_src_wire,
|
||||||
) {
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
self.flat_wires[source_wire as usize].visited_fwd = true;
|
self.flat_wires[source_wire as usize].write().unwrap().visited_fwd = true;
|
||||||
self.flat_wires[sink_wire as usize].visited_bwd = true;
|
self.flat_wires[sink_wire as usize].write().unwrap().visited_bwd = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,11 +555,14 @@ impl Router {
|
|||||||
let mut calculated_delay = 0.0;
|
let mut calculated_delay = 0.0;
|
||||||
|
|
||||||
while wire != source_wire {
|
while wire != source_wire {
|
||||||
let pip = self.flat_wires[wire as usize].pip_fwd;
|
let (pip, wireid) = {
|
||||||
|
let nwd = self.flat_wires[wire as usize].read().unwrap();
|
||||||
|
(nwd.pip_fwd, nwd.wire)
|
||||||
|
};
|
||||||
assert!(pip != PipId::null());
|
assert!(pip != PipId::null());
|
||||||
|
|
||||||
let node_delay = ctx.pip_delay(pip)
|
let node_delay = ctx.pip_delay(pip)
|
||||||
+ ctx.wire_delay(self.flat_wires[wire as usize].wire)
|
+ ctx.wire_delay(wireid)
|
||||||
+ ctx.delay_epsilon();
|
+ ctx.delay_epsilon();
|
||||||
calculated_delay += node_delay;
|
calculated_delay += node_delay;
|
||||||
|
|
||||||
@ -546,94 +571,97 @@ impl Router {
|
|||||||
}
|
}
|
||||||
let mut wire = midpoint.unwrap();
|
let mut wire = midpoint.unwrap();
|
||||||
while wire != sink_wire {
|
while wire != sink_wire {
|
||||||
let pip = self.flat_wires[wire as usize].pip_bwd;
|
let (pip, wireid) = {
|
||||||
|
let nwd = self.flat_wires[wire as usize].read().unwrap();
|
||||||
|
(nwd.pip_bwd, nwd.wire)
|
||||||
|
};
|
||||||
assert!(pip != PipId::null());
|
assert!(pip != PipId::null());
|
||||||
// do note that the order is inverted from the fwd loop
|
// do note that the order is inverted from the fwd loop
|
||||||
wire = *self.wire_to_idx.get(&ctx.pip_dst_wire(pip)).unwrap();
|
wire = *self.wire_to_idx.get(&ctx.pip_dst_wire(pip)).unwrap();
|
||||||
|
|
||||||
let node_delay = ctx.pip_delay(pip)
|
let node_delay = ctx.pip_delay(pip)
|
||||||
+ ctx.wire_delay(self.flat_wires[wire as usize].wire)
|
+ ctx.wire_delay(wireid)
|
||||||
+ ctx.delay_epsilon();
|
+ ctx.delay_epsilon();
|
||||||
calculated_delay += node_delay;
|
calculated_delay += node_delay;
|
||||||
|
|
||||||
self.bind_pip_internal(arc.net(), wire, pip);
|
self.bind_pip_internal(arc.net(), wire, pip);
|
||||||
}
|
}
|
||||||
let nd = &mut self.nets[arc.net().into_inner() as usize];
|
self.nets.write().unwrap()[arc.net().into_inner() as usize].done_sinks.insert(arc.sink_wire);
|
||||||
nd.done_sinks.insert(arc.sink_wire());
|
|
||||||
|
|
||||||
self.reset_wires();
|
self.reset_wires(&dirty_wires);
|
||||||
|
|
||||||
calculated_delay
|
calculated_delay
|
||||||
}
|
}
|
||||||
|
|
||||||
fn was_visited_fwd(&self, wire: u32) -> bool {
|
fn was_visited_fwd(&self, wire: u32) -> bool {
|
||||||
self.flat_wires[wire as usize].visited_fwd
|
self.flat_wires[wire as usize].read().unwrap().visited_fwd
|
||||||
}
|
}
|
||||||
|
|
||||||
fn was_visited_bwd(&self, wire: u32) -> bool {
|
fn was_visited_bwd(&self, wire: u32) -> bool {
|
||||||
self.flat_wires[wire as usize].visited_bwd
|
self.flat_wires[wire as usize].read().unwrap().visited_bwd
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visited_fwd(&mut self, wire: u32, pip: PipId) {
|
fn set_visited_fwd(&self, wire: u32, pip: PipId, dirty_wires: &mut Vec<u32>) {
|
||||||
let wd = &mut self.flat_wires[wire as usize];
|
let mut wd = self.flat_wires[wire as usize].write().unwrap();
|
||||||
if !wd.visited_fwd {
|
if !wd.visited_fwd {
|
||||||
self.dirty_wires.push(wire);
|
dirty_wires.push(wire);
|
||||||
}
|
}
|
||||||
wd.pip_fwd = pip;
|
wd.pip_fwd = pip;
|
||||||
wd.visited_fwd = true;
|
wd.visited_fwd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visited_bwd(&mut self, wire: u32, pip: PipId) {
|
fn set_visited_bwd(&self, wire: u32, pip: PipId, dirty_wires: &mut Vec<u32>) {
|
||||||
let wd = &mut self.flat_wires[wire as usize];
|
let mut wd = self.flat_wires[wire as usize].write().unwrap();
|
||||||
if !wd.visited_bwd {
|
if !wd.visited_bwd {
|
||||||
self.dirty_wires.push(wire);
|
dirty_wires.push(wire);
|
||||||
}
|
}
|
||||||
wd.pip_bwd = pip;
|
wd.pip_bwd = pip;
|
||||||
wd.visited_bwd = true;
|
wd.visited_bwd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_pip_internal(&mut self, netindex: NetIndex, wire: u32, pip: PipId) {
|
fn bind_pip_internal(&self, netindex: NetIndex, wire: u32, pip: PipId) {
|
||||||
let wireid = self.flat_wires[wire as usize].wire;
|
let wireid = self.flat_wires[wire as usize].read().unwrap().wire;
|
||||||
let net = &mut self.nets[netindex.into_inner() as usize];
|
let net = &mut self.nets.write().unwrap()[netindex.into_inner() as usize];
|
||||||
if let Some((bound_pip, usage)) = net.wires.get_mut(&wireid) {
|
if let Some((bound_pip, usage)) = net.wires.get_mut(&wireid) {
|
||||||
assert!(*bound_pip == pip);
|
assert!(*bound_pip == pip);
|
||||||
*usage += 1;
|
*usage += 1;
|
||||||
} else {
|
} else {
|
||||||
net.wires.insert(wireid, (pip, 1));
|
net.wires.insert(wireid, (pip, 1));
|
||||||
self.flat_wires[wire as usize].curr_cong += 1;
|
self.flat_wires[wire as usize].write().unwrap().curr_cong += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unbind_pip_internal(&mut self, net: NetIndex, wire: WireId) {
|
fn unbind_pip_internal(&self, net: NetIndex, wire: WireId) {
|
||||||
let net = net.into_inner() as usize;
|
let net = net.into_inner() as usize;
|
||||||
let wireidx = *self.wire_to_idx.get(&wire).unwrap() as usize;
|
let wireidx = *self.wire_to_idx.get(&wire).unwrap() as usize;
|
||||||
let (_pip, usage) = self.nets[net].wires.get_mut(&wire).unwrap();
|
let nd = &mut self.nets.write().unwrap()[net];
|
||||||
|
let (_pip, usage) = nd.wires.get_mut(&wire).unwrap();
|
||||||
*usage -= 1;
|
*usage -= 1;
|
||||||
if *usage == 0 {
|
if *usage == 0 {
|
||||||
self.flat_wires[wireidx].curr_cong -= 1;
|
self.flat_wires[wireidx].write().unwrap().curr_cong -= 1;
|
||||||
self.nets[net].wires.remove(&wire);
|
nd.wires.remove(&wire);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ripup_arc(&mut self, ctx: &npnr::Context, arc: &Arc) {
|
fn ripup_arc(&self, ctx: &npnr::Context, arc: &Arc) {
|
||||||
let net = arc.net().into_inner() as usize;
|
let net = arc.net().into_inner() as usize;
|
||||||
let source_wire = arc.source_wire;
|
let source_wire = arc.source_wire;
|
||||||
let mut wire = arc.sink_wire;
|
let mut wire = arc.sink_wire;
|
||||||
while wire != source_wire {
|
while wire != source_wire {
|
||||||
let pip = self.nets[net].wires.get(&wire).unwrap().0;
|
let pip = self.nets.read().unwrap()[net].wires.get(&wire).unwrap().0;
|
||||||
assert!(pip != PipId::null());
|
assert!(pip != PipId::null());
|
||||||
self.unbind_pip_internal(arc.net(), wire);
|
self.unbind_pip_internal(arc.net(), wire);
|
||||||
wire = ctx.pip_src_wire(pip);
|
wire = ctx.pip_src_wire(pip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_wires(&mut self) {
|
fn reset_wires(&self, dirty_wires: &Vec<u32>) {
|
||||||
for &wire in &self.dirty_wires {
|
for &wire in dirty_wires {
|
||||||
self.flat_wires[wire as usize].pip_fwd = PipId::null();
|
let mut nwd = self.flat_wires[wire as usize].write().unwrap();
|
||||||
self.flat_wires[wire as usize].visited_fwd = false;
|
nwd.pip_fwd = PipId::null();
|
||||||
self.flat_wires[wire as usize].pip_bwd = PipId::null();
|
nwd.visited_fwd = false;
|
||||||
self.flat_wires[wire as usize].visited_bwd = false;
|
nwd.pip_bwd = PipId::null();
|
||||||
|
nwd.visited_bwd = false;
|
||||||
}
|
}
|
||||||
self.dirty_wires.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user