diff --git a/lib/src/signals/logic.dart b/lib/src/signals/logic.dart index 981ad75f3..520b73d5c 100644 --- a/lib/src/signals/logic.dart +++ b/lib/src/signals/logic.dart @@ -439,13 +439,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 = this as Const; + } else if (other is Const && other.value.isValid) { + constOperand = other; + otherOperand = this; + } + + if (constOperand != null && otherOperand != null) { + if (constOperand.value == LogicValue.filled(width, LogicValue.zero)) { + return constOperand; + } 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 = this as Const; + } else if (other is Const && other.value.isValid) { + constOperand = other; + otherOperand = this; + } + + if (constOperand != null && otherOperand != null) { + if (constOperand.value == LogicValue.filled(width, LogicValue.one)) { + return constOperand; + } 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 905c912d9..fe892f726 100644 --- a/test/gate_test.dart +++ b/test/gate_test.dart @@ -352,6 +352,127 @@ 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)); + + expect(~normalLogic, isA()); + expect((~normalLogic).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(0, 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()); + expect((const0 & const1).value, equals(const0.value)); + }); + + 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 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(normalLogic.value)); + + expect(logicX | const0, isA()); + expect((logicX | const0).value, equals(logicX.value)); + + expect(normalLogic | const1, isA()); + expect((normalLogic | const1).value, equals(LogicValue.one)); + + expect(normalLogic | logicX, isA()); + expect((normalLogic | logicX).value, equals(LogicValue.one)); + + expect(const0 | const1, isA()); + expect((const0 | const1).value, equals(LogicValue.one)); + }); + + test('OR2Gate Multi bit Constant input', () async { + final const1 = Const(bin('1101'), 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('1101', width: 4))); + + expect(logic0 | const1, isA()); + expect((logic0 | const1).value, equals(const1.value)); + + expect(logic1 | const1, isA()); + expect((logic1 | const1).value, equals(const1.value)); + + expect(logicX | const1, isA()); + expect((logicX | const1).value, equals(LogicValue.of('11x1', width: 4))); + }); + }); + group('simcompare', () { test('NotGate single bit', () async { final gtm = GateTestModule(Logic(), Logic());