@@ -157,7 +157,10 @@ impl Context {
157
157
}
158
158
159
159
/// Bind a given bel to a given cell with the given strength.
160
- pub fn bind_bel ( & mut self , bel : BelId , cell : * mut CellInfo , strength : PlaceStrength ) {
160
+ ///
161
+ /// # Safety
162
+ /// `cell` must be valid and not null.
163
+ pub unsafe fn bind_bel ( & mut self , bel : BelId , cell : * mut CellInfo , strength : PlaceStrength ) {
161
164
unsafe { npnr_context_bind_bel ( self , bel, cell, strength) }
162
165
}
163
166
@@ -172,7 +175,10 @@ impl Context {
172
175
}
173
176
174
177
/// Bind a wire to a net. This method must be used when binding a wire that is driven by a bel pin. Use bindPip() when binding a wire that is driven by a pip.
175
- pub fn bind_wire ( & mut self , wire : WireId , net : * mut NetInfo , strength : PlaceStrength ) {
178
+ ///
179
+ /// # Safety
180
+ /// `net` must be valid and not null.
181
+ pub unsafe fn bind_wire ( & mut self , wire : WireId , net : * mut NetInfo , strength : PlaceStrength ) {
176
182
unsafe { npnr_context_bind_wire ( self , wire, net, strength) }
177
183
}
178
184
@@ -181,8 +187,11 @@ impl Context {
181
187
unsafe { npnr_context_unbind_wire ( self , wire) }
182
188
}
183
189
184
- /// Bid a pip to a net. This also bind the destination wire of that pip.
185
- pub fn bind_pip ( & mut self , pip : PipId , net : * mut NetInfo , strength : PlaceStrength ) {
190
+ /// Bind a pip to a net. This also binds the destination wire of that pip.
191
+ ///
192
+ /// # Safety
193
+ /// `net` must be valid and not null.
194
+ pub unsafe fn bind_pip ( & mut self , pip : PipId , net : * mut NetInfo , strength : PlaceStrength ) {
186
195
unsafe { npnr_context_bind_pip ( self , pip, net, strength) }
187
196
}
188
197
@@ -218,11 +227,15 @@ impl Context {
218
227
unsafe { npnr_context_delay_epsilon ( self ) }
219
228
}
220
229
221
- pub fn source_wire ( & self , net : * const NetInfo ) -> WireId {
230
+ /// # Safety
231
+ /// `net` must be valid and not null.
232
+ pub unsafe fn source_wire ( & self , net : * const NetInfo ) -> WireId {
222
233
unsafe { npnr_context_get_netinfo_source_wire ( self , net) }
223
234
}
224
235
225
- pub fn sink_wires ( & self , net : * const NetInfo , sink : * const PortRef ) -> Vec < WireId > {
236
+ /// # Safety
237
+ /// `net` and `sink` must be valid and not null.
238
+ pub unsafe fn sink_wires ( & self , net : * const NetInfo , sink : * const PortRef ) -> Vec < WireId > {
226
239
let mut v = Vec :: new ( ) ;
227
240
let mut n = 0 ;
228
241
loop {
@@ -269,10 +282,39 @@ impl Context {
269
282
}
270
283
271
284
pub fn pip_direction ( & self , pip : PipId ) -> Loc {
272
- unsafe { npnr_context_get_pip_direction ( self , pip) }
285
+ let mut src = Loc { x : 0 , y : 0 , z : 0 } ;
286
+ let mut dst = Loc { x : 0 , y : 0 , z : 0 } ;
287
+
288
+ let mut pips = 0 ;
289
+ for pip in self . get_uphill_pips ( self . pip_src_wire ( pip) ) {
290
+ let loc = self . pip_location ( pip) ;
291
+ src. x += loc. x ;
292
+ src. y += loc. y ;
293
+ pips += 1 ;
294
+ }
295
+ if pips != 0 {
296
+ src. x /= pips;
297
+ src. y /= pips;
298
+ }
299
+
300
+ let mut pips = 0 ;
301
+ for pip in self . get_downhill_pips ( self . pip_dst_wire ( pip) ) {
302
+ let loc = self . pip_location ( pip) ;
303
+ dst. x += loc. x ;
304
+ dst. y += loc. y ;
305
+ pips += 1 ;
306
+ }
307
+ if pips != 0 {
308
+ dst. x /= pips;
309
+ dst. y /= pips;
310
+ }
311
+
312
+ Loc { x : dst. x - src. x , y : dst. y - src. y , z : 0 }
273
313
}
274
314
275
- pub fn pip_avail_for_net ( & self , pip : PipId , net : * mut NetInfo ) -> bool {
315
+ /// # Safety
316
+ /// `net` must be valid and not null.
317
+ pub unsafe fn pip_avail_for_net ( & self , pip : PipId , net : * mut NetInfo ) -> bool {
276
318
unsafe { npnr_context_check_pip_avail_for_net ( self , pip, net) }
277
319
}
278
320
@@ -349,7 +391,6 @@ extern "C" {
349
391
fn npnr_context_get_wires_leak ( ctx : * const Context , wires : * mut * mut WireId ) -> u64 ;
350
392
fn npnr_context_get_pips_leak ( ctx : * const Context , pips : * mut * mut PipId ) -> u64 ;
351
393
fn npnr_context_get_pip_location ( ctx : * const Context , pip : PipId ) -> Loc ;
352
- fn npnr_context_get_pip_direction ( ctx : * const Context , pip : PipId ) -> Loc ;
353
394
fn npnr_context_check_pip_avail_for_net (
354
395
ctx : * const Context ,
355
396
pip : PipId ,
@@ -404,7 +445,6 @@ pub struct Nets<'a> {
404
445
nets : HashMap < IdString , * mut NetInfo > ,
405
446
users : HashMap < IdString , & ' a [ & ' a mut PortRef ] > ,
406
447
index_to_net : Vec < IdString > ,
407
- net_to_index : HashMap < * mut NetInfo , i32 > ,
408
448
_data : PhantomData < & ' a Context > ,
409
449
}
410
450
@@ -428,7 +468,6 @@ impl<'a> Nets<'a> {
428
468
let mut nets = HashMap :: new ( ) ;
429
469
let mut users = HashMap :: new ( ) ;
430
470
let mut index_to_net = Vec :: new ( ) ;
431
- let mut net_to_index = HashMap :: new ( ) ;
432
471
for i in 0 ..size {
433
472
let name = unsafe { IdString ( * names. add ( i as usize ) ) } ;
434
473
let net = unsafe { * nets_ptr. add ( i as usize ) } ;
@@ -443,7 +482,6 @@ impl<'a> Nets<'a> {
443
482
users. insert ( name, users_slice) ;
444
483
let index = index_to_net. len ( ) as i32 ;
445
484
index_to_net. push ( name) ;
446
- net_to_index. insert ( net, index) ;
447
485
unsafe {
448
486
npnr_netinfo_udata_set ( net, NetIndex ( index) ) ;
449
487
}
@@ -453,7 +491,6 @@ impl<'a> Nets<'a> {
453
491
nets,
454
492
users,
455
493
index_to_net,
456
- net_to_index,
457
494
_data : PhantomData ,
458
495
}
459
496
}
@@ -468,6 +505,10 @@ impl<'a> Nets<'a> {
468
505
self . nets . len ( )
469
506
}
470
507
508
+ pub fn is_empty ( & self ) -> bool {
509
+ self . nets . len ( ) == 0
510
+ }
511
+
471
512
pub fn name_from_index ( & self , index : NetIndex ) -> IdString {
472
513
self . index_to_net [ index. 0 as usize ]
473
514
}
0 commit comments