diff --git a/common/route/awooter.cc b/common/route/awooter.cc index d4882114..bf7f97a3 100644 --- a/common/route/awooter.cc +++ b/common/route/awooter.cc @@ -57,6 +57,8 @@ using DownhillIter = decltype(Context(ArchArgs()).getPipsDownhill(WireId()).begi struct DownhillIterWrapper { DownhillIter current; DownhillIter end; + + DownhillIterWrapper(DownhillIter begin, DownhillIter end) : current(begin), end(end) {} }; extern "C" { @@ -232,6 +234,15 @@ extern "C" { return size; } + DownhillIterWrapper *npnr_context_get_pips_downhill(Context *ctx, uint64_t wire_id) { + auto wire = unwrap_wire(wire_id); + auto range = ctx->getPipsDownhill(wire); + return new DownhillIterWrapper(range.begin(), range.end()); + } + void npnr_delete_downhill_iter(DownhillIterWrapper *iter) { + delete iter; + } + PortRef* npnr_netinfo_driver(NetInfo *const net) { if (net == nullptr) { return nullptr; @@ -267,7 +278,7 @@ extern "C" { } uint64_t npnr_deref_downhill_iter(DownhillIterWrapper *iter) { - wrap(*iter->current); + return wrap(*iter->current); } bool npnr_is_downhill_iter_done(DownhillIterWrapper *iter) { diff --git a/common/route/awooter/rust/src/npnr.rs b/common/route/awooter/rust/src/npnr.rs index 30fd5d0f..ab7fecfc 100644 --- a/common/route/awooter/rust/src/npnr.rs +++ b/common/route/awooter/rust/src/npnr.rs @@ -217,6 +217,14 @@ impl Context { unsafe { std::slice::from_raw_parts(pips, len as usize) } } + pub fn get_downhill_pips(&self, wire: WireId) -> DownhillPipsIter { + let iter = unsafe { npnr_context_get_pips_downhill(self, wire) }; + DownhillPipsIter { + iter, + phantom_data: Default::default(), + } + } + pub fn pip_location(&self, pip: PipId) -> Loc { unsafe { npnr_context_get_pip_location(self, pip) } } @@ -307,6 +315,8 @@ extern "C" { names: *mut *mut libc::c_int, nets: *mut *mut *mut NetInfo, ) -> u32; + fn npnr_context_get_pips_downhill(ctx: *const Context, wire: WireId) -> *mut RawDownhillIter; + fn npnr_delete_downhill_iter(iter: *mut RawDownhillIter); fn npnr_netinfo_driver(net: *mut NetInfo) -> *mut PortRef; fn npnr_netinfo_users_leak(net: *mut NetInfo, users: *mut *mut *mut PortRef) -> u32; @@ -405,11 +415,12 @@ struct RawDownhillIter { content: [u8; 0], } -struct DownhillPipsIter { +pub struct DownhillPipsIter<'a> { iter: *mut RawDownhillIter, + phantom_data: std::marker::PhantomData<&'a PipId>, } -impl Iterator for DownhillPipsIter { +impl<'a> Iterator for DownhillPipsIter<'a> { type Item = PipId; fn next(&mut self) -> Option { @@ -423,6 +434,12 @@ impl Iterator for DownhillPipsIter { } } +impl<'a> Drop for DownhillPipsIter<'a> { + fn drop(&mut self) { + unsafe { npnr_delete_downhill_iter(self.iter) }; + } +} + macro_rules! log_info { ($($t:tt)*) => { let s = std::ffi::CString::new(format!($($t)*)).unwrap();