@@ -378,6 +378,11 @@ class Sequential extends _Always {
378
378
/// The input clocks used in this block.
379
379
final List <Logic > _clks = [];
380
380
381
+ /// When `false` , an [SignalRedrivenException] will be thrown during
382
+ /// simulation if the same signal is driven multiple times within this
383
+ /// [Sequential] .
384
+ final bool allowMultipleAssignments;
385
+
381
386
/// Constructs a [Sequential] single-triggered by [clk] .
382
387
///
383
388
/// If `reset` is provided, then all signals driven by this block will be
@@ -387,12 +392,21 @@ class Sequential extends _Always {
387
392
/// that value instead upon reset. If a signal is in `resetValues` but not
388
393
/// driven by any other [Conditional] in this block, it will be driven to the
389
394
/// specified reset value.
390
- Sequential (Logic clk, List <Conditional > conditionals,
391
- {Logic ? reset,
392
- Map <Logic , dynamic >? resetValues,
393
- String name = 'sequential' })
394
- : this .multi ([clk], conditionals,
395
- name: name, reset: reset, resetValues: resetValues);
395
+ Sequential (
396
+ Logic clk,
397
+ List <Conditional > conditionals, {
398
+ Logic ? reset,
399
+ Map <Logic , dynamic >? resetValues,
400
+ bool allowMultipleAssignments = true ,
401
+ String name = 'sequential' ,
402
+ }) : this .multi (
403
+ [clk],
404
+ conditionals,
405
+ name: name,
406
+ reset: reset,
407
+ resetValues: resetValues,
408
+ allowMultipleAssignments: allowMultipleAssignments,
409
+ );
396
410
397
411
/// Constructs a [Sequential] multi-triggered by any of [clks] .
398
412
///
@@ -403,8 +417,14 @@ class Sequential extends _Always {
403
417
/// that value instead upon reset. If a signal is in `resetValues` but not
404
418
/// driven by any other [Conditional] in this block, it will be driven to the
405
419
/// specified reset value.
406
- Sequential .multi (List <Logic > clks, super ._conditionals,
407
- {super .reset, super .resetValues, super .name = 'sequential' }) {
420
+ Sequential .multi (
421
+ List <Logic > clks,
422
+ super ._conditionals, {
423
+ super .reset,
424
+ super .resetValues,
425
+ super .name = 'sequential' ,
426
+ this .allowMultipleAssignments = true ,
427
+ }) {
408
428
if (clks.isEmpty) {
409
429
throw IllegalConfigurationException ('Must provide at least one clock.' );
410
430
}
@@ -547,12 +567,18 @@ class Sequential extends _Always {
547
567
receiverOutput.put (LogicValue .x);
548
568
}
549
569
} else if (anyClkPosedge) {
550
- final allDrivenSignals = DuplicateDetectionSet <Logic >();
551
- for (final element in conditionals) {
552
- element.execute (allDrivenSignals, null );
553
- }
554
- if (allDrivenSignals.hasDuplicates) {
555
- throw SignalRedrivenException (allDrivenSignals.duplicates);
570
+ if (allowMultipleAssignments) {
571
+ for (final element in conditionals) {
572
+ element.execute (null , null );
573
+ }
574
+ } else {
575
+ final allDrivenSignals = DuplicateDetectionSet <Logic >();
576
+ for (final element in conditionals) {
577
+ element.execute (allDrivenSignals, null );
578
+ }
579
+ if (allDrivenSignals.hasDuplicates) {
580
+ throw SignalRedrivenException (allDrivenSignals.duplicates);
581
+ }
556
582
}
557
583
}
558
584
@@ -642,7 +668,7 @@ abstract class Conditional {
642
668
/// which consumes the current value of those drivers. It is used to check
643
669
/// that signals are not "written after read", for example.
644
670
@protected
645
- void execute (Set <Logic > drivenSignals, void Function (Logic toGuard)? guard);
671
+ void execute (Set <Logic >? drivenSignals, void Function (Logic toGuard)? guard);
646
672
647
673
/// Lists *all* receivers, recursively including all sub-[Conditional] s
648
674
/// receivers.
@@ -752,10 +778,11 @@ abstract class Conditional {
752
778
{required int context});
753
779
754
780
/// Drives X to all receivers.
755
- void _driveX (Set <Logic > drivenSignals) {
781
+ void _driveX (Set <Logic >? drivenSignals) {
756
782
for (final receiver in receivers) {
757
783
receiverOutput (receiver).put (LogicValue .x);
758
- if (! drivenSignals.contains (receiver) || receiver.value.isValid) {
784
+ if (drivenSignals != null &&
785
+ (! drivenSignals.contains (receiver) || receiver.value.isValid)) {
759
786
drivenSignals.add (receiver);
760
787
}
761
788
}
@@ -794,7 +821,7 @@ class ConditionalGroup extends Conditional {
794
821
[for (final conditional in conditionals) ...conditional.receivers];
795
822
796
823
@override
797
- void execute (Set <Logic > drivenSignals, void Function (Logic toGuard)? guard) {
824
+ void execute (Set <Logic >? drivenSignals, void Function (Logic toGuard)? guard) {
798
825
for (final conditional in conditionals) {
799
826
conditional.execute (drivenSignals, guard);
800
827
}
@@ -850,7 +877,7 @@ class ConditionalAssign extends Conditional {
850
877
late final _receiverOutput = receiverOutput (receiver);
851
878
852
879
@override
853
- void execute (Set <Logic > drivenSignals,
880
+ void execute (Set <Logic >? drivenSignals,
854
881
[void Function (Logic toGuard)? guard]) {
855
882
if (guard != null ) {
856
883
guard (driver);
@@ -863,7 +890,8 @@ class ConditionalAssign extends Conditional {
863
890
_receiverOutput.put (currentValue);
864
891
}
865
892
866
- if (! drivenSignals.contains (receiver) || receiver.value.isValid) {
893
+ if (drivenSignals != null &&
894
+ (! drivenSignals.contains (receiver) || receiver.value.isValid)) {
867
895
drivenSignals.add (receiver);
868
896
}
869
897
}
@@ -1053,7 +1081,7 @@ class Case extends Conditional {
1053
1081
String get caseType => 'case' ;
1054
1082
1055
1083
@override
1056
- void execute (Set <Logic > drivenSignals, [void Function (Logic )? guard]) {
1084
+ void execute (Set <Logic >? drivenSignals, [void Function (Logic )? guard]) {
1057
1085
if (guard != null ) {
1058
1086
guard (expression);
1059
1087
for (final item in items) {
@@ -1397,7 +1425,7 @@ class If extends Conditional {
1397
1425
}
1398
1426
1399
1427
@override
1400
- void execute (Set <Logic > drivenSignals, [void Function (Logic )? guard]) {
1428
+ void execute (Set <Logic >? drivenSignals, [void Function (Logic )? guard]) {
1401
1429
if (guard != null ) {
1402
1430
for (final iff in iffs) {
1403
1431
guard (iff.condition);
0 commit comments