Browse Source

jitted logic sim

devel
Stefan Holst 2 years ago
parent
commit
7430ebb068
  1. 50
      src/kyupy/logic_sim.py
  2. 37
      src/kyupy/sim.py

50
src/kyupy/logic_sim.py

@ -10,7 +10,7 @@ import math
import numpy as np import numpy as np
from . import logic, hr_bytes from . import numba, logic, hr_bytes, sim
from .sim import SimOps, SimPrim from .sim import SimOps, SimPrim
@ -148,7 +148,7 @@ class LogicSim(SimOps):
# return responses # 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). """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. 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. resumes with the manipulated values after the callback returns.
:type inject_cb: ``f(Line, ndarray)`` :type inject_cb: ``f(Line, ndarray)``
""" """
if sims is None: sims = self.sims
nbytes = (sims - 1) // 8 + 1
if self.m == 2: if self.m == 2:
for op, o0, i0, i1, i2, i3 in self.ops: if inject_cb is None:
o0, i0, i1, i2, i3 = [self.vat[x,0] for x in (o0, i0, i1, i2, i3)] _prop_cpu(self.ops, self.vat, self.c[...,:nbytes])
if op == SimPrim.BUF1: self.c[o0]=self.c[i0] else:
elif op == SimPrim.INV1: self.c[o0] = ~self.c[i0] for op, o0, i0, i1, i2, i3 in self.ops:
elif op == SimPrim.AND2: self.c[o0] = self.c[i0] & self.c[i1] o0, i0, i1, i2, i3 = [self.vat[x,0] for x in (o0, i0, i1, i2, i3)]
elif op == SimPrim.NAND2: self.c[o0] = ~(self.c[i0] & self.c[i1]) if op == SimPrim.BUF1: self.c[o0]=self.c[i0]
elif op == SimPrim.OR2: self.c[o0] = self.c[i0] | self.c[i1] elif op == SimPrim.INV1: self.c[o0] = ~self.c[i0]
elif op == SimPrim.NOR2: self.c[o0] = ~(self.c[i0] | self.c[i1]) elif op == SimPrim.AND2: 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.NAND2: self.c[o0] = ~(self.c[i0] & self.c[i1])
elif op == SimPrim.XNOR2: self.c[o0] = ~(self.c[i0] ^ self.c[i1]) elif op == SimPrim.OR2: self.c[o0] = self.c[i0] | self.c[i1]
else: print(f'unknown SimPrim {op}') elif op == SimPrim.NOR2: self.c[o0] = ~(self.c[i0] | self.c[i1])
if inject_cb is not None: inject_cb(o0, self.s[o0]) elif op == SimPrim.XOR2: self.c[o0] = self.c[i0] ^ self.c[i1]
pass 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: elif self.m == 4:
pass pass
else: else:
@ -285,4 +289,18 @@ class LogicSim(SimOps):
# def aoi21_fct(self, inputs, outputs): # def aoi21_fct(self, inputs, outputs):
# logic.bp_and(self.tmp[0], inputs[0], inputs[1]) # logic.bp_and(self.tmp[0], inputs[0], inputs[1])
# logic.bp_or(outputs[0], self.tmp[0], inputs[2]) # logic.bp_or(outputs[0], self.tmp[0], inputs[2])
# logic.bp_not(outputs[0], outputs[0]) # 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}')

37
src/kyupy/sim.py

@ -4,6 +4,43 @@ from bisect import bisect, insort_left
import numpy as np 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: class SimPrim:
BUF1 = 0b1010_1010_1010_1010 BUF1 = 0b1010_1010_1010_1010
INV1 = 0b0101_0101_0101_0101 INV1 = 0b0101_0101_0101_0101

Loading…
Cancel
Save