From c821a68da70c8de58adad65a4599a9447fa360ee Mon Sep 17 00:00:00 2001 From: Lofty Date: Mon, 21 Nov 2022 02:48:00 +0000 Subject: [PATCH] awooter: add net import code --- common/route/awooter.cc | 23 +++++++++++++-- common/route/awooter/rust/src/lib.rs | 22 +++++++++++++-- common/route/awooter/rust/src/npnr.rs | 40 +++++++++++++++++++++++---- common/route/awooter/rust/src/part.rs | 6 ---- 4 files changed, 76 insertions(+), 15 deletions(-) delete mode 100644 common/route/awooter/rust/src/part.rs diff --git a/common/route/awooter.cc b/common/route/awooter.cc index 39592d0b..8426473d 100644 --- a/common/route/awooter.cc +++ b/common/route/awooter.cc @@ -127,11 +127,30 @@ extern "C" { void npnr_context_check(const Context *const ctx) { ctx->check(); } bool npnr_context_debug(const Context *const ctx) { return ctx->debug; } - IdString npnr_context_id(const Context *const ctx, const char *const str) { return ctx->id(str); } + int npnr_context_id(const Context *const ctx, const char *const str) { return ctx->id(str).hash(); } const char *npnr_context_name_of(const Context *const ctx, IdString str) { return ctx->nameOf(str); } bool npnr_context_verbose(const Context *const ctx) { return ctx->verbose; } - //NetInfo** npnr_context_nets(Context *ctx) { /* oh no */ } + // 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(Context *ctx, uint32_t n) { + for (auto& item : ctx->nets) { + if (n == 0) { + return item.first.hash(); + } + n--; + } + return 0; + } + NetInfo* npnr_context_nets_value(Context *ctx, uint32_t n) { + for (auto& item : ctx->nets) { + if (n == 0) { + return item.second.get(); + } + n--; + } + return nullptr; + } extern bool npnr_router_awooter(Context *ctx); } diff --git a/common/route/awooter/rust/src/lib.rs b/common/route/awooter/rust/src/lib.rs index 1278efd4..a479f464 100644 --- a/common/route/awooter/rust/src/lib.rs +++ b/common/route/awooter/rust/src/lib.rs @@ -2,7 +2,21 @@ use std::ptr::NonNull; #[macro_use] mod npnr; -mod part; + +enum Subpartition { + Part(Box), + Nets(Vec), +} + +struct Partition { + parts: [Option; 4], + borders: [[Vec; 4]; 4] +} + +struct Net { + source: npnr::WireId, + sinks: Vec +} #[no_mangle] pub extern "C" fn npnr_router_awooter(ctx: Option>) -> bool { @@ -25,7 +39,11 @@ fn route(ctx: &mut npnr::Context) -> bool { ctx.grid_dim_x(), ctx.grid_dim_y() ); - // let _belid = npnr::BelId::null(); + let _belid = npnr::BelId::null(); log_info!("Managed to survive BelId()\n"); + + let nets = npnr::NetIter::new(ctx).into_iter().collect::>(); + log_info!("Found {} nets\n", nets.len()); + true } \ No newline at end of file diff --git a/common/route/awooter/rust/src/npnr.rs b/common/route/awooter/rust/src/npnr.rs index 408555b5..173514e4 100644 --- a/common/route/awooter/rust/src/npnr.rs +++ b/common/route/awooter/rust/src/npnr.rs @@ -1,4 +1,4 @@ -use std::ffi::CStr; +use std::{ffi::CStr, collections::binary_heap::Iter}; use libc::c_char; @@ -24,10 +24,8 @@ pub struct NetInfo { private: [u8; 0], } -#[repr(C)] -pub struct IdString { - index: libc::c_int, -} +#[repr(transparent)] +pub struct IdString(libc::c_int); /// A type representing a bel name. #[derive(Clone, Copy)] @@ -200,9 +198,41 @@ extern "C" { fn npnr_context_name_of(ctx: *const Context, s: IdString) -> *const libc::c_char; fn npnr_context_verbose(ctx: *const Context) -> bool; + fn npnr_context_nets_key(ctx: *const Context, n: u32) -> IdString; + fn npnr_context_nets_value(ctx: *const Context, n: u32) -> *mut NetInfo; // fn npnr_context_nets(ctx: *const Context) -> *mut *mut NetInfo; } +/// In case you missed the C++ comment; this is O(n^2) because FFI is misert. +/// It's probably best to run it exactly once. +pub struct NetIter<'a> { + ctx: &'a Context, + n: u32 +} + +impl<'a> NetIter<'a> { + pub fn new(ctx: &'a Context) -> Self { + Self { + ctx, + n: 0 + } + } +} + +impl<'a> Iterator for NetIter<'a> { + type Item = (IdString, *mut NetInfo); + + fn next(&mut self) -> Option { + let str = unsafe { npnr_context_nets_key(self.ctx, self.n) }; + let val = unsafe { npnr_context_nets_value(self.ctx, self.n) }; + if val.is_null() { + return None; + } + self.n += 1; + Some((str, val)) + } +} + macro_rules! log_info { ($($t:tt)*) => { let s = std::ffi::CString::new(format!($($t)*)).unwrap(); diff --git a/common/route/awooter/rust/src/part.rs b/common/route/awooter/rust/src/part.rs deleted file mode 100644 index daeec3f3..00000000 --- a/common/route/awooter/rust/src/part.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::npnr; - -pub struct Partition { - parts: [Option>; 4], - borders: [[Vec; 4]; 4] -}