Browse Source

sim support for remaining primitives

devel
Stefan Holst 1 year ago
parent
commit
d921eb5048
  1. 82
      src/kyupy/logic_sim.py
  2. 8
      src/kyupy/sim.py

82
src/kyupy/logic_sim.py

@ -95,7 +95,15 @@ class LogicSim(sim.SimOps):
elif op == sim.XNOR2: self.c[o0] = ~(self.c[i0] ^ self.c[i1]) elif op == sim.XNOR2: self.c[o0] = ~(self.c[i0] ^ self.c[i1])
elif op == sim.XNOR3: self.c[o0] = ~(self.c[i0] ^ self.c[i1] ^ self.c[i2]) elif op == sim.XNOR3: self.c[o0] = ~(self.c[i0] ^ self.c[i1] ^ self.c[i2])
elif op == sim.XNOR4: self.c[o0] = ~(self.c[i0] ^ self.c[i1] ^ self.c[i2] ^ self.c[i3]) elif op == sim.XNOR4: self.c[o0] = ~(self.c[i0] ^ self.c[i1] ^ self.c[i2] ^ self.c[i3])
elif op == sim.AO21: self.c[o0] = (self.c[i0] & self.c[i1]) | self.c[i2]
elif op == sim.AOI21: self.c[o0] = ~((self.c[i0] & self.c[i1]) | self.c[i2]) elif op == sim.AOI21: self.c[o0] = ~((self.c[i0] & self.c[i1]) | self.c[i2])
elif op == sim.OA21: self.c[o0] = (self.c[i0] | self.c[i1]) & self.c[i2]
elif op == sim.OAI21: self.c[o0] = ~((self.c[i0] | self.c[i1]) & self.c[i2])
elif op == sim.AO22: self.c[o0] = (self.c[i0] & self.c[i1]) | (self.c[i2] & self.c[i3])
elif op == sim.AOI22: self.c[o0] = ~((self.c[i0] & self.c[i1]) | (self.c[i2] & self.c[i3]))
elif op == sim.OA22: self.c[o0] = (self.c[i0] | self.c[i1]) & (self.c[i2] | self.c[i3])
elif op == sim.OAI22: self.c[o0] = ~((self.c[i0] | self.c[i1]) & (self.c[i2] | self.c[i3]))
elif op == sim.MUX21: self.c[o0] = (self.c[i0] & ~self.c[i2]) | (self.c[i1] & self.c[i2])
else: print(f'unknown op {op}') else: print(f'unknown op {op}')
inject_cb(o0, self.s[o0]) inject_cb(o0, self.s[o0])
elif self.m == 4: elif self.m == 4:
@ -121,10 +129,43 @@ class LogicSim(sim.SimOps):
elif op == sim.XNOR2: logic.bp4v_xor(self.c[o0], self.c[i0], self.c[i1]); logic.bp4v_not(self.c[o0], self.c[o0]) elif op == sim.XNOR2: logic.bp4v_xor(self.c[o0], self.c[i0], self.c[i1]); logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.XNOR3: logic.bp4v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2]); logic.bp4v_not(self.c[o0], self.c[o0]) elif op == sim.XNOR3: logic.bp4v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2]); logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.XNOR4: logic.bp4v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2], self.c[i3]); logic.bp4v_not(self.c[o0], self.c[o0]) elif op == sim.XNOR4: logic.bp4v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2], self.c[i3]); logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.AO21:
logic.bp4v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
elif op == sim.AOI21: elif op == sim.AOI21:
logic.bp4v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1]) logic.bp4v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2]) logic.bp4v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
logic.bp4v_not(self.c[o0], self.c[o0]) logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.OA21:
logic.bp4v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
elif op == sim.OAI21:
logic.bp4v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.AO22:
logic.bp4v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_and(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp4v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
elif op == sim.AOI22:
logic.bp4v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_and(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp4v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.OA22:
logic.bp4v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_or(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp4v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
elif op == sim.OAI22:
logic.bp4v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp4v_or(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp4v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
logic.bp4v_not(self.c[o0], self.c[o0])
elif op == sim.MUX21:
logic.bp4v_not(self.c[self.c_locs[self.tmp2_idx]], self.c[i2])
logic.bp4v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[self.c_locs[self.tmp2_idx]])
logic.bp4v_and(self.c[self.c_locs[self.tmp2_idx]], self.c[i1], self.c[i2])
logic.bp4v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
else: print(f'unknown op {op}') else: print(f'unknown op {op}')
else: else:
for op, o0, i0, i1, i2, i3 in self.ops: for op, o0, i0, i1, i2, i3 in self.ops:
@ -149,10 +190,43 @@ class LogicSim(sim.SimOps):
elif op == sim.XNOR2: logic.bp8v_xor(self.c[o0], self.c[i0], self.c[i1]); logic.bp8v_not(self.c[o0], self.c[o0]) elif op == sim.XNOR2: logic.bp8v_xor(self.c[o0], self.c[i0], self.c[i1]); logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.XNOR3: logic.bp8v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2]); logic.bp8v_not(self.c[o0], self.c[o0]) elif op == sim.XNOR3: logic.bp8v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2]); logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.XNOR4: logic.bp8v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2], self.c[i3]); logic.bp8v_not(self.c[o0], self.c[o0]) elif op == sim.XNOR4: logic.bp8v_xor(self.c[o0], self.c[i0], self.c[i1], self.c[i2], self.c[i3]); logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.AO21:
logic.bp8v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
elif op == sim.AOI21: elif op == sim.AOI21:
logic.bp8v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1]) logic.bp8v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2]) logic.bp8v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
logic.bp8v_not(self.c[o0], self.c[o0]) logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.OA21:
logic.bp8v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
elif op == sim.OAI21:
logic.bp8v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[i2])
logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.AO22:
logic.bp8v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_and(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp8v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
elif op == sim.AOI22:
logic.bp8v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_and(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp8v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.OA22:
logic.bp8v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_or(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp8v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
elif op == sim.OAI22:
logic.bp8v_or(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[i1])
logic.bp8v_or(self.c[self.c_locs[self.tmp2_idx]], self.c[i2], self.c[i3])
logic.bp8v_and(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
logic.bp8v_not(self.c[o0], self.c[o0])
elif op == sim.MUX21:
logic.bp8v_not(self.c[self.c_locs[self.tmp2_idx]], self.c[i2])
logic.bp8v_and(self.c[self.c_locs[self.tmp_idx]], self.c[i0], self.c[self.c_locs[self.tmp2_idx]])
logic.bp8v_and(self.c[self.c_locs[self.tmp2_idx]], self.c[i1], self.c[i2])
logic.bp8v_or(self.c[o0], self.c[self.c_locs[self.tmp_idx]], self.c[self.c_locs[self.tmp2_idx]])
else: print(f'unknown op {op}') else: print(f'unknown op {op}')
if inject_cb is not None: inject_cb(o0, self.s[o0]) if inject_cb is not None: inject_cb(o0, self.s[o0])
@ -211,5 +285,13 @@ def _prop_cpu(ops, c_locs, c):
elif op == sim.XNOR2: c[o0] = ~(c[i0] ^ c[i1]) elif op == sim.XNOR2: c[o0] = ~(c[i0] ^ c[i1])
elif op == sim.XNOR3: c[o0] = ~(c[i0] ^ c[i1] ^ c[i2]) elif op == sim.XNOR3: c[o0] = ~(c[i0] ^ c[i1] ^ c[i2])
elif op == sim.XNOR4: c[o0] = ~(c[i0] ^ c[i1] ^ c[i2] ^ c[i3]) elif op == sim.XNOR4: c[o0] = ~(c[i0] ^ c[i1] ^ c[i2] ^ c[i3])
elif op == sim.AO21: c[o0] = (c[i0] & c[i1]) | c[i2]
elif op == sim.AOI21: c[o0] = ~((c[i0] & c[i1]) | c[i2]) elif op == sim.AOI21: c[o0] = ~((c[i0] & c[i1]) | c[i2])
elif op == sim.OA21: c[o0] = (c[i0] | c[i1]) & c[i2]
elif op == sim.OAI21: c[o0] = ~((c[i0] | c[i1]) & c[i2])
elif op == sim.AO22: c[o0] = (c[i0] & c[i1]) | (c[i2] & c[i3])
elif op == sim.AOI22: c[o0] = ~((c[i0] & c[i1]) | (c[i2] & c[i3]))
elif op == sim.OA22: c[o0] = (c[i0] | c[i1]) & (c[i2] | c[i3])
elif op == sim.OAI22: c[o0] = ~((c[i0] | c[i1]) & (c[i2] | c[i3]))
elif op == sim.MUX21: c[o0] = (c[i0] & ~c[i2]) | (c[i1] & c[i2])
else: print(f'unknown op {op}') else: print(f'unknown op {op}')

8
src/kyupy/sim.py

@ -41,6 +41,7 @@ kind_prefixes = {
'nor': (NOR4, NOR3, NOR2), 'nor': (NOR4, NOR3, NOR2),
'and': (AND4, AND3, AND2), 'and': (AND4, AND3, AND2),
'or': (OR4, OR3, OR2), 'or': (OR4, OR3, OR2),
'isolor': (OR2, OR2, OR2),
'xor': (XOR4, XOR3, XOR2), 'xor': (XOR4, XOR3, XOR2),
'xnor': (XNOR4, XNOR3, XNOR2), 'xnor': (XNOR4, XNOR3, XNOR2),
@ -155,7 +156,8 @@ class SimOps:
# special locations and offsets in c_locs/c_caps # special locations and offsets in c_locs/c_caps
self.zero_idx = len(circuit.lines) self.zero_idx = len(circuit.lines)
self.tmp_idx = self.zero_idx + 1 self.tmp_idx = self.zero_idx + 1
self.ppi_offset = self.tmp_idx + 1 self.tmp2_idx = self.tmp_idx + 1
self.ppi_offset = self.tmp2_idx + 1
self.ppo_offset = self.ppi_offset + self.s_len self.ppo_offset = self.ppi_offset + self.s_len
self.c_locs_len = self.ppo_offset + self.s_len self.c_locs_len = self.ppo_offset + self.s_len
@ -198,7 +200,7 @@ class SimOps:
sp = prims[2] sp = prims[2]
break break
if sp is None: if sp is None:
print('unknown gate type', kind) print('unknown cell type', kind)
else: else:
ops.append((sp, o0_idx, i0_idx, i1_idx, i2_idx, i3_idx)) ops.append((sp, o0_idx, i0_idx, i1_idx, i2_idx, i3_idx))
@ -246,8 +248,10 @@ class SimOps:
# allocate and keep memory for special fields # allocate and keep memory for special fields
self.c_locs[self.zero_idx], self.c_caps[self.zero_idx] = h.alloc(c_caps_min), c_caps_min self.c_locs[self.zero_idx], self.c_caps[self.zero_idx] = h.alloc(c_caps_min), c_caps_min
self.c_locs[self.tmp_idx], self.c_caps[self.tmp_idx] = h.alloc(c_caps_min), c_caps_min self.c_locs[self.tmp_idx], self.c_caps[self.tmp_idx] = h.alloc(c_caps_min), c_caps_min
self.c_locs[self.tmp2_idx], self.c_caps[self.tmp2_idx] = h.alloc(c_caps_min), c_caps_min
ref_count[self.zero_idx] += 1 ref_count[self.zero_idx] += 1
ref_count[self.tmp_idx] += 1 ref_count[self.tmp_idx] += 1
ref_count[self.tmp2_idx] += 1
# allocate and keep memory for PI/PPI, keep memory for PO/PPO (allocated later) # allocate and keep memory for PI/PPI, keep memory for PO/PPO (allocated later)
for i, n in enumerate(circuit.s_nodes): for i, n in enumerate(circuit.s_nodes):

Loading…
Cancel
Save