LogicSim clean-up and new fault injection facility. version bump.
This commit is contained in:
1 parent
7501613951
commit
0bad95e94e
2 files changed
+43
-135
No files matched your search
@@ -5,9 +5,10 @@ with open('README.rst', 'r') as f:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='kyupy',
|
name='kyupy',
|
||||||
version='0.0.2',
|
version='0.0.3',
|
||||||
description='High-performance processing and analysis of non-hierarchical VLSI designs',
|
description='High-performance processing and analysis of non-hierarchical VLSI designs',
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
|
long_description_content_type='text/x-rst',
|
||||||
packages=find_packages(where='src'),
|
packages=find_packages(where='src'),
|
||||||
package_dir={'': 'src'},
|
package_dir={'': 'src'},
|
||||||
url='https://github.com/s-holst/kyupy',
|
url='https://github.com/s-holst/kyupy',
|
||||||
|
|||||||
+41
-134
@@ -22,40 +22,19 @@ class LogicSim:
|
|||||||
self.zero = np.zeros((mdim, nbytes), dtype='uint8')
|
self.zero = np.zeros((mdim, nbytes), dtype='uint8')
|
||||||
self.epoch = 0
|
self.epoch = 0
|
||||||
|
|
||||||
self.fork_vd1 = self.fork_vdx
|
known_fct = [(f[:-4], getattr(self, f)) for f in dir(self) if f.endswith(f'_fct')]
|
||||||
self.const0_vd1 = self.const0_vdx
|
|
||||||
self.input_vd1 = self.fork_vd1
|
|
||||||
self.output_vd1 = self.fork_vd1
|
|
||||||
self.inv_vd1 = self.not_vd1
|
|
||||||
self.ibuff_vd1 = self.not_vd1
|
|
||||||
self.nbuff_vd1 = self.fork_vd1
|
|
||||||
self.xor2_vd1 = self.xor_vd1
|
|
||||||
|
|
||||||
self.fork_vd2 = self.fork_vdx
|
|
||||||
self.const0_vd2 = self.const0_vdx
|
|
||||||
self.input_vd2 = self.fork_vd2
|
|
||||||
self.output_vd2 = self.fork_vd2
|
|
||||||
self.inv_vd2 = self.not_vd2
|
|
||||||
self.ibuff_vd2 = self.not_vd2
|
|
||||||
self.nbuff_vd2 = self.fork_vd2
|
|
||||||
self.xor2_vd2 = self.xor_vd2
|
|
||||||
|
|
||||||
self.fork_vd3 = self.fork_vdx
|
|
||||||
self.const0_vd3 = self.const0_vdx
|
|
||||||
self.input_vd3 = self.fork_vd3
|
|
||||||
self.output_vd3 = self.fork_vd3
|
|
||||||
self.inv_vd3 = self.not_vd3
|
|
||||||
self.ibuff_vd3 = self.not_vd3
|
|
||||||
self.nbuff_vd3 = self.fork_vd3
|
|
||||||
self.xor2_vd3 = self.xor_vd3
|
|
||||||
|
|
||||||
known_fct = [(f[:-4], getattr(self, f)) for f in dir(self) if f.endswith(f'_vd{mdim}')]
|
|
||||||
self.node_fct = []
|
self.node_fct = []
|
||||||
for n in circuit.nodes:
|
for n in circuit.nodes:
|
||||||
t = n.kind.lower().replace('__fork__', 'fork')
|
t = n.kind.lower().replace('__fork__', 'fork')
|
||||||
|
t = t.replace('nbuff', 'fork')
|
||||||
|
t = t.replace('input', 'fork')
|
||||||
|
t = t.replace('output', 'fork')
|
||||||
t = t.replace('__const0__', 'const0')
|
t = t.replace('__const0__', 'const0')
|
||||||
t = t.replace('__const1__', 'const1')
|
t = t.replace('__const1__', 'const1')
|
||||||
t = t.replace('tieh', 'const1')
|
t = t.replace('tieh', 'const1')
|
||||||
|
t = t.replace('ibuff', 'not')
|
||||||
|
t = t.replace('inv', 'not')
|
||||||
|
|
||||||
fcts = [f for n, f in known_fct if t.startswith(n)]
|
fcts = [f for n, f in known_fct if t.startswith(n)]
|
||||||
if len(fcts) < 1:
|
if len(fcts) < 1:
|
||||||
raise ValueError(f'Unknown node kind {n.kind}')
|
raise ValueError(f'Unknown node kind {n.kind}')
|
||||||
@@ -90,7 +69,7 @@ class LogicSim:
|
|||||||
resp[...] = self.state[node.ins[0].index]
|
resp[...] = self.state[node.ins[0].index]
|
||||||
# print(responses)
|
# print(responses)
|
||||||
|
|
||||||
def propagate(self):
|
def propagate(self, inject_cb=None):
|
||||||
"""Propagate the input values towards the outputs (Perform all logic operations in topological order)."""
|
"""Propagate the input values towards the outputs (Perform all logic operations in topological order)."""
|
||||||
for node in self.circuit.topological_order():
|
for node in self.circuit.topological_order():
|
||||||
if self.state_epoch[node.index] != self.epoch: continue
|
if self.state_epoch[node.index] != self.epoch: continue
|
||||||
@@ -99,133 +78,61 @@ class LogicSim:
|
|||||||
# print('sim', node)
|
# print('sim', node)
|
||||||
self.node_fct[node.index](inputs, outputs)
|
self.node_fct[node.index](inputs, outputs)
|
||||||
for line in node.outs:
|
for line in node.outs:
|
||||||
|
if inject_cb is not None: inject_cb(line.index, self.state[line.index])
|
||||||
self.state_epoch[line.reader.index] = self.epoch
|
self.state_epoch[line.reader.index] = self.epoch
|
||||||
self.epoch = (self.epoch + 1) % 128
|
self.epoch = (self.epoch + 1) % 128
|
||||||
|
|
||||||
def fork_vdx(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def fork_fct(inputs, outputs):
|
||||||
for o in outputs: o[...] = inputs[0]
|
for o in outputs: o[...] = inputs[0]
|
||||||
|
|
||||||
def const0_vdx(self, _, outputs):
|
|
||||||
for o in outputs: o[...] = self.zero
|
|
||||||
|
|
||||||
# 2-valued simulation
|
@staticmethod
|
||||||
|
def const0_fct(_, outputs):
|
||||||
|
for o in outputs: o[...] = 0
|
||||||
|
|
||||||
def not_vd1(self, inputs, outputs):
|
@staticmethod
|
||||||
outputs[0][0] = ~inputs[0][0]
|
def const1_fct(_, outputs):
|
||||||
|
for o in outputs:
|
||||||
|
o[...] = 0
|
||||||
|
logic.bp_not(o, o)
|
||||||
|
|
||||||
def const1_vd1(self, _, outputs):
|
@staticmethod
|
||||||
for o in outputs: o[...] = self.zero
|
def not_fct(inputs, outputs):
|
||||||
self.not_vd1(outputs, outputs)
|
|
||||||
|
|
||||||
def and_vd1(self, inputs, outputs):
|
|
||||||
o = outputs[0]
|
|
||||||
o[0] = inputs[0][0]
|
|
||||||
for i in inputs[1:]: o[0] &= i[0]
|
|
||||||
|
|
||||||
def or_vd1(self, inputs, outputs):
|
|
||||||
o = outputs[0]
|
|
||||||
o[0] = inputs[0][0]
|
|
||||||
for i in inputs[1:]: o[0] |= i[0]
|
|
||||||
|
|
||||||
def xor_vd1(self, inputs, outputs):
|
|
||||||
o = outputs[0]
|
|
||||||
o[0] = inputs[0][0]
|
|
||||||
for i in inputs[1:]: o[0] ^= i[0]
|
|
||||||
|
|
||||||
def sdff_vd1(self, inputs, outputs):
|
|
||||||
outputs[0][0] = inputs[0][0]
|
|
||||||
if len(outputs) > 1:
|
|
||||||
outputs[1][0] = ~inputs[0][0]
|
|
||||||
|
|
||||||
def dff_vd1(self, inputs, outputs):
|
|
||||||
outputs[0][0] = inputs[0][0]
|
|
||||||
if len(outputs) > 1:
|
|
||||||
outputs[1][0] = ~inputs[0][0]
|
|
||||||
|
|
||||||
def nand_vd1(self, inputs, outputs):
|
|
||||||
self.and_vd1(inputs, outputs)
|
|
||||||
self.not_vd1(outputs, outputs)
|
|
||||||
|
|
||||||
def nor_vd1(self, inputs, outputs):
|
|
||||||
self.or_vd1(inputs, outputs)
|
|
||||||
self.not_vd1(outputs, outputs)
|
|
||||||
|
|
||||||
def xnor_vd1(self, inputs, outputs):
|
|
||||||
self.xor_vd1(inputs, outputs)
|
|
||||||
self.not_vd1(outputs, outputs)
|
|
||||||
|
|
||||||
# 4-valued simulation
|
|
||||||
|
|
||||||
def not_vd2(self, inputs, outputs):
|
|
||||||
logic.bp_not(outputs[0], inputs[0])
|
logic.bp_not(outputs[0], inputs[0])
|
||||||
|
|
||||||
def and_vd2(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def and_fct(inputs, outputs):
|
||||||
logic.bp_and(outputs[0], *inputs)
|
logic.bp_and(outputs[0], *inputs)
|
||||||
|
|
||||||
def or_vd2(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def or_fct(inputs, outputs):
|
||||||
logic.bp_or(outputs[0], *inputs)
|
logic.bp_or(outputs[0], *inputs)
|
||||||
|
|
||||||
def xor_vd2(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def xor_fct(inputs, outputs):
|
||||||
logic.bp_xor(outputs[0], *inputs)
|
logic.bp_xor(outputs[0], *inputs)
|
||||||
|
|
||||||
def sdff_vd2(self, inputs, outputs):
|
@staticmethod
|
||||||
self.dff_vd2(inputs, outputs)
|
def sdff_fct(inputs, outputs):
|
||||||
|
logic.bp_buf(outputs[0], inputs[0])
|
||||||
if len(outputs) > 1:
|
if len(outputs) > 1:
|
||||||
logic.bp_not(outputs[1], inputs[0])
|
logic.bp_not(outputs[1], inputs[0])
|
||||||
|
|
||||||
def dff_vd2(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def dff_fct(inputs, outputs):
|
||||||
logic.bp_buf(outputs[0], inputs[0])
|
logic.bp_buf(outputs[0], inputs[0])
|
||||||
|
|
||||||
def nand_vd2(self, inputs, outputs):
|
@staticmethod
|
||||||
self.and_vd2(inputs, outputs)
|
def nand_fct(inputs, outputs):
|
||||||
self.not_vd2(outputs, outputs)
|
|
||||||
|
|
||||||
def nor_vd2(self, inputs, outputs):
|
|
||||||
self.or_vd2(inputs, outputs)
|
|
||||||
self.not_vd2(outputs, outputs)
|
|
||||||
|
|
||||||
def xnor_vd2(self, inputs, outputs):
|
|
||||||
self.xor_vd2(inputs, outputs)
|
|
||||||
self.not_vd2(outputs, outputs)
|
|
||||||
|
|
||||||
def const1_vd2(self, _, outputs):
|
|
||||||
for o in outputs: o[...] = self.zero
|
|
||||||
self.not_vd2(outputs, outputs)
|
|
||||||
|
|
||||||
# 8-valued simulation
|
|
||||||
|
|
||||||
def not_vd3(self, inputs, outputs):
|
|
||||||
logic.bp_not(outputs[0], inputs[0])
|
|
||||||
|
|
||||||
def and_vd3(self, inputs, outputs):
|
|
||||||
logic.bp_and(outputs[0], *inputs)
|
logic.bp_and(outputs[0], *inputs)
|
||||||
|
logic.bp_not(outputs[0], outputs[0])
|
||||||
|
|
||||||
def or_vd3(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def nor_fct(inputs, outputs):
|
||||||
logic.bp_or(outputs[0], *inputs)
|
logic.bp_or(outputs[0], *inputs)
|
||||||
|
logic.bp_not(outputs[0], outputs[0])
|
||||||
|
|
||||||
def xor_vd3(self, inputs, outputs):
|
@staticmethod
|
||||||
|
def xnor_fct(inputs, outputs):
|
||||||
logic.bp_xor(outputs[0], *inputs)
|
logic.bp_xor(outputs[0], *inputs)
|
||||||
|
logic.bp_not(outputs[0], outputs[0])
|
||||||
def sdff_vd3(self, inputs, outputs):
|
|
||||||
self.dff_vd3(inputs, outputs)
|
|
||||||
if len(outputs) > 1:
|
|
||||||
logic.bp_not(outputs[1], inputs[0])
|
|
||||||
|
|
||||||
def dff_vd3(self, inputs, outputs):
|
|
||||||
logic.bp_buf(outputs[0], inputs[0])
|
|
||||||
|
|
||||||
def nand_vd3(self, inputs, outputs):
|
|
||||||
self.and_vd3(inputs, outputs)
|
|
||||||
self.not_vd3(outputs, outputs)
|
|
||||||
|
|
||||||
def nor_vd3(self, inputs, outputs):
|
|
||||||
self.or_vd3(inputs, outputs)
|
|
||||||
self.not_vd3(outputs, outputs)
|
|
||||||
|
|
||||||
def xnor_vd3(self, inputs, outputs):
|
|
||||||
self.xor_vd3(inputs, outputs)
|
|
||||||
self.not_vd3(outputs, outputs)
|
|
||||||
|
|
||||||
def const1_vd3(self, _, outputs):
|
|
||||||
for o in outputs: o[...] = self.zero
|
|
||||||
self.not_vd3(outputs, outputs)
|
|
||||||
Reference in new issue
Block a user