mirror of https://github.com/YosysHQ/nextpnr.git
rust: extend example_printnets to demo iterators
This commit is contained in:
parent
0ee8181733
commit
8f8181c717
|
|
@ -3,7 +3,23 @@ use nextpnr::Context;
|
|||
#[no_mangle]
|
||||
pub extern "C" fn rust_example_printnets(ctx: &mut Context) {
|
||||
println!("Nets in design:");
|
||||
for (name, _net) in &ctx.nets() {
|
||||
println!(" {}", ctx.name_of(name).to_str().unwrap());
|
||||
for (name, net) in &ctx.nets() {
|
||||
let net = unsafe { &*net };
|
||||
let driver = net.driver();
|
||||
println!(" {}:", ctx.name_of(name).to_str().unwrap());
|
||||
if let Some(driver) = driver {
|
||||
let cell = driver.cell().map_or("(no cell)", |cell| ctx.name_of(cell.name()).to_str().unwrap());
|
||||
let port = ctx.name_of(driver.port()).to_str().unwrap();
|
||||
println!(" driver: {cell}.{port}");
|
||||
} else {
|
||||
println!(" driver: (no driver)");
|
||||
}
|
||||
println!(" sinks:");
|
||||
for (user, port) in net.users() {
|
||||
let user = unsafe { &*user };
|
||||
let user = ctx.name_of(user.name()).to_str().unwrap();
|
||||
let port = ctx.name_of(port).to_str().unwrap();
|
||||
println!(" {user}.{port}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ impl CellInfo {
|
|||
pub fn location(&self) -> Loc {
|
||||
unsafe { npnr_cellinfo_get_location(self) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn name(&self) -> IdString {
|
||||
IdString(unsafe { npnr_cellinfo_name(self) })
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -32,7 +37,7 @@ pub struct NetInfo {
|
|||
}
|
||||
|
||||
impl NetInfo {
|
||||
pub fn driver(&mut self) -> Option<&mut PortRef> {
|
||||
pub fn driver(&self) -> Option<&PortRef> {
|
||||
unsafe { npnr_netinfo_driver(self) }
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +50,14 @@ impl NetInfo {
|
|||
pub fn index(&self) -> NetIndex {
|
||||
unsafe { npnr_netinfo_udata(self) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn users(&self) -> NetUserIter<'_> {
|
||||
NetUserIter {
|
||||
iter: unsafe { npnr_context_net_user_iter(self) },
|
||||
phantom_data: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
|
|
@ -69,6 +82,11 @@ impl PortRef {
|
|||
// SAFETY: handing out &s is safe when we have &self.
|
||||
unsafe { npnr_portref_cell(self) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn port(&self) -> IdString {
|
||||
IdString(unsafe { npnr_portref_port(self) })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
@ -459,14 +477,15 @@ unsafe extern "C" {
|
|||
n: u32,
|
||||
) -> WireId;
|
||||
|
||||
fn npnr_netinfo_driver(net: &mut NetInfo) -> Option<&mut PortRef>;
|
||||
fn npnr_netinfo_users_leak(net: &NetInfo, users: *mut *mut *const PortRef) -> u32;
|
||||
fn npnr_netinfo_driver(net: &NetInfo) -> Option<&PortRef>;
|
||||
fn npnr_netinfo_is_global(net: &NetInfo) -> bool;
|
||||
fn npnr_netinfo_udata(net: &NetInfo) -> NetIndex;
|
||||
fn npnr_netinfo_udata_set(net: &mut NetInfo, value: NetIndex);
|
||||
|
||||
fn npnr_portref_cell(port: &PortRef) -> Option<&CellInfo>;
|
||||
fn npnr_cellinfo_get_location(info: &CellInfo) -> Loc;
|
||||
fn npnr_portref_port(port: &PortRef) -> libc::c_int;
|
||||
fn npnr_cellinfo_get_location(cell: &CellInfo) -> Loc;
|
||||
fn npnr_cellinfo_name(cell: &CellInfo) -> libc::c_int;
|
||||
|
||||
fn npnr_context_get_pips_downhill(ctx: &Context, wire: WireId) -> &mut RawDownhillIter;
|
||||
fn npnr_delete_downhill_iter(iter: &mut RawDownhillIter);
|
||||
|
|
@ -511,6 +530,13 @@ unsafe extern "C" {
|
|||
fn npnr_deref_cell_iter_first(iter: &mut RawCellIter) -> libc::c_int;
|
||||
fn npnr_deref_cell_iter_second(iter: &mut RawCellIter) -> &mut CellInfo;
|
||||
fn npnr_is_cell_iter_done(iter: &mut RawCellIter) -> bool;
|
||||
|
||||
fn npnr_context_net_user_iter(net: &NetInfo) -> &mut RawNetUserIter;
|
||||
fn npnr_delete_net_user_iter(iter: &mut RawNetUserIter);
|
||||
fn npnr_inc_net_user_iter(iter: &mut RawNetUserIter);
|
||||
fn npnr_deref_net_user_iter_cell(iter: &mut RawNetUserIter) -> &mut CellInfo;
|
||||
fn npnr_deref_net_user_iter_port(iter: &mut RawNetUserIter) -> libc::c_int;
|
||||
fn npnr_is_net_user_iter_done(iter: &mut RawNetUserIter) -> bool;
|
||||
}
|
||||
|
||||
/// Store for the nets of a context.
|
||||
|
|
@ -781,6 +807,37 @@ impl Drop for CellIter<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct RawNetUserIter {
|
||||
content: [u8; 0],
|
||||
}
|
||||
|
||||
pub struct NetUserIter<'a> {
|
||||
iter: &'a mut RawNetUserIter,
|
||||
phantom_data: PhantomData<&'a CellInfo>,
|
||||
}
|
||||
|
||||
impl Iterator for NetUserIter<'_> {
|
||||
type Item = (*const CellInfo, IdString);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if unsafe { npnr_is_net_user_iter_done(self.iter) } {
|
||||
None
|
||||
} else {
|
||||
let cell = unsafe { &raw const *npnr_deref_net_user_iter_cell(self.iter) };
|
||||
let port = IdString(unsafe { npnr_deref_net_user_iter_port(self.iter) });
|
||||
unsafe { npnr_inc_net_user_iter(self.iter) };
|
||||
Some((cell, port))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for NetUserIter<'_> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { npnr_delete_net_user_iter(self.iter) };
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! log_info {
|
||||
($($t:tt)*) => {
|
||||
let s = std::ffi::CString::new(format!($($t)*)).unwrap();
|
||||
|
|
|
|||
30
rust/rust.cc
30
rust/rust.cc
|
|
@ -85,6 +85,9 @@ using NetIterWrapper = IterWrapper<NetIter>;
|
|||
using CellIter = decltype(Context(ArchArgs()).cells.begin());
|
||||
using CellIterWrapper = IterWrapper<CellIter>;
|
||||
|
||||
using NetUserIter = decltype(NetInfo(IdString()).users.begin());
|
||||
using NetUserIterWrapper = IterWrapper<NetUserIter>;
|
||||
|
||||
extern "C" {
|
||||
USING_NEXTPNR_NAMESPACE;
|
||||
|
||||
|
|
@ -229,6 +232,16 @@ int npnr_deref_cell_iter_first(CellIterWrapper *iter) { return wrap(iter->curren
|
|||
CellInfo *npnr_deref_cell_iter_second(CellIterWrapper *iter) { return iter->current->second.get(); }
|
||||
bool npnr_is_cell_iter_done(CellIterWrapper *iter) { return !(iter->current != iter->end); }
|
||||
|
||||
NetUserIterWrapper *npnr_context_net_user_iter(NetInfo *net)
|
||||
{
|
||||
return new NetUserIterWrapper(net->users.begin(), net->users.end());
|
||||
}
|
||||
void npnr_delete_net_user_iter(NetUserIterWrapper *iter) { delete iter; }
|
||||
void npnr_inc_net_user_iter(NetUserIterWrapper *iter) { ++iter->current; }
|
||||
CellInfo *npnr_deref_net_user_iter_cell(NetUserIterWrapper *iter) { return (*iter->current).cell; }
|
||||
uint64_t npnr_deref_net_user_iter_port(NetUserIterWrapper *iter) { return wrap((*iter->current).port.index); }
|
||||
bool npnr_is_net_user_iter_done(NetUserIterWrapper *iter) { return !(iter->current != iter->end); }
|
||||
|
||||
PortRef *npnr_netinfo_driver(NetInfo *net)
|
||||
{
|
||||
if (net == nullptr) {
|
||||
|
|
@ -237,19 +250,6 @@ PortRef *npnr_netinfo_driver(NetInfo *net)
|
|||
return &net->driver;
|
||||
}
|
||||
|
||||
uint32_t npnr_netinfo_users_leak(const NetInfo *net, const PortRef ***users)
|
||||
{
|
||||
auto size = net->users.entries();
|
||||
*users = new const PortRef *[size];
|
||||
auto idx = 0;
|
||||
for (auto &item : net->users) {
|
||||
(*users)[idx] = &item;
|
||||
idx++;
|
||||
}
|
||||
// Yes, by not freeing `users`, we leak memory.
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef ARCH_ECP5
|
||||
bool npnr_netinfo_is_global(NetInfo *net) { return net->is_global; }
|
||||
#else
|
||||
|
|
@ -260,7 +260,9 @@ int32_t npnr_netinfo_udata(NetInfo *net) { return net->udata; }
|
|||
void npnr_netinfo_udata_set(NetInfo *net, int32_t value) { net->udata = value; }
|
||||
|
||||
CellInfo *npnr_portref_cell(const PortRef *port) { return port->cell; }
|
||||
Loc npnr_cellinfo_get_location(const CellInfo *info) { return info->getLocation(); }
|
||||
uint64_t npnr_portref_port(const PortRef *port) { return wrap(port->port); }
|
||||
Loc npnr_cellinfo_get_location(const CellInfo *cell) { return cell->getLocation(); }
|
||||
uint64_t npnr_cellinfo_name(const CellInfo *cell) { return wrap(cell->name.index); }
|
||||
|
||||
void rust_example_printnets(Context *ctx);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue