diff --git "a/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/README.md" "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/README.md" new file mode 100644 index 0000000..fdbe1d0 --- /dev/null +++ "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/README.md" @@ -0,0 +1,36 @@ +# 逻辑模拟器 + +一个轻量级的 Python 逻辑门模拟器示例仓库,用于搭建、运行和测试简单的组合逻辑电路。 + +## 功能 + +- 支持 `AND`、`OR`、`NOT`、`XOR`、`NAND`、`NOR` 等常见逻辑门。 +- 支持通过连线把逻辑门组合成电路。 +- 提供半加器示例,便于快速验证模拟结果。 + +## 快速开始 + +```bash +python examples/half_adder.py +``` + +预期输出: + +```text +A=0 B=0 -> SUM=0 CARRY=0 +A=0 B=1 -> SUM=1 CARRY=0 +A=1 B=0 -> SUM=1 CARRY=0 +A=1 B=1 -> SUM=0 CARRY=1 +``` + +## 目录结构 + +```text +逻辑模拟器/ +├── README.md +├── examples/ +│ └── half_adder.py +└── logic_simulator/ + ├── __init__.py + └── core.py +``` diff --git "a/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/examples/half_adder.py" "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/examples/half_adder.py" new file mode 100644 index 0000000..dfd9500 --- /dev/null +++ "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/examples/half_adder.py" @@ -0,0 +1,23 @@ +"""Half-adder example built with the logic simulator.""" + +from pathlib import Path +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + +from logic_simulator import Circuit, and_gate, xor_gate + + +def build_half_adder() -> Circuit: + circuit = Circuit() + circuit.add_gate("sum", ["A", "B"], "SUM", xor_gate) + circuit.add_gate("carry", ["A", "B"], "CARRY", and_gate) + return circuit + + +if __name__ == "__main__": + half_adder = build_half_adder() + for a in (0, 1): + for b in (0, 1): + result = half_adder.run(A=a, B=b) + print(f"A={a} B={b} -> SUM={int(result['SUM'])} CARRY={int(result['CARRY'])}") diff --git "a/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/logic_simulator/__init__.py" "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/logic_simulator/__init__.py" new file mode 100644 index 0000000..63536a3 --- /dev/null +++ "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/logic_simulator/__init__.py" @@ -0,0 +1,14 @@ +"""Tiny logic simulator package.""" + +from .core import Circuit, Gate, and_gate, nand_gate, nor_gate, not_gate, or_gate, xor_gate + +__all__ = [ + "Circuit", + "Gate", + "and_gate", + "nand_gate", + "nor_gate", + "not_gate", + "or_gate", + "xor_gate", +] diff --git "a/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/logic_simulator/core.py" "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/logic_simulator/core.py" new file mode 100644 index 0000000..458ab5a --- /dev/null +++ "b/\351\200\273\350\276\221\346\250\241\346\213\237\345\231\250/logic_simulator/core.py" @@ -0,0 +1,71 @@ +"""Core primitives for a tiny combinational logic simulator.""" + +from dataclasses import dataclass, field +from typing import Callable, Dict, Iterable, List + +LogicFunction = Callable[..., bool] + + +def _to_bool(value: bool | int) -> bool: + """Normalize an input value to a boolean signal.""" + return bool(value) + + +def and_gate(*inputs: bool | int) -> bool: + return all(_to_bool(value) for value in inputs) + + +def or_gate(*inputs: bool | int) -> bool: + return any(_to_bool(value) for value in inputs) + + +def not_gate(input_value: bool | int) -> bool: + return not _to_bool(input_value) + + +def xor_gate(*inputs: bool | int) -> bool: + return sum(_to_bool(value) for value in inputs) % 2 == 1 + + +def nand_gate(*inputs: bool | int) -> bool: + return not and_gate(*inputs) + + +def nor_gate(*inputs: bool | int) -> bool: + return not or_gate(*inputs) + + +@dataclass(frozen=True) +class Gate: + """A named logic operation that reads input signal names and writes one output.""" + + name: str + inputs: List[str] + output: str + operation: LogicFunction + + def evaluate(self, signals: Dict[str, bool]) -> bool: + values = [signals[input_name] for input_name in self.inputs] + return self.operation(*values) + + +@dataclass +class Circuit: + """A simple acyclic combinational circuit.""" + + gates: List[Gate] = field(default_factory=list) + + def add_gate( + self, + name: str, + inputs: Iterable[str], + output: str, + operation: LogicFunction, + ) -> None: + self.gates.append(Gate(name, list(inputs), output, operation)) + + def run(self, **input_signals: bool | int) -> Dict[str, bool]: + signals = {name: _to_bool(value) for name, value in input_signals.items()} + for gate in self.gates: + signals[gate.output] = gate.evaluate(signals) + return signals