awooter: wire storage and some cleanup
This commit is contained in:
parent
153c8a9c6c
commit
95e802ee3d
@ -126,6 +126,19 @@ extern "C" {
|
||||
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_delay_epsilon(const Context *const ctx) { return ctx->getDelayNS(ctx->getDelayEpsilon()); }
|
||||
|
||||
uint64_t npnr_context_get_wires_leak(const Context *const ctx, WireId **wires) {
|
||||
auto wire_vec = std::vector<WireId>{};
|
||||
for (auto wire : ctx->getWires()) {
|
||||
wire_vec.push_back(wire);
|
||||
}
|
||||
wire_vec.shrink_to_fit();
|
||||
auto size = wire_vec.size();
|
||||
*wires = wire_vec.data();
|
||||
// Yes, by placement-newing over `wire_vec` we leak memory.
|
||||
new (&wire_vec) std::vector<WireId>;
|
||||
return size;
|
||||
}
|
||||
|
||||
void npnr_context_check(const Context *const ctx) { ctx->check(); }
|
||||
bool npnr_context_debug(const Context *const ctx) { return ctx->debug; }
|
||||
int npnr_context_id(const Context *const ctx, const char *const str) { return ctx->id(str).hash(); }
|
||||
@ -158,33 +171,6 @@ extern "C" {
|
||||
return size;
|
||||
}
|
||||
|
||||
// Yes, this is quadratic. It gets imported once and then never worried about again.
|
||||
// There are bigger fish to fry.
|
||||
int npnr_context_nets_key(const Context *const ctx, uint32_t n) {
|
||||
if (ctx == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
for (auto& item : ctx->nets) {
|
||||
if (n == 0) {
|
||||
return item.first.hash();
|
||||
}
|
||||
n--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
NetInfo* npnr_context_nets_value(const Context *const ctx, uint32_t n) {
|
||||
if (ctx == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (auto& item : ctx->nets) {
|
||||
if (n == 0) {
|
||||
return item.second.get();
|
||||
}
|
||||
n--;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PortRef* npnr_netinfo_driver(NetInfo *const net) {
|
||||
if (net == nullptr) {
|
||||
return nullptr;
|
||||
@ -221,8 +207,6 @@ extern "C" {
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
bool router_awooter(Context *ctx) {
|
||||
static_assert(std::is_standard_layout<IdString>::value == true, "IdString is not FFI-safe");
|
||||
|
||||
log_info("Running Awooter...\n");
|
||||
auto result = npnr_router_awooter(ctx);
|
||||
log_info("Router returned: %d\n", result);
|
||||
|
@ -212,6 +212,9 @@ fn route(ctx: &mut npnr::Context) -> bool {
|
||||
ctx.grid_dim_y()
|
||||
);
|
||||
|
||||
let wires = npnr::Wires::new(ctx);
|
||||
log_info!("Found {} wires\n", wires.len());
|
||||
|
||||
let nets = npnr::Nets::new(ctx);
|
||||
log_info!("Found {} nets\n", nets.len());
|
||||
|
||||
@ -301,6 +304,8 @@ fn route(ctx: &mut npnr::Context) -> bool {
|
||||
log_info!("=== level 1:\n");
|
||||
let (x, y, ne, se, sw, nw) = find_partition_point(&arcs, x_start, x_finish, y_start, y_finish);
|
||||
|
||||
todo!("figure out how to tell if a wire crosses the calculated partition boundaries");
|
||||
|
||||
/*log_info!("=== level 2 NE:\n");
|
||||
let _ = find_partition_point(&ne, x_start, x, y_start, y);
|
||||
log_info!("=== level 2 SE:\n");
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::{ffi::CStr, collections::{HashMap}, ptr::{NonNull}, marker::PhantomData};
|
||||
use core::slice;
|
||||
use std::{ffi::CStr, collections::{HashMap}, marker::PhantomData};
|
||||
|
||||
use libc::c_char;
|
||||
|
||||
@ -69,9 +70,7 @@ pub struct IdString(libc::c_int);
|
||||
/// A type representing a bel name.
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct BelId {
|
||||
_private: u64,
|
||||
}
|
||||
pub struct BelId(u64);
|
||||
|
||||
impl BelId {
|
||||
/// Return a sentinel value that represents an invalid bel.
|
||||
@ -88,9 +87,7 @@ impl BelId {
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct PipId {
|
||||
_private: u64,
|
||||
}
|
||||
pub struct PipId(u64);
|
||||
|
||||
impl PipId {
|
||||
pub fn null() -> Self {
|
||||
@ -256,6 +253,7 @@ extern "C" {
|
||||
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_get_wires_leak(ctx: *const Context, wires: *mut *mut WireId) -> u64;
|
||||
|
||||
fn npnr_context_check(ctx: *const Context);
|
||||
fn npnr_context_debug(ctx: *const Context) -> bool;
|
||||
@ -284,9 +282,7 @@ extern "C" {
|
||||
|
||||
/// Store for the users of a net.
|
||||
pub struct NetUsers<'a> {
|
||||
users: NonNull<*mut PortRef>,
|
||||
size: u32,
|
||||
_data: PhantomData<&'a NetInfo>,
|
||||
users: &'a [*mut PortRef],
|
||||
}
|
||||
|
||||
impl<'a> NetUsers<'a> {
|
||||
@ -294,9 +290,9 @@ impl<'a> NetUsers<'a> {
|
||||
let mut users = std::ptr::null_mut();
|
||||
// SAFETY: net is not null because it's a &mut, and users is only written to.
|
||||
// Leaking memory is the most convenient FFI I could think of.
|
||||
let size = unsafe { npnr_netinfo_users_leak(net, &mut users as *mut *mut *mut PortRef) };
|
||||
let users = unsafe { NonNull::new_unchecked(users) };
|
||||
Self { users, size, _data: PhantomData }
|
||||
let len = unsafe { npnr_netinfo_users_leak(net, &mut users as *mut *mut *mut PortRef) };
|
||||
let users = unsafe { slice::from_raw_parts(users, len as usize) };
|
||||
Self { users }
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> NetUsersIter<'_> {
|
||||
@ -306,17 +302,14 @@ impl<'a> NetUsers<'a> {
|
||||
|
||||
pub struct NetUsersIter<'a> {
|
||||
users: &'a NetUsers<'a>,
|
||||
n: u32,
|
||||
n: usize,
|
||||
}
|
||||
|
||||
impl Iterator for NetUsersIter<'_> {
|
||||
type Item = *mut PortRef;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.n >= self.users.size {
|
||||
return None;
|
||||
}
|
||||
let user = unsafe { *self.users.users.as_ptr().add(self.n as usize) };
|
||||
let user = *self.users.users.get(self.n)?;
|
||||
self.n += 1;
|
||||
Some(user)
|
||||
}
|
||||
@ -389,6 +382,27 @@ impl<'a> Iterator for NetSinkWireIter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Wires<'a> {
|
||||
wires: &'a [WireId],
|
||||
}
|
||||
|
||||
impl<'a> Wires<'a> {
|
||||
pub fn new(ctx: &'a Context) -> Wires<'a> {
|
||||
let mut wires = std::ptr::null_mut();
|
||||
let len = unsafe { npnr_context_get_wires_leak(ctx, &mut wires as *mut *mut WireId) };
|
||||
let wires = unsafe { std::slice::from_raw_parts(wires, len as usize) };
|
||||
Self { wires }
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.wires.len()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item=&WireId> {
|
||||
self.wires.iter()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! log_info {
|
||||
($($t:tt)*) => {
|
||||
let s = std::ffi::CString::new(format!($($t)*)).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user