diff --git a/lib/src/signals/logic.dart b/lib/src/signals/logic.dart index b9e59c5ed..0c79bf31a 100644 --- a/lib/src/signals/logic.dart +++ b/lib/src/signals/logic.dart @@ -383,13 +383,59 @@ class Logic { void operator <=(Logic other) => gets(other); /// Logical bitwise NOT. - Logic operator ~() => NotGate(this).out; + Logic operator ~() => this is Const ? Const(~value) : NotGate(this).out; /// Logical bitwise AND. - Logic operator &(Logic other) => And2Gate(this, other).out; + Logic operator &(Logic other) { + if (this is Const && other is Const) { + return Const((this as Const).value & other.value); + } + Const? constOperand; + Logic? otherOperand; + + if (this is Const && value.isValid) { + constOperand = Const(this); + } else if (other is Const && other.value.isValid) { + constOperand = other; + otherOperand = this; + } + + if (constOperand != null) { + if (constOperand.value == LogicValue.filled(width, LogicValue.zero)) { + return Const(LogicValue.filled(width, LogicValue.zero)); + } else if (constOperand.value == + LogicValue.filled(width, LogicValue.one)) { + return otherOperand!; + } + } + return And2Gate(this, other).out; + } /// Logical bitwise OR. - Logic operator |(Logic other) => Or2Gate(this, other).out; + Logic operator |(Logic other) { + if (this is Const && other is Const) { + return Const((this as Const).value | other.value); + } + Const? constOperand; + Logic? otherOperand; + + if (this is Const && value.isValid) { + constOperand = Const(this); + } else if (other is Const && other.value.isValid) { + constOperand = other; + otherOperand = this; + } + + if (constOperand != null) { + if (constOperand.value == LogicValue.filled(width, LogicValue.one)) { + return Const(LogicValue.filled(width, LogicValue.one)); + } else if (constOperand.value == + LogicValue.filled(width, LogicValue.zero)) { + return otherOperand!; + } + } + return Or2Gate(this, other).out; + } /// Logical bitwise XOR. Logic operator ^(Logic other) => Xor2Gate(this, other).out; diff --git a/test/gate_test.dart b/test/gate_test.dart index 117783848..d405f0ff8 100644 --- a/test/gate_test.dart +++ b/test/gate_test.dart @@ -353,6 +353,109 @@ void main() { }); }); + group('Const input Gate test', () { + test('NotGate single bit Constant input', () async { + final normalLogic = Logic(); + final const0 = Const(LogicValue.zero, width: 1); + final constX = Const(LogicValue.x, width: 1); + final const1 = Const(LogicValue.one, width: 1); + normalLogic.put(LogicValue.one); + + expect(~const0, isA()); + expect((~const0).value, equals(LogicValue.one)); + + expect(~constX, isA()); + expect((~constX).value, equals(LogicValue.x)); + + expect(~const1, isA()); + expect((~const1).value, equals(LogicValue.zero)); + }); + + test('NotGate Multi bit Constant input', () async { + final const1 = Const(bin('1111'), width: 4); + final const4 = Const(bin('0100'), width: 4); + + expect(~const1, isA()); + expect((~const1).value, equals(LogicValue.of(LogicValue.zero, width: 4))); + + expect(~const4, isA()); + expect((~const4).value, equals(LogicValue.of(11, width: 4))); + }); + + test('And2Gate Single bit Constant input', () async { + final normalLogic = Logic(); + final const0 = Const(LogicValue.zero); + final logicX = Logic(); + final const1 = Const(LogicValue.one); + normalLogic.put(LogicValue.one); + logicX.put(LogicValue.x); + + expect(normalLogic & const0, isA()); + expect((normalLogic & const0).value, equals(LogicValue.zero)); + expect(logicX & const0, isA()); + expect((logicX & const0).value, equals(LogicValue.zero)); + expect(normalLogic & const1, isA()); + expect((normalLogic & const1).value, equals(normalLogic.value)); + expect(normalLogic & logicX, isA()); + expect((normalLogic & logicX).value, equals(LogicValue.x)); + expect(const0 & const1, isA()); + }); + + test('And2Gate Multi bit Constant input', () async { + final const1 = Const(bin('1111'), width: 4); + final const4 = Const(bin('0100'), width: 4); + final logic0 = Logic(width: 4)..put(LogicValue.zero); + final logic1 = Logic(width: 4)..put(LogicValue.one); + final logicX = Logic(width: 4)..put(LogicValue.x); + + expect(const1 & const4, isA()); + expect((const1 & const4).value, equals(LogicValue.of('0100', width: 4))); + + expect(logic0 & const1, isA()); + expect((logic0 & const1).value, equals(LogicValue.of('0000', width: 4))); + + expect(logic1 & const1, isA()); + expect((logic1 & const1).value, equals(LogicValue.of('0001', width: 4))); + + expect(logicX & const1, isA()); + expect((logicX & const1).value, equals(LogicValue.of('xxxx', width: 4))); + }); + + test('OR2Gate Single bit Constant input', () async { + final a = Logic(); + final b = Const(LogicValue.zero, width: 1); + final c = Const(LogicValue.x, width: 1); + final d = Const(LogicValue.one, width: 1); + final z = Const('11111', width: 5); + final y = Const(LogicValue.of('11x01', width: 5)); + a.put(LogicValue.one); + + expect(a | b, isA()); + expect((a | b).value, equals(a.value)); + + expect(a | c, isA()); + expect((a | c).value, equals(LogicValue.one)); + + expect(a | d, isA()); + expect((a | d).value, equals(LogicValue.one)); + + expect(y | z, isA()); + expect((y | z).value, equals(LogicValue.of('11111', width: 5))); + }); + + test('OR2Gate Multi bit Constant input', () async { + final a = Const(LogicValue.of(LogicValue.zero, width: 4)); + final b = Const(bin('1111'), width: 4); + final c = Const(bin('0100'), width: 4); + + expect(a | c, isA()); + expect((a | c).value, equals(c.value)); + + expect(b | c, isA()); + expect((b | c).value, equals(LogicValue.filled(4, LogicValue.one))); + }); + }); + group('simcompare', () { test('NotGate single bit', () async { final gtm = GateTestModule(Logic(), Logic());