@@ -13,6 +13,7 @@ import {
13
13
} from './engine'
14
14
import Wire from './wire'
15
15
import { colors } from './themer/themer'
16
+ import ContentionMeta from './contention'
16
17
17
18
/**
18
19
* Constructs all the connections of Node node
@@ -418,48 +419,69 @@ export default class Node {
418
419
return
419
420
}
420
421
421
- if ( this . type == 0 ) {
422
+ // For input nodes, resolve its parents if they are resolvable at this point.
423
+ if ( this . type == NODE_INPUT ) {
422
424
if ( this . parent . isResolvable ( ) ) {
423
425
simulationArea . simulationQueue . add ( this . parent )
424
426
}
425
427
}
428
+ else if ( this . type == NODE_OUTPUT ) {
429
+ // Since output node forces its value on its neighbours, remove its contentions.
430
+ // An existing contention will now trickle to the other output node that was causing
431
+ // the contention.
432
+ simulationArea . contentionPending . removeAllContentionsForNode ( this ) ;
433
+ }
426
434
427
435
for ( var i = 0 ; i < this . connections . length ; i ++ ) {
428
- const node = this . connections [ i ]
429
-
430
- if ( node . value != this . value || node . bitWidth != this . bitWidth ) {
431
- if (
432
- node . type == 1 &&
433
- node . value != undefined &&
434
- node . parent . objectType != 'TriState' &&
435
- ! ( node . subcircuitOverride && node . scope != this . scope ) && // Subcircuit Input Node Output Override
436
- node . parent . objectType != 'SubCircuit'
437
- ) {
438
- // Subcircuit Output Node Override
439
- this . highlighted = true
440
- node . highlighted = true
441
- var circuitName = node . scope . name
442
- var circuitElementName = node . parent . objectType
443
- showError (
444
- `Contention Error: ${ this . value } and ${ node . value } at ${ circuitElementName } in ${ circuitName } `
445
- )
446
- } else if ( node . bitWidth == this . bitWidth || node . type == 2 ) {
447
- if ( ( node . parent . objectType == 'TriState' || node . parent . objectType == 'ControlledInverter' ) && node . value != undefined ) {
448
- if ( node . parent . state . value ) {
449
- simulationArea . contentionPending . push ( node . parent )
436
+ const node = this . connections [ i ] ;
437
+
438
+ switch ( node . type ) {
439
+ // TODO: For an output node, a downstream value (value given by elements other than the parent)
440
+ // should be overwritten in contention check and should not cause contention.
441
+ case NODE_OUTPUT :
442
+ if ( node . value != this . value || node . bitWidth != this . bitWidth ) {
443
+ // Check contentions
444
+ if ( node . value != undefined && node . parent . objectType != 'SubCircuit'
445
+ && ! ( node . subcircuitOverride && node . scope != this . scope ) ) {
446
+ // Tristate has always been a pain in the ass.
447
+ if ( ( node . parent . objectType == 'TriState' || node . parent . objectType == 'ControlledInverter' ) && node . value != undefined ) {
448
+ if ( node . parent . state . value ) {
449
+ simulationArea . contentionPending . add ( node , this ) ;
450
+ break ;
451
+ }
452
+ }
453
+ else {
454
+ simulationArea . contentionPending . add ( node , this ) ;
455
+ break ;
450
456
}
451
457
}
452
-
453
- node . bitWidth = this . bitWidth
454
- node . value = this . value
455
- simulationArea . simulationQueue . add ( node )
456
458
} else {
457
- this . highlighted = true
458
- node . highlighted = true
459
- showError (
460
- `BitWidth Error: ${ this . bitWidth } and ${ node . bitWidth } `
461
- )
459
+ // Output node was given an agreeing value, so remove any contention
460
+ // entry between these two nodes if it exists.
461
+ simulationArea . contentionPending . remove ( node , this ) ;
462
+ }
463
+
464
+ // Fallthrough. NODE_OUTPUT propagates like a contention checked NODE_INPUT
465
+ case NODE_INPUT :
466
+ // Check bitwidths
467
+ if ( this . bitWidth != node . bitWidth ) {
468
+ this . highlighted = true ;
469
+ node . highlighted = true ;
470
+ showError ( `BitWidth Error: ${ this . bitWidth } and ${ node . bitWidth } ` ) ;
471
+ break ;
472
+ }
473
+
474
+ // Fallthrough. NODE_INPUT propagates like a bitwidth checked NODE_INTERMEDIATE
475
+ case NODE_INTERMEDIATE :
476
+
477
+ if ( node . value != this . value || node . bitWidth != this . bitWidth ) {
478
+ // Propagate
479
+ node . bitWidth = this . bitWidth ;
480
+ node . value = this . value ;
481
+ simulationArea . simulationQueue . add ( node ) ;
462
482
}
483
+ default :
484
+ break ;
463
485
}
464
486
}
465
487
}
0 commit comments