diff --git a/common/route/awooter.cc b/common/route/awooter.cc index f38144b0..d4882114 100644 --- a/common/route/awooter.cc +++ b/common/route/awooter.cc @@ -52,6 +52,13 @@ namespace { } } +using DownhillIter = decltype(Context(ArchArgs()).getPipsDownhill(WireId()).begin()); + +struct DownhillIterWrapper { + DownhillIter current; + DownhillIter end; +}; + extern "C" { USING_NEXTPNR_NAMESPACE; @@ -255,6 +262,18 @@ extern "C" { CellInfo* npnr_portref_cell(const PortRef *const port) { return port->cell; } Loc npnr_cellinfo_get_location(const CellInfo *const info) { return info->getLocation(); } + void npnr_inc_downhill_iter(DownhillIterWrapper *iter) { + ++iter->current; + } + + uint64_t npnr_deref_downhill_iter(DownhillIterWrapper *iter) { + wrap(*iter->current); + } + + bool npnr_is_downhill_iter_done(DownhillIterWrapper *iter) { + return !(iter->current != iter->end); + } + extern bool npnr_router_awooter(Context *ctx); } diff --git a/common/route/awooter/rust/src/npnr.rs b/common/route/awooter/rust/src/npnr.rs index a255d652..30fd5d0f 100644 --- a/common/route/awooter/rust/src/npnr.rs +++ b/common/route/awooter/rust/src/npnr.rs @@ -1,5 +1,5 @@ use core::slice; -use std::{collections::HashMap, ffi::CStr, marker::PhantomData}; +use std::{collections::HashMap, ffi::CStr, marker::PhantomData, os::raw::c_void}; use libc::c_char; @@ -314,6 +314,10 @@ extern "C" { fn npnr_portref_cell(port: *const PortRef) -> *mut CellInfo; fn npnr_cellinfo_get_location(info: *const CellInfo) -> Loc; + + fn npnr_inc_downhill_iter(iter: *mut RawDownhillIter); + fn npnr_deref_downhill_iter(iter: *mut RawDownhillIter) -> PipId; + fn npnr_is_downhill_iter_done(iter: *mut RawDownhillIter) -> bool; } /// Store for the nets of a context. @@ -396,6 +400,29 @@ impl<'a> Iterator for NetSinkWireIter<'a> { } } +#[repr(C)] +struct RawDownhillIter { + content: [u8; 0], +} + +struct DownhillPipsIter { + iter: *mut RawDownhillIter, +} + +impl Iterator for DownhillPipsIter { + type Item = PipId; + + fn next(&mut self) -> Option { + if unsafe { npnr_is_downhill_iter_done(self.iter) } { + None + } else { + let pip = unsafe { npnr_deref_downhill_iter(self.iter) }; + unsafe { npnr_inc_downhill_iter(self.iter) }; + Some(pip) + } + } +} + macro_rules! log_info { ($($t:tt)*) => { let s = std::ffi::CString::new(format!($($t)*)).unwrap();