fault.test_vectors
module
Source code
from magma import BitKind, ArrayKind, SIntKind, UIntKind, BitsKind
from magma.simulator.python_simulator import PythonSimulator
from hwtypes import BitVector, SIntVector, UIntVector
from inspect import signature
from itertools import product
import pytest
import fault
class TestVector:
__test__ = False
def __init__(self, test_vector):
self.test_vector = test_vector
def __eq__(self, other):
if not isinstance(other, TestVector):
raise ValueError("Expected another TestVector for __eq__")
for x, y in zip(self, other):
if x is fault.AnyValue or y is fault.AnyValue:
continue
if x != y:
return False
return True
def __len__(self):
return len(self.test_vector)
def __iter__(self):
return iter(self.test_vector)
def __str__(self):
return str(self.test_vector)
def __repr__(self):
return repr(self.test_vector)
# check that number of function arguments equals number of circuit inputs
def check(circuit, func):
sig = signature(func)
nfuncargs = len(sig.parameters)
# count circuit inputs
ncircargs = 0
for name, port in circuit.IO.items():
if port.isinput():
ncircargs += 1
assert nfuncargs == ncircargs
def flatten_tests(tests):
flattened_tests = []
for i in range(len(tests)):
flattened_tests.append(tests[i][0][:])
if i == 0:
flattened_tests[-1].extend(
[fault.AnyValue for _ in range(len(tests[i][1]))])
else:
flattened_tests[-1].extend(tests[i - 1][1])
flattened_tests.append(tests[-1][0][:])
flattened_tests[-1].extend(tests[-1][1])
return [TestVector(x) for x in flattened_tests]
@pytest.mark.skip(reason="Not a test")
def generate_function_test_vectors(circuit, func, input_ranges=None,
mode='complete', flatten=True):
check(circuit, func)
args = []
for i, (name, port) in enumerate(circuit.IO.items()):
if port.isinput():
if isinstance(port, BitKind):
args.append([BitVector(0), BitVector(1)])
elif isinstance(port, ArrayKind) and isinstance(port.T, BitKind):
num_bits = port.N
if isinstance(port, SIntKind):
if input_ranges is None:
input_range = range(-2**(num_bits - 1),
2**(num_bits - 1))
else:
input_range = input_ranges[i]
args.append([SIntVector[num_bits](x)
for x in input_range])
else:
if input_ranges is None:
input_range = range(1 << num_bits)
else:
input_range = input_ranges[i]
args.append([BitVector[num_bits](x)
for x in input_range])
else:
raise NotImplementedError(type(port))
tests = []
for test in product(*args):
result = func(*list(test))
test = [list(test), []]
if isinstance(result, tuple):
test[-1].extend(result)
else:
test[-1].append(result)
tests.append(test)
if flatten:
tests = flatten_tests(tests)
else:
tests = [test[0] + test[1] for test in tests]
return tests
def generate_simulator_test_vectors(circuit, input_ranges=None,
mode='complete', flatten=True):
ntest = len(circuit.interface.ports.items())
simulator = PythonSimulator(circuit)
args = []
for i, (name, port) in enumerate(circuit.IO.items()):
if port.isinput():
if isinstance(port, BitKind):
args.append([BitVector(0), BitVector(1)])
elif isinstance(port, ArrayKind) and isinstance(port.T, BitKind):
num_bits = port.N
if isinstance(port, SIntKind):
if input_ranges is None:
start = -2**(num_bits - 1)
# We don't subtract one because range end is exclusive
end = 2**(num_bits - 1)
input_range = range(start, end)
else:
input_range = input_ranges[i]
args.append([SIntVector[num_bits](x)
for x in input_range])
else:
if input_ranges is None:
input_range = range(1 << num_bits)
else:
input_range = input_ranges[i]
args.append([BitVector[num_bits](x)
for x in input_range])
else:
assert True, "can't test Tuples"
tests = []
for test in product(*args):
testv = [list(test), []]
j = 0
for i, (name, port) in enumerate(circuit.IO.items()):
if port.isinput():
val = test[j].as_bool_list()
if len(val) == 1:
val = val[0]
simulator.set_value(getattr(circuit, name), val)
j += 1
simulator.evaluate()
for i, (name, port) in enumerate(circuit.IO.items()):
if port.isoutput():
val = simulator.get_value(getattr(circuit, name))
if isinstance(port, ArrayKind) and \
not isinstance(port, (BitsKind, SIntKind, UIntKind)):
val = BitVector(val)
testv[1].append(val)
tests.append(testv)
if flatten:
tests = flatten_tests(tests)
else:
tests = [test[0] + test[1] for test in tests]
return tests}
Functions
def check(circuit, func)
-
Source code
def check(circuit, func): sig = signature(func) nfuncargs = len(sig.parameters) # count circuit inputs ncircargs = 0 for name, port in circuit.IO.items(): if port.isinput(): ncircargs += 1 assert nfuncargs == ncircargs}
def flatten_tests(tests)
-
Source code
def flatten_tests(tests): flattened_tests = [] for i in range(len(tests)): flattened_tests.append(tests[i][0][:]) if i == 0: flattened_tests[-1].extend( [fault.AnyValue for _ in range(len(tests[i][1]))]) else: flattened_tests[-1].extend(tests[i - 1][1]) flattened_tests.append(tests[-1][0][:]) flattened_tests[-1].extend(tests[-1][1]) return [TestVector(x) for x in flattened_tests]}
def generate_function_test_vectors(circuit, func, input_ranges=None, mode='complete', flatten=True)
-
Source code
@pytest.mark.skip(reason="Not a test") def generate_function_test_vectors(circuit, func, input_ranges=None, mode='complete', flatten=True): check(circuit, func) args = [] for i, (name, port) in enumerate(circuit.IO.items()): if port.isinput(): if isinstance(port, BitKind): args.append([BitVector(0), BitVector(1)]) elif isinstance(port, ArrayKind) and isinstance(port.T, BitKind): num_bits = port.N if isinstance(port, SIntKind): if input_ranges is None: input_range = range(-2**(num_bits - 1), 2**(num_bits - 1)) else: input_range = input_ranges[i] args.append([SIntVector[num_bits](x) for x in input_range]) else: if input_ranges is None: input_range = range(1 << num_bits) else: input_range = input_ranges[i] args.append([BitVector[num_bits](x) for x in input_range]) else: raise NotImplementedError(type(port)) tests = [] for test in product(*args): result = func(*list(test)) test = [list(test), []] if isinstance(result, tuple): test[-1].extend(result) else: test[-1].append(result) tests.append(test) if flatten: tests = flatten_tests(tests) else: tests = [test[0] + test[1] for test in tests] return tests}
def generate_simulator_test_vectors(circuit, input_ranges=None, mode='complete', flatten=True)
-
Source code
def generate_simulator_test_vectors(circuit, input_ranges=None, mode='complete', flatten=True): ntest = len(circuit.interface.ports.items()) simulator = PythonSimulator(circuit) args = [] for i, (name, port) in enumerate(circuit.IO.items()): if port.isinput(): if isinstance(port, BitKind): args.append([BitVector(0), BitVector(1)]) elif isinstance(port, ArrayKind) and isinstance(port.T, BitKind): num_bits = port.N if isinstance(port, SIntKind): if input_ranges is None: start = -2**(num_bits - 1) # We don't subtract one because range end is exclusive end = 2**(num_bits - 1) input_range = range(start, end) else: input_range = input_ranges[i] args.append([SIntVector[num_bits](x) for x in input_range]) else: if input_ranges is None: input_range = range(1 << num_bits) else: input_range = input_ranges[i] args.append([BitVector[num_bits](x) for x in input_range]) else: assert True, "can't test Tuples" tests = [] for test in product(*args): testv = [list(test), []] j = 0 for i, (name, port) in enumerate(circuit.IO.items()): if port.isinput(): val = test[j].as_bool_list() if len(val) == 1: val = val[0] simulator.set_value(getattr(circuit, name), val) j += 1 simulator.evaluate() for i, (name, port) in enumerate(circuit.IO.items()): if port.isoutput(): val = simulator.get_value(getattr(circuit, name)) if isinstance(port, ArrayKind) and \ not isinstance(port, (BitsKind, SIntKind, UIntKind)): val = BitVector(val) testv[1].append(val) tests.append(testv) if flatten: tests = flatten_tests(tests) else: tests = [test[0] + test[1] for test in tests] return tests}
Classes
class TestVector
-
Source code
class TestVector: __test__ = False def __init__(self, test_vector): self.test_vector = test_vector def __eq__(self, other): if not isinstance(other, TestVector): raise ValueError("Expected another TestVector for __eq__") for x, y in zip(self, other): if x is fault.AnyValue or y is fault.AnyValue: continue if x != y: return False return True def __len__(self): return len(self.test_vector) def __iter__(self): return iter(self.test_vector) def __str__(self): return str(self.test_vector) def __repr__(self): return repr(self.test_vector)}
Methods
def __init__(self, test_vector)
-
Initialize self. See help(type(self)) for accurate signature.
Source code
def __init__(self, test_vector): self.test_vector = test_vector}