slightly better at recursive partitioning
still very fucked
This commit is contained in:
parent
b38215062e
commit
000ad6d539
@ -182,9 +182,11 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
|
|||||||
let dst_name = ctx.name_of_wire(arc.sink_wire()).to_str().unwrap();
|
let dst_name = ctx.name_of_wire(arc.sink_wire()).to_str().unwrap();
|
||||||
|
|
||||||
if src_name.contains("FCO_SLICE")
|
if src_name.contains("FCO_SLICE")
|
||||||
|
|| src_name.contains("Q6_SLICE")
|
||||||
|| src_name.contains('J')
|
|| src_name.contains('J')
|
||||||
|| src_name.contains("DDR")
|
|| src_name.contains("DDR")
|
||||||
|| dst_name.contains("DDR")
|
|| dst_name.contains("DDR")
|
||||||
|
|| dst_name.contains("X126/Y20/PADDOD_PIO")
|
||||||
{
|
{
|
||||||
special_arcs.push(arc);
|
special_arcs.push(arc);
|
||||||
} else {
|
} else {
|
||||||
@ -206,30 +208,21 @@ fn route(ctx: &mut npnr::Context, pressure: f32, history: f32) -> bool {
|
|||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
let mut new_partitions = Vec::with_capacity(partitions.len() * 4);
|
let mut new_partitions = Vec::with_capacity(partitions.len() * 4);
|
||||||
for (min, max, partition, name) in &partitions {
|
for (min, max, partition, name) in &partitions {
|
||||||
|
log_info!("partition {}:\n", name);
|
||||||
let (x_part, y_part, ne, se, sw, nw) = partition::find_partition_point_and_sanity_check(
|
let (x_part, y_part, ne, se, sw, nw) = partition::find_partition_point_and_sanity_check(
|
||||||
ctx, &nets, partition, pips, min.x, max.x, min.y, max.y,
|
ctx, &nets, partition, pips, min.x, max.x, min.y, max.y,
|
||||||
);
|
);
|
||||||
|
new_partitions.push((*min, Coord::new(x_part, y_part), ne, format!("{}_NE", name)));
|
||||||
new_partitions.push((
|
new_partitions.push((
|
||||||
*min,
|
Coord::new(x_part, min.y),
|
||||||
Coord::new(x_part + 1, y_part + 1),
|
Coord::new(max.x, y_part),
|
||||||
ne,
|
|
||||||
format!("{}_NE", name),
|
|
||||||
));
|
|
||||||
new_partitions.push((
|
|
||||||
Coord::new(x_part - 1, min.y),
|
|
||||||
Coord::new(max.x, y_part + 1),
|
|
||||||
se,
|
se,
|
||||||
format!("{}_SE", name),
|
format!("{}_SE", name),
|
||||||
));
|
));
|
||||||
|
new_partitions.push((Coord::new(x_part, y_part), *max, sw, format!("{}_SW", name)));
|
||||||
new_partitions.push((
|
new_partitions.push((
|
||||||
Coord::new(x_part - 1, y_part - 1),
|
Coord::new(min.x, y_part),
|
||||||
*max,
|
Coord::new(x_part, max.y),
|
||||||
sw,
|
|
||||||
format!("{}_SW", name),
|
|
||||||
));
|
|
||||||
new_partitions.push((
|
|
||||||
Coord::new(min.x, y_part - 1),
|
|
||||||
Coord::new(x_part + 1, max.y),
|
|
||||||
nw,
|
nw,
|
||||||
format!("{}_NW", name),
|
format!("{}_NW", name),
|
||||||
));
|
));
|
||||||
|
@ -155,12 +155,12 @@ impl Coord {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
match direction {
|
match direction {
|
||||||
Direction::North => Coord {
|
Direction::North => Coord {
|
||||||
x: self.x.clamp(min_bounds.x + 1, partition_point.x - 1),
|
x: self.x.clamp(min_bounds.x, partition_point.x - 1),
|
||||||
y: self.y,
|
y: self.y,
|
||||||
},
|
},
|
||||||
Direction::East => Coord {
|
Direction::East => Coord {
|
||||||
x: self.x,
|
x: self.x,
|
||||||
y: self.y.clamp(min_bounds.y + 1, partition_point.y - 1),
|
y: self.y.clamp(min_bounds.y, partition_point.y - 1),
|
||||||
},
|
},
|
||||||
Direction::South => Coord {
|
Direction::South => Coord {
|
||||||
x: self.x.clamp(partition_point.x + 1, max_bounds.x - 1),
|
x: self.x.clamp(partition_point.x + 1, max_bounds.x - 1),
|
||||||
@ -204,8 +204,8 @@ pub fn find_partition_point(
|
|||||||
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
|
) -> (i32, i32, Vec<Arc>, Vec<Arc>, Vec<Arc>, Vec<Arc>) {
|
||||||
let mut x = ((x_finish - x_start) / 2) + x_start;
|
let mut x = ((x_finish - x_start) / 2) + x_start;
|
||||||
let mut y = ((y_finish - y_start) / 2) + y_start;
|
let mut y = ((y_finish - y_start) / 2) + y_start;
|
||||||
let mut x_diff = (x_finish - x_start) / 4;
|
let mut x_diff = 0; //(x_finish - x_start) / 4;
|
||||||
let mut y_diff = (y_finish - y_start) / 4;
|
let mut y_diff = 0; //(y_finish - y_start) / 4;
|
||||||
|
|
||||||
while x_diff != 0 {
|
while x_diff != 0 {
|
||||||
let (ne, se, sw, nw) = approximate_partition_results(arcs, (x, y));
|
let (ne, se, sw, nw) = approximate_partition_results(arcs, (x, y));
|
||||||
@ -863,6 +863,7 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
let mut out_of_bound_arcs_in_sw = 0;
|
let mut out_of_bound_arcs_in_sw = 0;
|
||||||
let mut out_of_bound_arcs_in_nw = 0;
|
let mut out_of_bound_arcs_in_nw = 0;
|
||||||
|
|
||||||
|
println!("\nne:");
|
||||||
for arc in &ne {
|
for arc in &ne {
|
||||||
if arc.source_loc().x > x_part
|
if arc.source_loc().x > x_part
|
||||||
|| arc.source_loc().y > y_part
|
|| arc.source_loc().y > y_part
|
||||||
@ -876,9 +877,11 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
|| arc.sink_loc().x <= x_start
|
|| arc.sink_loc().x <= x_start
|
||||||
|| arc.sink_loc().y <= y_start
|
|| arc.sink_loc().y <= y_start
|
||||||
{
|
{
|
||||||
|
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
||||||
out_of_bound_arcs_in_ne += 1;
|
out_of_bound_arcs_in_ne += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("\nse:");
|
||||||
for arc in &se {
|
for arc in &se {
|
||||||
if arc.source_loc().x < x_part
|
if arc.source_loc().x < x_part
|
||||||
|| arc.source_loc().y > y_part
|
|| arc.source_loc().y > y_part
|
||||||
@ -892,9 +895,11 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
|| arc.sink_loc().x >= x_finish
|
|| arc.sink_loc().x >= x_finish
|
||||||
|| arc.sink_loc().y <= y_start
|
|| arc.sink_loc().y <= y_start
|
||||||
{
|
{
|
||||||
|
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
||||||
out_of_bound_arcs_in_se += 1;
|
out_of_bound_arcs_in_se += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("\nsw:");
|
||||||
for arc in &sw {
|
for arc in &sw {
|
||||||
if arc.source_loc().x < x_part
|
if arc.source_loc().x < x_part
|
||||||
|| arc.source_loc().y < y_part
|
|| arc.source_loc().y < y_part
|
||||||
@ -908,9 +913,11 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
|| arc.sink_loc().x >= x_finish
|
|| arc.sink_loc().x >= x_finish
|
||||||
|| arc.sink_loc().y >= y_finish
|
|| arc.sink_loc().y >= y_finish
|
||||||
{
|
{
|
||||||
|
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
||||||
out_of_bound_arcs_in_sw += 1;
|
out_of_bound_arcs_in_sw += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("\nnw:");
|
||||||
for arc in &nw {
|
for arc in &nw {
|
||||||
if arc.source_loc().x > x_part
|
if arc.source_loc().x > x_part
|
||||||
|| arc.source_loc().y < y_part
|
|| arc.source_loc().y < y_part
|
||||||
@ -924,6 +931,7 @@ pub fn find_partition_point_and_sanity_check(
|
|||||||
|| arc.sink_loc().x <= x_start
|
|| arc.sink_loc().x <= x_start
|
||||||
|| arc.sink_loc().y >= y_finish
|
|| arc.sink_loc().y >= y_finish
|
||||||
{
|
{
|
||||||
|
println!("oob: {:?} -> {:?}", arc.source_loc(), arc.sink_loc());
|
||||||
out_of_bound_arcs_in_nw += 1;
|
out_of_bound_arcs_in_nw += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1019,8 +1027,8 @@ impl PipSelector {
|
|||||||
for &pip in pips {
|
for &pip in pips {
|
||||||
let loc = ctx.pip_location(pip);
|
let loc = ctx.pip_location(pip);
|
||||||
if (loc.x == partition_point.x || loc.y == partition_point.y)
|
if (loc.x == partition_point.x || loc.y == partition_point.y)
|
||||||
&& loc.x > bounds.0 .0
|
&& loc.x >= bounds.0 .0
|
||||||
&& loc.x < bounds.0 .1
|
&& loc.x <= bounds.0 .1
|
||||||
&& loc.y > bounds.1 .0
|
&& loc.y > bounds.1 .0
|
||||||
&& loc.y < bounds.1 .1
|
&& loc.y < bounds.1 .1
|
||||||
{
|
{
|
||||||
@ -1050,6 +1058,10 @@ impl PipSelector {
|
|||||||
|
|
||||||
candidates += 1;
|
candidates += 1;
|
||||||
|
|
||||||
|
// a stack, to do recursion, because we need that i guess
|
||||||
|
let mut pips = vec![];
|
||||||
|
const MAX_PIP_SEARCH_DEPTH: usize = 3;
|
||||||
|
|
||||||
if loc.y == partition_point.y {
|
if loc.y == partition_point.y {
|
||||||
// pip is on east-west border
|
// pip is on east-west border
|
||||||
|
|
||||||
@ -1059,21 +1071,42 @@ impl PipSelector {
|
|||||||
(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)) {
|
||||||
|
pips.push((src_pip, 0));
|
||||||
|
}
|
||||||
|
while let Some((src_pip, depth)) = pips.pop() {
|
||||||
let src_pip_coord: Coord = ctx.pip_location(src_pip).into();
|
let src_pip_coord: Coord = ctx.pip_location(src_pip).into();
|
||||||
if (src_pip_coord.x < partition_point.x) == (loc.x < partition_point.x) {
|
if (src_pip_coord.x < partition_point.x) && (loc.x < partition_point.x)
|
||||||
src_has_middle |= src_pip_coord.y == loc.y;
|
|| (src_pip_coord.x > partition_point.x) && (loc.x > partition_point.x)
|
||||||
|
{
|
||||||
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 {
|
||||||
|
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
|
||||||
|
pips.push((src_pip, depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(pip)) {
|
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(pip)) {
|
||||||
|
pips.push((dst_pip, 0));
|
||||||
|
}
|
||||||
|
while let Some((dst_pip, depth)) = pips.pop() {
|
||||||
let dst_pip_coord: Coord = ctx.pip_location(dst_pip).into();
|
let dst_pip_coord: Coord = ctx.pip_location(dst_pip).into();
|
||||||
if (dst_pip_coord.x < partition_point.x) == (loc.x < partition_point.x) {
|
|
||||||
dst_has_middle |= dst_pip_coord.y == loc.y;
|
if (dst_pip_coord.x < partition_point.x) && (loc.x < partition_point.x)
|
||||||
|
|| (dst_pip_coord.x > partition_point.x) && (loc.x > partition_point.x)
|
||||||
|
{
|
||||||
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 {
|
||||||
|
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
|
||||||
|
pips.push((dst_pip, depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_has_east && (dst_has_west || dst_has_middle))
|
if (src_has_east && (dst_has_west || dst_has_middle))
|
||||||
|| (src_has_middle && dst_has_west)
|
|| (src_has_middle && dst_has_west)
|
||||||
{
|
{
|
||||||
@ -1103,21 +1136,44 @@ impl PipSelector {
|
|||||||
(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)) {
|
||||||
|
pips.push((src_pip, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some((src_pip, depth)) = pips.pop() {
|
||||||
let src_pip_coord: Coord = ctx.pip_location(src_pip).into();
|
let src_pip_coord: Coord = ctx.pip_location(src_pip).into();
|
||||||
if (src_pip_coord.y < partition_point.y) == (loc.y < partition_point.y) {
|
if (src_pip_coord.y < partition_point.y) && (loc.y < partition_point.y)
|
||||||
src_has_middle |= src_pip_coord.x == loc.x;
|
|| (src_pip_coord.y > partition_point.y) && (loc.y > partition_point.y)
|
||||||
|
{
|
||||||
src_has_north |= src_pip_coord.is_north_of(&partition_point.into());
|
src_has_north |= src_pip_coord.is_north_of(&partition_point.into());
|
||||||
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 {
|
||||||
|
// yaaaaaaay, we need to everything again for this pip :)
|
||||||
|
for src_pip in ctx.get_uphill_pips(ctx.pip_src_wire(src_pip)) {
|
||||||
|
pips.push((src_pip, depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(pip)) {
|
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(pip)) {
|
||||||
|
pips.push((dst_pip, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some((dst_pip, depth)) = pips.pop() {
|
||||||
let dst_pip_coord: Coord = ctx.pip_location(dst_pip).into();
|
let dst_pip_coord: Coord = ctx.pip_location(dst_pip).into();
|
||||||
if (dst_pip_coord.y < partition_point.y) == (loc.y < partition_point.y) {
|
if (dst_pip_coord.y < partition_point.y) && (loc.y < partition_point.y)
|
||||||
dst_has_middle |= dst_pip_coord.x == loc.x;
|
|| (dst_pip_coord.y > partition_point.y) && (loc.y > partition_point.y)
|
||||||
|
{
|
||||||
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 {
|
||||||
|
for dst_pip in ctx.get_downhill_pips(ctx.pip_dst_wire(dst_pip)) {
|
||||||
|
pips.push((dst_pip, depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_has_north && (dst_has_south || dst_has_middle))
|
if (src_has_north && (dst_has_south || dst_has_middle))
|
||||||
|| (src_has_middle && dst_has_south)
|
|| (src_has_middle && dst_has_south)
|
||||||
{
|
{
|
||||||
@ -1264,16 +1320,13 @@ impl PipSelector {
|
|||||||
|
|
||||||
let pips = &self.pips[pip_index];
|
let pips = &self.pips[pip_index];
|
||||||
|
|
||||||
let selected_pip = self
|
let (selected_pip, mut candidate, mut source, mut sink) = self
|
||||||
.pip_index_to_position_iter(pip_index, (desired_pip_location.x, desired_pip_location.y))
|
.pip_index_to_position_iter(pip_index, (desired_pip_location.x, desired_pip_location.y))
|
||||||
.flat_map(|pos| {
|
.flat_map(|pos| pips.get(&pos))
|
||||||
pips.get(&pos)
|
.flat_map(|vec| vec.iter())
|
||||||
.unwrap_or_else(|| panic!("tried at {:?}", pos))
|
.filter_map(|pip| {
|
||||||
.iter()
|
|
||||||
})
|
|
||||||
.find(|&pip| {
|
|
||||||
if !ctx.pip_avail_for_net(*pip, raw_net) {
|
if !ctx.pip_avail_for_net(*pip, raw_net) {
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let source = ctx.pip_src_wire(*pip);
|
let source = ctx.pip_src_wire(*pip);
|
||||||
@ -1285,7 +1338,7 @@ impl PipSelector {
|
|||||||
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
|
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
|
||||||
(source, sink)
|
(source, sink)
|
||||||
}
|
}
|
||||||
Ordering::Equal => return false,
|
Ordering::Equal => return None,
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
|
let sink = self.used_wires.get(&sink).unwrap().lock().unwrap();
|
||||||
let source = self.used_wires.get(&source).unwrap().lock().unwrap();
|
let source = self.used_wires.get(&source).unwrap().lock().unwrap();
|
||||||
@ -1295,21 +1348,18 @@ impl PipSelector {
|
|||||||
|
|
||||||
let mut candidate = self.used_pips.get(pip).unwrap().lock().unwrap();
|
let mut 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 false;
|
return None;
|
||||||
}
|
}
|
||||||
if source.map(|other| other != net).unwrap_or(false) {
|
if source.map(|other| other != net).unwrap_or(false) {
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
if sink.map(|other| other != net).unwrap_or(false) {
|
if sink.map(|other| other != net).unwrap_or(false) {
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
*candidate = Some(net);
|
Some((pip, candidate, source, sink))
|
||||||
*source = Some(net);
|
})
|
||||||
*sink = Some(net);
|
.next()?;
|
||||||
|
|
||||||
true
|
|
||||||
})?;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut cache = self.pip_selection_cache[pip_index]
|
let mut cache = self.pip_selection_cache[pip_index]
|
||||||
@ -1317,9 +1367,19 @@ impl PipSelector {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.write()
|
.write()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// while we were looking, someone else might have found a pip
|
||||||
|
if let Some(other_pip) = *cache {
|
||||||
|
return Some(other_pip);
|
||||||
|
}
|
||||||
|
|
||||||
*cache = Some(*selected_pip);
|
*cache = Some(*selected_pip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*candidate = Some(net);
|
||||||
|
*source = Some(net);
|
||||||
|
*sink = Some(net);
|
||||||
|
|
||||||
Some(*selected_pip)
|
Some(*selected_pip)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1354,7 +1414,7 @@ impl PipSelector {
|
|||||||
0 | 2 => (
|
0 | 2 => (
|
||||||
(1, 0),
|
(1, 0),
|
||||||
self.partition_loc.x - start_position.0 - 1,
|
self.partition_loc.x - start_position.0 - 1,
|
||||||
start_position.0 - self.boundaries.0 .0 - 1,
|
start_position.0 - self.boundaries.0 .0,
|
||||||
),
|
),
|
||||||
1 | 3 => (
|
1 | 3 => (
|
||||||
(1, 0),
|
(1, 0),
|
||||||
@ -1364,7 +1424,7 @@ impl PipSelector {
|
|||||||
4 | 6 => (
|
4 | 6 => (
|
||||||
(0, 1),
|
(0, 1),
|
||||||
self.partition_loc.y - start_position.1 - 1,
|
self.partition_loc.y - start_position.1 - 1,
|
||||||
start_position.1 - self.boundaries.1 .0 - 1,
|
start_position.1 - self.boundaries.1 .0,
|
||||||
),
|
),
|
||||||
5 | 7 => (
|
5 | 7 => (
|
||||||
(0, 1),
|
(0, 1),
|
||||||
|
Loading…
Reference in New Issue
Block a user