awooter: wip
This commit is contained in:
parent
b333080715
commit
6213b13277
@ -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(); }
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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],
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user