fault injection for 4v sim, wave_sim test fix
This commit is contained in:
1 parent
0cdaf71963
commit
9ca437fe47
3 files changed
+63
-12
No files matched your search
+20
-9
@@ -43,6 +43,7 @@ class LogicSim(sim.SimOps):
|
||||
Access this array to assign new values to the (P)PIs or read values from the (P)POs.
|
||||
"""
|
||||
self.s[:,:,1,:] = 255 # unassigned
|
||||
self._full_mask = np.full(self.c.shape[-1], 255, dtype=np.uint8)
|
||||
|
||||
def __repr__(self):
|
||||
return f'{{name: "{self.circuit.name}", sims: {self.sims}, m: {self.m}, c_bytes: {eng(self.c.nbytes)}}}'
|
||||
@@ -61,20 +62,22 @@ class LogicSim(sim.SimOps):
|
||||
:param inject_cb: A callback function for manipulating intermediate signal values.
|
||||
This function is called with a line and its new logic values (in bit-parallel format) after
|
||||
evaluation of a node. The callback may manipulate the given values in-place, the simulation
|
||||
resumes with the manipulated values after the callback returns.
|
||||
resumes with the manipulated values after the callback returns. Specifying this callback
|
||||
may reduce performance as it disables jit compilation.
|
||||
:type inject_cb: ``f(Line, ndarray)``
|
||||
"""
|
||||
fault_line = int(fault_line)
|
||||
if fault_mask is None:
|
||||
fault_mask = self._full_mask # default: full mask
|
||||
else:
|
||||
if len(fault_mask) < self.c.shape[-1]: # pad mask with 0's if necessary
|
||||
fault_mask2 = np.full(self.c.shape[-1], 0, dtype=np.uint8)
|
||||
fault_mask2[:len(fault_mask)] = fault_mask
|
||||
fault_mask = fault_mask2
|
||||
t0 = self.c_locs[self.tmp_idx]
|
||||
t1 = self.c_locs[self.tmp2_idx]
|
||||
if self.m == 2:
|
||||
if inject_cb is None:
|
||||
if fault_mask is None:
|
||||
fault_mask = np.full(self.c.shape[-1], 255, dtype=np.uint8)
|
||||
else:
|
||||
if len(fault_mask) < self.c.shape[-1]:
|
||||
fault_mask2 = np.full(self.c.shape[-1], 0, dtype=np.uint8)
|
||||
fault_mask2[:len(fault_mask)] = fault_mask
|
||||
fault_mask = fault_mask2
|
||||
_prop_cpu(self.ops, self.c_locs, self.c, int(fault_line), fault_mask, int(fault_model))
|
||||
else:
|
||||
for op, o0l, i0l, i1l, i2l, i3l in self.ops[:,:6]:
|
||||
@@ -190,6 +193,15 @@ class LogicSim(sim.SimOps):
|
||||
logic.bp4v_or(self.c[o0], self.c[t0], self.c[t1])
|
||||
else: print(f'unknown op {op}')
|
||||
if inject_cb is not None: inject_cb(o0l, self.c[o0])
|
||||
if fault_line >= 0 and o0l == fault_line:
|
||||
if fault_model == 0:
|
||||
self.c[o0] = self.c[o0] & ~fault_mask[np.newaxis]
|
||||
elif fault_model == 1:
|
||||
self.c[o0] = self.c[o0] | fault_mask[np.newaxis]
|
||||
else:
|
||||
self.c[t0, 0] = ~(self.c[o0, 0] & self.c[o0, 1] & fault_mask)
|
||||
self.c[o0, 1] = ~self.c[o0, 0] & ~self.c[o0, 1] & fault_mask
|
||||
self.c[o0, 0] = self.c[t0, 0]
|
||||
else:
|
||||
for op, o0l, i0l, i1l, i2l, i3l in self.ops[:,:6]:
|
||||
o0, i0, i1, i2, i3 = [self.c_locs[x] for x in (o0l, i0l, i1l, i2l, i3l)]
|
||||
@@ -343,7 +355,6 @@ def _prop_cpu(ops, c_locs, c, fault_line, fault_mask, fault_model):
|
||||
elif op == sim.MUX21: c[o0] = (c[i0] & ~c[i2]) | (c[i1] & c[i2])
|
||||
else: print(f'unknown op {op}')
|
||||
if fault_line >= 0 and o0l == fault_line:
|
||||
#n = len(fault_mask)
|
||||
if fault_model == 0:
|
||||
c[o0] = c[o0] & ~fault_mask
|
||||
elif fault_model == 1:
|
||||
|
||||
+39
-1
@@ -75,7 +75,7 @@ def test_2v():
|
||||
|
||||
def test_4v():
|
||||
c = bench.parse('input(x, y) output(a, o, n) a=and(x,y) o=or(x,y) n=not(x)')
|
||||
s = LogicSim(c, 16, m=8) # FIXME: m=4
|
||||
s = LogicSim(c, 16, m=4)
|
||||
assert s.s_len == 5
|
||||
bpa = bparray(
|
||||
'00---', '01---', '0----', '0X---',
|
||||
@@ -93,6 +93,44 @@ def test_4v():
|
||||
'--0XX', '--X1X', '--XXX', '--XXX',
|
||||
'--0XX', '--X1X', '--XXX', '--XXX'))
|
||||
|
||||
def test_4v_fault():
|
||||
c = bench.parse('input(x, y) output(a) a=and(x,y)')
|
||||
s = LogicSim(c, 16, m=4)
|
||||
assert s.s_len == 3
|
||||
bpa = bparray(
|
||||
'00-', '01-', '0--', '0X-',
|
||||
'10-', '11-', '1--', '1X-',
|
||||
'-0-', '-1-', '---', '-X-',
|
||||
'X0-', 'X1-', 'X--', 'XX-')
|
||||
s.s[0] = bpa
|
||||
s.s_to_c()
|
||||
s.c_prop()
|
||||
s.c_to_s()
|
||||
mva = bp_to_mv(s.s[1])
|
||||
assert_equal_shape_and_contents(mva, mvarray(
|
||||
'--0', '--0', '--0', '--0',
|
||||
'--0', '--1', '--X', '--X',
|
||||
'--0', '--X', '--X', '--X',
|
||||
'--0', '--X', '--X', '--X'))
|
||||
fault_line = s.circuit.cells['a'].ins[0]
|
||||
s.s_to_c()
|
||||
s.c_prop(fault_line=fault_line, fault_model=1)
|
||||
s.c_to_s()
|
||||
mva = bp_to_mv(s.s[1])
|
||||
assert_equal_shape_and_contents(mva, mvarray(
|
||||
'--0', '--1', '--X', '--X',
|
||||
'--0', '--1', '--X', '--X',
|
||||
'--0', '--1', '--X', '--X',
|
||||
'--0', '--1', '--X', '--X'))
|
||||
s.s_to_c()
|
||||
s.c_prop(fault_line=fault_line, fault_model=0)
|
||||
s.c_to_s()
|
||||
mva = bp_to_mv(s.s[1])
|
||||
assert_equal_shape_and_contents(mva, mvarray(
|
||||
'--0', '--0', '--0', '--0',
|
||||
'--0', '--0', '--0', '--0',
|
||||
'--0', '--0', '--0', '--0',
|
||||
'--0', '--0', '--0', '--0'))
|
||||
|
||||
def test_6v():
|
||||
c = bench.parse('input(x, y) output(a, o, n, xo, no) a=AND2(x,y) o=OR2(x,y) n=INV1(x) xo=XOR2(x,y) no=NOR2(x,y)')
|
||||
|
||||
@@ -25,10 +25,11 @@ def test_xnor2_delays():
|
||||
delays[0, 1, 1, 1] = 0.036 # B fall -> Z fall
|
||||
|
||||
simctl_int = np.asarray([0], dtype=np.int32)
|
||||
simctl_float = np.asarray([1], dtype=np.float32)
|
||||
|
||||
def wave_assert(inputs, output):
|
||||
for i, a in zip(inputs, c.reshape(-1,16)): a[:len(i)] = i
|
||||
wave_eval_cpu(op, c, c_locs, c_caps, ebuf, 0, delays, simctl_int, 0, 0)
|
||||
wave_eval_cpu(op, c, c_locs, c_caps, ebuf, 0, delays, simctl_int, simctl_float, 0, 0)
|
||||
for i, v in enumerate(output): np.testing.assert_allclose(c.reshape(-1,16)[2,i], v)
|
||||
|
||||
wave_assert([[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # XNOR(1,1) => 1
|
||||
@@ -63,10 +64,11 @@ def test_nand_delays():
|
||||
delays[0, 3, :, 1] = 0.8
|
||||
|
||||
simctl_int = np.asarray([0], dtype=np.int32)
|
||||
simctl_float = np.asarray([1], dtype=np.float32)
|
||||
|
||||
def wave_assert(inputs, output):
|
||||
for i, a in zip(inputs, c.reshape(-1,16)): a[:len(i)] = i
|
||||
wave_eval_cpu(op, c, c_locs, c_caps, ebuf, 0, delays, simctl_int, 0, 0)
|
||||
wave_eval_cpu(op, c, c_locs, c_caps, ebuf, 0, delays, simctl_int, simctl_float, 0, 0)
|
||||
for i, v in enumerate(output): np.testing.assert_allclose(c.reshape(-1,16)[4,i], v)
|
||||
|
||||
wave_assert([[TMAX,TMAX],[TMAX,TMAX],[TMIN,TMAX],[TMIN,TMAX]], [TMIN,TMAX]) # NAND(0,0,1,1) => 1
|
||||
|
||||
Reference in new issue
Block a user