diff --git a/src/kyupy/logic_sim.py b/src/kyupy/logic_sim.py index dd9a45c..a8bc535 100644 --- a/src/kyupy/logic_sim.py +++ b/src/kyupy/logic_sim.py @@ -10,7 +10,7 @@ import math import numpy as np -from . import logic, hr_bytes +from . import numba, logic, hr_bytes, sim from .sim import SimOps, SimPrim @@ -148,7 +148,7 @@ class LogicSim(SimOps): # return responses - def c_prop(self, inject_cb=None): + def c_prop(self, sims=None, inject_cb=None): """Propagate the input values towards the outputs (Perform all logic operations in topological order). If the circuit is sequential (it contains flip-flops), one call simulates one clock cycle. @@ -168,20 +168,24 @@ class LogicSim(SimOps): resumes with the manipulated values after the callback returns. :type inject_cb: ``f(Line, ndarray)`` """ + if sims is None: sims = self.sims + nbytes = (sims - 1) // 8 + 1 if self.m == 2: - for op, o0, i0, i1, i2, i3 in self.ops: - o0, i0, i1, i2, i3 = [self.vat[x,0] for x in (o0, i0, i1, i2, i3)] - if op == SimPrim.BUF1: self.c[o0]=self.c[i0] - elif op == SimPrim.INV1: self.c[o0] = ~self.c[i0] - elif op == SimPrim.AND2: self.c[o0] = self.c[i0] & self.c[i1] - elif op == SimPrim.NAND2: self.c[o0] = ~(self.c[i0] & self.c[i1]) - elif op == SimPrim.OR2: self.c[o0] = self.c[i0] | self.c[i1] - elif op == SimPrim.NOR2: self.c[o0] = ~(self.c[i0] | self.c[i1]) - elif op == SimPrim.XOR2: self.c[o0] = self.c[i0] ^ self.c[i1] - elif op == SimPrim.XNOR2: self.c[o0] = ~(self.c[i0] ^ self.c[i1]) - else: print(f'unknown SimPrim {op}') - if inject_cb is not None: inject_cb(o0, self.s[o0]) - pass + if inject_cb is None: + _prop_cpu(self.ops, self.vat, self.c[...,:nbytes]) + else: + for op, o0, i0, i1, i2, i3 in self.ops: + o0, i0, i1, i2, i3 = [self.vat[x,0] for x in (o0, i0, i1, i2, i3)] + if op == SimPrim.BUF1: self.c[o0]=self.c[i0] + elif op == SimPrim.INV1: self.c[o0] = ~self.c[i0] + elif op == SimPrim.AND2: self.c[o0] = self.c[i0] & self.c[i1] + elif op == SimPrim.NAND2: self.c[o0] = ~(self.c[i0] & self.c[i1]) + elif op == SimPrim.OR2: self.c[o0] = self.c[i0] | self.c[i1] + elif op == SimPrim.NOR2: self.c[o0] = ~(self.c[i0] | self.c[i1]) + elif op == SimPrim.XOR2: self.c[o0] = self.c[i0] ^ self.c[i1] + elif op == SimPrim.XNOR2: self.c[o0] = ~(self.c[i0] ^ self.c[i1]) + else: print(f'unknown SimPrim {op}') + inject_cb(o0, self.s[o0]) elif self.m == 4: pass else: @@ -285,4 +289,18 @@ class LogicSim(SimOps): # def aoi21_fct(self, inputs, outputs): # logic.bp_and(self.tmp[0], inputs[0], inputs[1]) # logic.bp_or(outputs[0], self.tmp[0], inputs[2]) - # logic.bp_not(outputs[0], outputs[0]) \ No newline at end of file + # logic.bp_not(outputs[0], outputs[0]) + +@numba.njit() +def _prop_cpu(ops, vat, c): + for op, o0, i0, i1, i2, i3 in ops: + o0, i0, i1, i2, i3 = [vat[x,0] for x in (o0, i0, i1, i2, i3)] + if op == sim.BUF1: c[o0]=c[i0] + elif op == sim.INV1: c[o0] = ~c[i0] + elif op == sim.AND2: c[o0] = c[i0] & c[i1] + elif op == sim.NAND2: c[o0] = ~(c[i0] & c[i1]) + elif op == sim.OR2: c[o0] = c[i0] | c[i1] + elif op == sim.NOR2: c[o0] = ~(c[i0] | c[i1]) + elif op == sim.XOR2: c[o0] = c[i0] ^ c[i1] + elif op == sim.XNOR2: c[o0] = ~(c[i0] ^ c[i1]) + else: print(f'unknown SimPrim {op}') diff --git a/src/kyupy/sim.py b/src/kyupy/sim.py index 76efe98..f0a9116 100644 --- a/src/kyupy/sim.py +++ b/src/kyupy/sim.py @@ -4,6 +4,43 @@ from bisect import bisect, insort_left import numpy as np +BUF1 = 0b1010_1010_1010_1010 +INV1 = 0b0101_0101_0101_0101 + +NAND4 = 0b0111_1111_1111_1111 +NAND3 = 0b0111_1111_0111_1111 +NAND2 = 0b0111_0111_0111_0111 + +NOR4 = 0b0000_0000_0000_0001 +NOR3 = 0b0000_0001_0000_0001 +NOR2 = 0b0001_0001_0001_0001 + +AND4 = 0b1000_0000_0000_0000 +AND3 = 0b1000_0000_1000_0000 +AND2 = 0b1000_1000_1000_1000 + +OR4 = 0b1111_1111_1111_1110 +OR3 = 0b1111_1110_1111_1110 +OR2 = 0b1110_1110_1110_1110 + +XOR4 = 0b0110_1001_1001_0110 +XOR3 = 0b1001_0110_1001_0110 +XOR2 = 0b0110_0110_0110_0110 + +XNOR4 = 0b1001_0110_0110_1001 +XNOR3 = 0b0110_1001_0110_1001 +XNOR2 = 0b1001_1001_1001_1001 + +AO22 = 0b1111_1000_1000_1000 +AOI22 = 0b0000_0111_0111_0111 +AO21 = 0b1110_1010_1110_1010 +AOI21 = 0b0001_0101_0001_0101 +OA22 = 0b1110_1110_1110_0000 +OAI22 = 0b0001_0001_0001_1111 +OA21 = 0b1010_1000_1010_1000 +OAI21 = 0b0101_0111_0101_0111 +MUX21 = 0b1110_0100_1110_0100 + class SimPrim: BUF1 = 0b1010_1010_1010_1010 INV1 = 0b0101_0101_0101_0101