diff --git a/src/kyupy/logic_sim.py b/src/kyupy/logic_sim.py index 6a3ce94..92150fa 100644 --- a/src/kyupy/logic_sim.py +++ b/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.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.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.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}') inject_cb(o0, self.s[o0]) 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.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.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: 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_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: 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.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.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: 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_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}') 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.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.AO21: 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}') diff --git a/src/kyupy/sim.py b/src/kyupy/sim.py index fc9d287..bd9a549 100644 --- a/src/kyupy/sim.py +++ b/src/kyupy/sim.py @@ -41,6 +41,7 @@ kind_prefixes = { 'nor': (NOR4, NOR3, NOR2), 'and': (AND4, AND3, AND2), 'or': (OR4, OR3, OR2), + 'isolor': (OR2, OR2, OR2), 'xor': (XOR4, XOR3, XOR2), 'xnor': (XNOR4, XNOR3, XNOR2), @@ -155,7 +156,8 @@ class SimOps: # special locations and offsets in c_locs/c_caps self.zero_idx = len(circuit.lines) 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.c_locs_len = self.ppo_offset + self.s_len @@ -198,7 +200,7 @@ class SimOps: sp = prims[2] break if sp is None: - print('unknown gate type', kind) + print('unknown cell type', kind) else: 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 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.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.tmp_idx] += 1 + ref_count[self.tmp2_idx] += 1 # allocate and keep memory for PI/PPI, keep memory for PO/PPO (allocated later) for i, n in enumerate(circuit.s_nodes):