diff --git a/benchmark/comb_guard_fanout_benchmark.dart b/benchmark/comb_guard_fanout_benchmark.dart index 446ddd528..bac930106 100644 --- a/benchmark/comb_guard_fanout_benchmark.dart +++ b/benchmark/comb_guard_fanout_benchmark.dart @@ -48,11 +48,6 @@ class CombGuardFanoutBenchmark extends AsyncBenchmarkBase { CombGuardFanoutBenchmark({this.numPuts = 100}) : super('CombGuardFanoutBenchmark'); - @override - Future teardown() async { - await Simulator.reset(); - } - CombGuardFanout? mod; final Logic a = Logic(width: 8); diff --git a/lib/src/modules/conditional.dart b/lib/src/modules/conditional.dart index b11b3487a..7852fe296 100644 --- a/lib/src/modules/conditional.dart +++ b/lib/src/modules/conditional.dart @@ -855,7 +855,12 @@ class ConditionalAssign extends Conditional { guard(driver); } - _receiverOutput.put(driverValue(driver)); + final currentValue = driverValue(driver); + if (!currentValue.isValid) { + _receiverOutput.put(LogicValue.x); + } else { + _receiverOutput.put(currentValue); + } if (!drivenSignals.contains(receiver) || receiver.value.isValid) { drivenSignals.add(receiver); @@ -1406,12 +1411,7 @@ class If extends Conditional { break; } else if (driverValue(iff.condition) != LogicValue.zero) { // x and z propagation - for (final receiver in receivers) { - receiverOutput(receiver).put(driverValue(iff.condition)[0]); - if (!drivenSignals.contains(receiver) || receiver.value.isValid) { - drivenSignals.add(receiver); - } - } + _driveX(drivenSignals); break; } // if it's 0, then continue searching down the path diff --git a/lib/src/modules/gates.dart b/lib/src/modules/gates.dart index 7415e58ff..f7194efe5 100644 --- a/lib/src/modules/gates.dart +++ b/lib/src/modules/gates.dart @@ -661,11 +661,11 @@ class Mux extends Module with InlineSystemVerilog { /// Executes the functional behavior of the mux. void _execute() { if (!_control.value.isValid) { - out.put(_control.value); + out.put(LogicValue.x); } else if (_control.value == LogicValue.zero) { - out.put(_d0.value); + out.put(_d0.value.isValid ? _d0.value : LogicValue.x); } else if (_control.value == LogicValue.one) { - out.put(_d1.value); + out.put(_d1.value.isValid ? _d1.value : LogicValue.x); } } diff --git a/lib/src/utilities/simcompare.dart b/lib/src/utilities/simcompare.dart index 4a6b073ad..95ac4b342 100644 --- a/lib/src/utilities/simcompare.dart +++ b/lib/src/utilities/simcompare.dart @@ -86,11 +86,9 @@ class Vector { } return arrAssigns.toString(); } else { - var assignmentValue = inputValues[signalName]; - if (assignmentValue is BigInt) { - assignmentValue = LogicValue.of(assignmentValue, width: signal.width); - } - return '$signalName = $assignmentValue;'; + final signalVal = + LogicValue.of(inputValues[signalName], width: signal.width); + return '$signalName = $signalVal;'; } }).join('\n'); diff --git a/test/conditionals_test.dart b/test/conditionals_test.dart index 981f73607..01905c1c5 100644 --- a/test/conditionals_test.dart +++ b/test/conditionals_test.dart @@ -163,6 +163,16 @@ class UniqueCase extends Module { enum SeqCondModuleType { caseNormal, caseZ, ifNormal } +class ConditionalAssignModule extends Module { + ConditionalAssignModule( + Logic a, + ) : super(name: 'ConditionalAssignModule') { + a = addInput('a', a); + final c = addOutput('c'); + Combinational([c < a]); + } +} + class SeqCondModule extends Module { Logic get equal => output('equal'); SeqCondModule(Logic clk, Logic a, {required SeqCondModuleType combType}) { @@ -214,6 +224,18 @@ class IfBlockModule extends Module { } } +class IffModule extends Module { + IffModule(Logic a, Logic b) : super(name: 'Iffmodule') { + a = addInput('a', a); + b = addInput('b', b); + final c = addOutput('c'); + + Combinational([ + If(a, then: [c < b]) + ]); + } +} + class SingleIfBlockModule extends Module { SingleIfBlockModule(Logic a) : super(name: 'singleifblockmodule') { a = addInput('a', a); @@ -537,6 +559,17 @@ void main() { expect(simResult, equals(true)); }); + test('if invalid ', () async { + final mod = IffModule(Logic(), Logic()); + await mod.build(); + final vectors = [ + Vector({'a': 1, 'b': 0}, {'c': 0}), + Vector({'a': LogicValue.z, 'b': 1}, {'c': LogicValue.x}), + Vector({'a': LogicValue.x, 'b': 0}, {'c': LogicValue.x}), + ]; + await SimCompare.checkFunctionalVector(mod, vectors); + }); + test('single iffblock comb', () async { final mod = SingleIfBlockModule(Logic()); await mod.build(); @@ -562,6 +595,18 @@ void main() { expect(simResult, equals(true)); }); + test('Conditional assign module with invalid inputs', () async { + final mod = ConditionalAssignModule(Logic()); + await mod.build(); + final vectors = [ + Vector({'a': 1}, {'c': 1}), + Vector({'a': 0}, {'c': 0}), + Vector({'a': LogicValue.z}, {'c': LogicValue.x}), + Vector({'a': LogicValue.x}, {'c': LogicValue.x}), + ]; + await SimCompare.checkFunctionalVector(mod, vectors); + }); + test('single elseifblock comb', () async { final mod = SingleElseIfBlockModule(Logic()); await mod.build(); diff --git a/test/gate_test.dart b/test/gate_test.dart index 032ecbb62..cde781e8e 100644 --- a/test/gate_test.dart +++ b/test/gate_test.dart @@ -414,13 +414,25 @@ void main() { test('Mux bus', () async { final mod = MuxWrapper(Logic(), Logic(width: 8), Logic(width: 8)); await mod.build(); - final vectors = [ + final vector1 = [ Vector({'control': 1, 'd0': 12, 'd1': 15}, {'y': 15}), Vector({'control': 0, 'd0': 18, 'd1': 7}, {'y': 18}), Vector({'control': 0, 'd0': 3, 'd1': 6}, {'y': 3}), + Vector({'control': 0, 'd0': 10, 'd1': LogicValue.z}, {'y': 10}), + Vector({'control': 1, 'd0': LogicValue.z, 'd1': 6}, {'y': 6}), ]; - await SimCompare.checkFunctionalVector(mod, vectors); - final simResult = SimCompare.iverilogVector(mod, vectors); + + final vector2 = [ + Vector( + {'control': 1, 'd0': 6, 'd1': LogicValue.z}, {'y': LogicValue.x}), + Vector( + {'control': LogicValue.z, 'd0': 10, 'd1': 6}, {'y': LogicValue.x}), + Vector( + {'control': 0, 'd0': LogicValue.z, 'd1': 10}, {'y': LogicValue.x}), + ]; + + await SimCompare.checkFunctionalVector(mod, vector1 + vector2); + final simResult = SimCompare.iverilogVector(mod, vector1); expect(simResult, equals(true)); });