|
|
|
|
@ -356,6 +356,19 @@ class LogicSim2V(sim.SimOps):
@@ -356,6 +356,19 @@ class LogicSim2V(sim.SimOps):
|
|
|
|
|
Storage locations are indirectly addressed. |
|
|
|
|
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) |
|
|
|
|
"""Logic values assigned to the ports and flip-flops of the circuit. |
|
|
|
|
|
|
|
|
|
@ -390,7 +403,7 @@ class LogicSim2V(sim.SimOps):
@@ -390,7 +403,7 @@ class LogicSim2V(sim.SimOps):
|
|
|
|
|
fault_mask2 = np.full(self.c.shape[-1], 0, dtype=np.uint8) |
|
|
|
|
fault_mask2[:len(fault_mask)] = fault_mask |
|
|
|
|
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): |
|
|
|
|
"""Captures the results of the combinational portion into ``self.s_result``. |
|
|
|
|
@ -424,9 +437,11 @@ class LogicSim2V(sim.SimOps):
@@ -424,9 +437,11 @@ class LogicSim2V(sim.SimOps):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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]: |
|
|
|
|
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] |
|
|
|
|
elif op == sim.INV1: c[o0] = ~c[i0] |
|
|
|
|
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):
@@ -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 |
|
|
|
|
elif fault_model == 1: |
|
|
|
|
c[o0] = c[o0] | fault_mask |
|
|
|
|
else: |
|
|
|
|
elif fault_model == 2: |
|
|
|
|
c[o0] = c[o0] ^ fault_mask |
|
|
|
|
c_dirty[o0] = 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LogicSim4V(sim.SimOps): |
|
|
|
|
|