Browse Source

simple incremental sim using dirty flags

devel
stefan 3 days ago
parent
commit
53309f9e59
  1. 2
      src/kyupy/__init__.py
  2. 22
      src/kyupy/logic_sim.py

2
src/kyupy/__init__.py

@ -111,7 +111,7 @@ class Timer:
class Timers: class Timers:
def __init__(self, t={}): self.timers = defaultdict(Timer) | t def __init__(self, t={}): self.timers: dict[str, Timer] = defaultdict(Timer) | t
def __getitem__(self, name): return self.timers[name] def __getitem__(self, name): return self.timers[name]
def __repr__(self): return '{' + ', '.join([f'{k}: {v}' for k, v in self.timers.items()]) + '}' def __repr__(self): return '{' + ', '.join([f'{k}: {v}' for k, v in self.timers.items()]) + '}'
def __add__(self, t): def __add__(self, t):

22
src/kyupy/logic_sim.py

@ -356,6 +356,19 @@ class LogicSim2V(sim.SimOps):
Storage locations are indirectly addressed. Storage locations are indirectly addressed.
Data for line `l` is in `self.c[self.c_locs[l]]`. Data for line `l` is in `self.c[self.c_locs[l]]`.
""" """
self.c_dirty = np.full(self.c_len, 1, dtype=np.uint8)
"""Marker for logic values that have changed recently for use in incremental simulation.
A node n will be evaluated by `c_prop()` if and only if at least one of its inputs is marked dirty (`c_dirty[c_locs[n.ins[i]]] == 1`).
If a node is evaluated, its output is marked dirty.
By default, this array is all-1, therefore every node is evaluated every time by `c_prop()`.
Enable incremental simulation by setting this array to all-0, change signal values in `c` and set `c_dirty` to 1 for all changed signals.
Next call to `c_prop()` will only evaluate nodes that read from the changed signals.
To restore the original simulation state, revert the signal value changes in `c`, and call `c_prop()` again.
Caveats:
- Injected changes that are located downstream of other changes will have no effect.
- Only works with `c_reuse=False` (default).
"""
self.s_assign = np.zeros((self.s_len, self.sims), dtype=np.uint8) self.s_assign = np.zeros((self.s_len, self.sims), dtype=np.uint8)
"""Logic values assigned to the ports and flip-flops of the circuit. """Logic values assigned to the ports and flip-flops of the circuit.
@ -390,7 +403,7 @@ class LogicSim2V(sim.SimOps):
fault_mask2 = np.full(self.c.shape[-1], 0, dtype=np.uint8) fault_mask2 = np.full(self.c.shape[-1], 0, dtype=np.uint8)
fault_mask2[:len(fault_mask)] = fault_mask fault_mask2[:len(fault_mask)] = fault_mask
fault_mask = fault_mask2 fault_mask = fault_mask2
c_prop_2v_cpu(self.ops, self.c_locs, self.c, int(fault_line), fault_mask, int(fault_model)) c_prop_2v_cpu(self.ops, self.c_locs, self.c, self.c_dirty, int(fault_line), fault_mask, int(fault_model))
def c_to_s(self): def c_to_s(self):
"""Captures the results of the combinational portion into ``self.s_result``. """Captures the results of the combinational portion into ``self.s_result``.
@ -424,9 +437,11 @@ class LogicSim2V(sim.SimOps):
@numba.njit @numba.njit
def c_prop_2v_cpu(ops, c_locs, c, fault_line, fault_mask, fault_model): def c_prop_2v_cpu(ops, c_locs, c, c_dirty, fault_line, fault_mask, fault_model):
for op, o0l, i0l, i1l, i2l, i3l in ops[:,:6]: for op, o0l, i0l, i1l, i2l, i3l in ops[:,:6]:
o0, i0, i1, i2, i3 = [c_locs[x] for x in (o0l, i0l, i1l, i2l, i3l)] o0, i0, i1, i2, i3 = [c_locs[x] for x in (o0l, i0l, i1l, i2l, i3l)]
if fault_line < 0 or o0l != fault_line: # fault injection forces node evaluation
if not (c_dirty[i0] | c_dirty[i1] | c_dirty[i2] | c_dirty[i3]): continue
if op == sim.BUF1: c[o0]=c[i0] if op == sim.BUF1: c[o0]=c[i0]
elif op == sim.INV1: 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.AND2: c[o0] = c[i0] & c[i1]
@ -466,8 +481,9 @@ def c_prop_2v_cpu(ops, c_locs, c, fault_line, fault_mask, fault_model):
c[o0] = c[o0] & ~fault_mask c[o0] = c[o0] & ~fault_mask
elif fault_model == 1: elif fault_model == 1:
c[o0] = c[o0] | fault_mask c[o0] = c[o0] | fault_mask
else: elif fault_model == 2:
c[o0] = c[o0] ^ fault_mask c[o0] = c[o0] ^ fault_mask
c_dirty[o0] = 1
class LogicSim4V(sim.SimOps): class LogicSim4V(sim.SimOps):

Loading…
Cancel
Save