awooter: wip

This commit is contained in:
Lofty 2022-11-27 19:27:33 +00:00
parent b333080715
commit 6213b13277
5 changed files with 211 additions and 9 deletions

View File

@ -134,6 +134,8 @@ extern "C" {
uint64_t npnr_context_get_pip_src_wire(const Context *const ctx, uint64_t pip) { return wrap(ctx->getPipSrcWire(unwrap_pip(pip))); }
uint64_t npnr_context_get_pip_dst_wire(const Context *const ctx, uint64_t pip) { return wrap(ctx->getPipDstWire(unwrap_pip(pip))); }
float npnr_context_estimate_delay(const Context *const ctx, uint64_t src, uint64_t dst) { return ctx->getDelayNS(ctx->estimateDelay(unwrap_wire(src), unwrap_wire(dst))); }
float npnr_context_get_pip_delay(const Context *const ctx, uint64_t pip) { return ctx->getDelayNS(ctx->getPipDelay(unwrap_pip(pip)).maxDelay()); }
float npnr_context_get_wire_delay(const Context *const ctx, uint64_t wire) { return ctx->getDelayNS(ctx->getWireDelay(unwrap_wire(wire)).maxDelay()); }
float npnr_context_delay_epsilon(const Context *const ctx) { return ctx->getDelayNS(ctx->getDelayEpsilon()); }
Loc npnr_context_get_pip_location(const Context *const ctx, uint64_t pip) { return ctx->getPipLocation(unwrap_pip(pip)); }
@ -270,6 +272,8 @@ extern "C" {
bool npnr_netinfo_is_global(NetInfo *const net) { return false; }
#endif
int32_t npnr_netinfo_udata(NetInfo *const net) { return net->udata; }
CellInfo* npnr_portref_cell(const PortRef *const port) { return port->cell; }
Loc npnr_cellinfo_get_location(const CellInfo *const info) { return info->getLocation(); }

View File

@ -2,6 +2,8 @@ use std::{ptr::NonNull, time::Instant};
use colored::Colorize;
use crate::partition::Coord;
#[macro_use]
mod npnr;
mod partition;
@ -206,6 +208,9 @@ fn route(ctx: &mut npnr::Context) -> bool {
println!("count in nw: {}", invalid_arcs_in_nw.to_string().bold());
}
let mut router = route::Router::new(Coord::new(0, 0), Coord::new(x_part, y_part));
router.route(ctx, &ne);
/*log_info!("=== level 2 NE:\n");
let _ = find_partition_point(&ne, x_start, x, y_start, y);
log_info!("=== level 2 SE:\n");

View File

@ -1,5 +1,5 @@
use core::slice;
use std::{collections::HashMap, ffi::CStr, marker::PhantomData, os::raw::c_void};
use std::{collections::HashMap, ffi::CStr, marker::PhantomData};
use libc::c_char;
@ -39,8 +39,16 @@ impl NetInfo {
pub fn is_global(&self) -> bool {
unsafe { npnr_netinfo_is_global(self) }
}
pub fn index(&self) -> NetIndex {
unsafe { npnr_netinfo_udata(self) }
}
}
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct NetIndex(i32);
#[repr(C)]
pub struct PortRef {
private: [u8; 0],
@ -91,7 +99,7 @@ impl PipId {
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct WireId(u64);
@ -187,6 +195,18 @@ impl Context {
unsafe { npnr_context_estimate_delay(self, src, dst) as f32 }
}
pub fn pip_delay(&self, pip: PipId) -> f32 {
unsafe { npnr_context_get_pip_delay(self, pip) }
}
pub fn wire_delay(&self, wire: WireId) -> f32 {
unsafe { npnr_context_get_wire_delay(self, wire) }
}
pub fn delay_epsilon(&self) -> f32 {
unsafe { npnr_context_delay_epsilon(self) }
}
pub fn source_wire(&self, net: *const NetInfo) -> WireId {
unsafe { npnr_context_get_netinfo_source_wire(self, net) }
}
@ -290,7 +310,10 @@ extern "C" {
fn npnr_context_unbind_pip(ctx: *mut Context, pip: PipId);
fn npnr_context_get_pip_src_wire(ctx: *const Context, pip: PipId) -> WireId;
fn npnr_context_get_pip_dst_wire(ctx: *const Context, pip: PipId) -> WireId;
fn npnr_context_estimate_delay(ctx: *const Context, src: WireId, dst: WireId) -> libc::c_float;
fn npnr_context_estimate_delay(ctx: *const Context, src: WireId, dst: WireId) -> f32;
fn npnr_context_delay_epsilon(ctx: *const Context) -> f32;
fn npnr_context_get_pip_delay(ctx: *const Context, pip: PipId) -> f32;
fn npnr_context_get_wire_delay(ctx: *const Context, wire: WireId) -> f32;
fn npnr_context_get_wires_leak(ctx: *const Context, wires: *mut *mut WireId) -> u64;
fn npnr_context_get_pips_leak(ctx: *const Context, pips: *mut *mut PipId) -> u64;
fn npnr_context_get_pip_location(ctx: *const Context, pip: PipId) -> Loc;
@ -321,6 +344,7 @@ extern "C" {
fn npnr_netinfo_driver(net: *mut NetInfo) -> *mut PortRef;
fn npnr_netinfo_users_leak(net: *mut NetInfo, users: *mut *mut *mut PortRef) -> u32;
fn npnr_netinfo_is_global(net: *const NetInfo) -> bool;
fn npnr_netinfo_udata(net: *const NetInfo) -> NetIndex;
fn npnr_portref_cell(port: *const PortRef) -> *mut CellInfo;
fn npnr_cellinfo_get_location(info: *const CellInfo) -> Loc;
@ -334,6 +358,8 @@ extern "C" {
pub struct Nets<'a> {
nets: HashMap<IdString, *mut NetInfo>,
users: HashMap<IdString, &'a [&'a mut PortRef]>,
index_to_net: Vec<IdString>,
net_to_index: HashMap<*mut NetInfo, i32>,
_data: PhantomData<&'a Context>,
}
@ -353,6 +379,8 @@ impl<'a> Nets<'a> {
};
let mut nets = HashMap::new();
let mut users = HashMap::new();
let mut index_to_net = Vec::new();
let mut net_to_index = HashMap::new();
for i in 0..size {
let name = unsafe { IdString(*names.add(i as usize)) };
let net = unsafe { *nets_ptr.add(i as usize) };
@ -365,11 +393,16 @@ impl<'a> Nets<'a> {
unsafe { slice::from_raw_parts(users_ptr as *mut &mut PortRef, len as usize) };
nets.insert(name, net);
users.insert(name, users_slice);
let index = index_to_net.len() as i32;
index_to_net.push(name);
net_to_index.insert(net, index);
}
// Note: the contents of `names` and `nets_ptr` are now lost.
Self {
nets,
users,
index_to_net,
net_to_index,
_data: PhantomData,
}
}

View File

@ -42,6 +42,14 @@ impl Coord {
self.y < other.y
}
pub fn is_south_of(&self, other: &Self) -> bool {
self.x > other.x
}
pub fn is_west_of(&self, other: &Self) -> bool {
self.y > other.y
}
pub fn segment_from(&self, other: &Self) -> Segment {
match (self.is_north_of(other), self.is_east_of(other)) {
(true, true) => Segment::Northeast,
@ -52,6 +60,15 @@ impl Coord {
}
}
impl From<npnr::Loc> for Coord {
fn from(other: npnr::Loc) -> Self {
Self {
x: other.x,
y: other.y,
}
}
}
pub fn find_partition_point(
ctx: &npnr::Context,
arcs: &[Arc],

View File

@ -1,21 +1,23 @@
use crate::npnr;
use std::collections::{BinaryHeap, HashMap};
use crate::{npnr::{self, NetIndex, PipId}, partition};
pub struct Arc {
source_wire: npnr::WireId,
source_loc: npnr::Loc,
sink_wire: npnr::WireId,
sink_loc: npnr::Loc,
net: *mut npnr::NetInfo,
net: npnr::NetIndex,
}
impl Arc {
pub fn new(source_wire: npnr::WireId, source_loc: npnr::Loc, sink_wire: npnr::WireId, sink_loc: npnr::Loc, net: *mut npnr::NetInfo) -> Self {
pub fn new(source_wire: npnr::WireId, source_loc: npnr::Loc, sink_wire: npnr::WireId, sink_loc: npnr::Loc, net: NetIndex) -> Self {
Self {
source_wire, source_loc, sink_wire, sink_loc, net
}
}
pub fn split(&self, ctx: &npnr::Context, pip: npnr::PipId) -> (Self, Self) {
pub fn split(&mut self, ctx: &npnr::Context, pip: npnr::PipId) -> (Self, Self) {
let pip_src = ctx.pip_src_wire(pip);
let pip_dst = ctx.pip_dst_wire(pip);
(Self {
@ -35,6 +37,147 @@ impl Arc {
}
}
pub struct Router {
arcs: Vec<Arc>
#[derive(Copy, Clone)]
struct QueuedWire {
cost: f32,
togo: f32,
wire: npnr::WireId,
}
impl QueuedWire {
pub fn new(cost: f32, togo: f32, wire: npnr::WireId) -> Self {
Self {
cost,
togo,
wire,
}
}
}
impl PartialEq for QueuedWire {
fn eq(&self, other: &Self) -> bool {
self.cost == other.cost && self.togo == other.togo && self.wire == other.wire
}
}
impl Eq for QueuedWire {}
impl Ord for QueuedWire {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let me = self.cost + self.togo;
let other = other.cost + other.togo;
other.total_cmp(&me)
}
}
impl PartialOrd for QueuedWire {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
pub struct Router {
box_ne: partition::Coord,
box_sw: partition::Coord,
bound_pip: HashMap<npnr::PipId, NetIndex>,
wire_driver: HashMap<npnr::WireId, npnr::PipId>,
}
impl Router {
pub fn new(box_ne: partition::Coord, box_sw: partition::Coord) -> Self {
Self {
box_ne,
box_sw,
bound_pip: HashMap::new(),
wire_driver: HashMap::new(),
}
}
pub fn route(&mut self, ctx: &npnr::Context, arcs: &[Arc]) {
for arc in arcs {
self.route_arc(ctx, arc);
}
}
fn route_arc(&mut self, ctx: &npnr::Context, arc: &Arc) {
let mut queue = BinaryHeap::new();
let mut visited = HashMap::new();
queue.push(QueuedWire::new(0.0, 0.0, arc.source_wire));
visited.insert(arc.source_wire, npnr::PipId::null());
while let Some(source) = queue.pop() {
if source.wire == arc.sink_wire {
panic!("found the sink!");
break;
}
for pip in ctx.get_downhill_pips(source.wire) {
let pip_loc = ctx.pip_location(pip);
let pip_coord = partition::Coord::from(pip_loc);
if pip_coord.is_north_of(&self.box_ne) || pip_coord.is_east_of(&self.box_ne) {
continue;
}
if pip_coord.is_south_of(&self.box_sw) || pip_coord.is_west_of(&self.box_sw) {
continue;
}
/*
if (!ctx->checkPipAvailForNet(dh, net))
continue;
WireId next = ctx->getPipDstWire(dh);
int next_idx = wire_to_idx.at(next);
if (was_visited_fwd(next_idx)) {
// Don't expand the same node twice.
continue;
}
auto &nwd = flat_wires.at(next_idx);
if (nwd.unavailable)
continue;
// Reserved for another net
if (nwd.reserved_net != -1 && nwd.reserved_net != net->udata)
continue;
// Don't allow the same wire to be bound to the same net with a different driving pip
auto fnd_wire = nd.wires.find(next);
if (fnd_wire != nd.wires.end() && fnd_wire->second.first != dh)
continue;
if (!thread_test_wire(t, nwd))
continue; // thread safety issue
*/
let sink = ctx.pip_dst_wire(pip);
if visited.contains_key(&sink) {
continue;
}
let driver = self.wire_driver.get(&sink);
if let Some(&driver) = driver {
if driver != pip {
continue;
}
if *self.bound_pip.get(&driver).unwrap() != arc.net {
continue;
}
}
visited.insert(sink, pip);
let delay = source.cost + ctx.pip_delay(pip) + ctx.wire_delay(sink) + ctx.delay_epsilon();
let qw = QueuedWire::new(delay, ctx.estimate_delay(sink, arc.sink_wire), sink);
queue.push(qw);
}
}
let mut wire = arc.sink_wire;
while wire != arc.source_wire {
let pip = *visited.get(&wire).unwrap();
self.bind_pip(pip, arc.net);
wire = ctx.pip_src_wire(pip);
}
}
fn bind_pip(&mut self, pip: PipId, net: NetIndex) {
assert!(!self.bound_pip.contains_key(&pip));
self.bound_pip.insert(pip, net);
}
}