fault.symbolic_tester
module
Source code
import fault
from fault.tester import Tester
from fault.wrapper import Wrapper, PortWrapper, InstanceWrapper
from fault.cosa_target import CoSATarget
import fault.actions as actions
class SymbolicWrapper(Wrapper):
def __init__(self, circuit, parent):
super().__init__(circuit, parent)
def __setattr__(self, attr, value):
# Hack to stage this after __init__ has been run, should redefine this
# method in a metaclass? Could also use a try/except pattern, so the
# exceptions only occur during object instantiation
if hasattr(self, "circuit") and hasattr(self, "instance_map"):
if attr in self.circuit.interface.ports.keys():
if isinstance(self.parent, fault.Tester):
self.parent.poke(self.circuit.interface.ports[attr], value)
else:
exit(1)
else:
object.__setattr__(self, attr, value)
else:
object.__setattr__(self, attr, value)
def __getattr__(self, attr):
# Hack to stage this after __init__ has been run, should redefine this
# method in a metaclass?
try:
if attr in self.circuit.interface.ports.keys():
return SymbolicPortWrapper(self.circuit.interface.ports[attr],
self)
elif attr in self.instance_map:
return SymbolicInstanceWrapper(self.instance_map[attr], self)
else:
object.__getattribute__(self, attr)
except Exception as e:
object.__getattribute__(self, attr)
class SymbolicCircuitWrapper(SymbolicWrapper):
pass
class SymbolicPortWrapper(PortWrapper):
def assume(self, pred):
select_path = self.select_path
select_path.tester.assume(select_path, pred)
def guarantee(self, pred):
select_path = self.select_path
select_path.tester.guarantee(select_path, pred)
class SymbolicInstanceWrapper(InstanceWrapper):
pass
class SymbolicTester(Tester):
def __init__(self, circuit, clock=None, num_tests=100):
super().__init__(circuit, clock)
self.num_tests = num_tests
def assume(self, port, constraint):
"""
Place a constraint on an input port by providing a symbolic expression
as a Python lambda or function
symbolic_tester_inst.assume(top.I, lambda x : x >= 0)
"""
self.actions.append(actions.Assume(port, constraint))
def guarantee(self, port, constraint):
"""
Assert a property about an output port by providing a symbolic
expression as a Python lambda or function
symbolic_tester_inst.assume(top.O, lambda x : x >= 0)
"""
self.actions.append(actions.Guarantee(port, constraint))
@property
def circuit(self):
return SymbolicCircuitWrapper(self._circuit, self)
def run(self, target="verilator"):
if target == "verilator":
self.targets[target].run(self.actions, self.verilator_includes,
self.num_tests, self._circuit)
elif target == "cosa":
self.targets[target].run(self.actions)
else:
raise NotImplementedError()
def make_target(self, target: str, **kwargs):
if target == "cosa":
return CoSATarget(self._circuit, **kwargs)
else:
return super().make_target(target, **kwargs)}
Classes
class SymbolicCircuitWrapper (ancestors: SymbolicWrapper, Wrapper)
-
Inherited from:
SymbolicWrapper
Source code
class SymbolicCircuitWrapper(SymbolicWrapper): pass}
Inherited members
class SymbolicInstanceWrapper (ancestors: InstanceWrapper, Wrapper)
-
Inherited from:
InstanceWrapper
Source code
class SymbolicInstanceWrapper(InstanceWrapper): pass}
Inherited members
class SymbolicPortWrapper (ancestors: PortWrapper)
-
Inherited from:
PortWrapper
Source code
class SymbolicPortWrapper(PortWrapper): def assume(self, pred): select_path = self.select_path select_path.tester.assume(select_path, pred) def guarantee(self, pred): select_path = self.select_path select_path.tester.guarantee(select_path, pred)}
Methods
def assume(self, pred)
-
Source code
def assume(self, pred): select_path = self.select_path select_path.tester.assume(select_path, pred)}
def guarantee(self, pred)
-
Source code
def guarantee(self, pred): select_path = self.select_path select_path.tester.guarantee(select_path, pred)}
Inherited members
class SymbolicTester (ancestors: Tester)
-
Inherited from:
Tester
The fault
Tester
object provides a mechanism in Python to construct tests for magma circuits. TheTester
is instantiated with a specific magma …Source code
class SymbolicTester(Tester): def __init__(self, circuit, clock=None, num_tests=100): super().__init__(circuit, clock) self.num_tests = num_tests def assume(self, port, constraint): """ Place a constraint on an input port by providing a symbolic expression as a Python lambda or function symbolic_tester_inst.assume(top.I, lambda x : x >= 0) """ self.actions.append(actions.Assume(port, constraint)) def guarantee(self, port, constraint): """ Assert a property about an output port by providing a symbolic expression as a Python lambda or function symbolic_tester_inst.assume(top.O, lambda x : x >= 0) """ self.actions.append(actions.Guarantee(port, constraint)) @property def circuit(self): return SymbolicCircuitWrapper(self._circuit, self) def run(self, target="verilator"): if target == "verilator": self.targets[target].run(self.actions, self.verilator_includes, self.num_tests, self._circuit) elif target == "cosa": self.targets[target].run(self.actions) else: raise NotImplementedError() def make_target(self, target: str, **kwargs): if target == "cosa": return CoSATarget(self._circuit, **kwargs) else: return super().make_target(target, **kwargs)}
Instance variables
var circuit
-
Source code
@property def circuit(self): return SymbolicCircuitWrapper(self._circuit, self)}
Methods
def assume(self, port, constraint)
-
Place a constraint on an input port by providing a symbolic expression as a Python lambda or function
symbolic_tester_inst.assume(top.I, lambda x : x >= 0)
Source code
def assume(self, port, constraint): """ Place a constraint on an input port by providing a symbolic expression as a Python lambda or function symbolic_tester_inst.assume(top.I, lambda x : x >= 0) """ self.actions.append(actions.Assume(port, constraint))}
def guarantee(self, port, constraint)
-
Assert a property about an output port by providing a symbolic expression as a Python lambda or function
symbolic_tester_inst.assume(top.O, lambda x : x >= 0)
Source code
def guarantee(self, port, constraint): """ Assert a property about an output port by providing a symbolic expression as a Python lambda or function symbolic_tester_inst.assume(top.O, lambda x : x >= 0) """ self.actions.append(actions.Guarantee(port, constraint))}
Inherited members
class SymbolicWrapper (ancestors: Wrapper)
-
Inherited from:
Wrapper
Source code
class SymbolicWrapper(Wrapper): def __init__(self, circuit, parent): super().__init__(circuit, parent) def __setattr__(self, attr, value): # Hack to stage this after __init__ has been run, should redefine this # method in a metaclass? Could also use a try/except pattern, so the # exceptions only occur during object instantiation if hasattr(self, "circuit") and hasattr(self, "instance_map"): if attr in self.circuit.interface.ports.keys(): if isinstance(self.parent, fault.Tester): self.parent.poke(self.circuit.interface.ports[attr], value) else: exit(1) else: object.__setattr__(self, attr, value) else: object.__setattr__(self, attr, value) def __getattr__(self, attr): # Hack to stage this after __init__ has been run, should redefine this # method in a metaclass? try: if attr in self.circuit.interface.ports.keys(): return SymbolicPortWrapper(self.circuit.interface.ports[attr], self) elif attr in self.instance_map: return SymbolicInstanceWrapper(self.instance_map[attr], self) else: object.__getattribute__(self, attr) except Exception as e: object.__getattribute__(self, attr)}
Subclasses
Inherited members