Skip to content

Commit

Permalink
Merge 5083fda into 3ec7203
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardt committed Sep 14, 2018
2 parents 3ec7203 + 5083fda commit 1a95a03
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 16 deletions.
18 changes: 18 additions & 0 deletions fault/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ def __init__(self, port, value):
super().__init__(port, value)


class Peek(Action):
def __init__(self, port, format_str="%x"):
if port.isoutput():
raise ValueError(f"Can only peek outputs: {port.debug_name} "
f"{type(port)}")
super().__init__()
self.port = port
self.format_str = format_str

def __str__(self):
return f"Peek({self.port.debug_name}, \"{self.format_str}\")"

def retarget(self, new_circuit, clock):
cls = type(self)
new_port = new_circuit.interface.ports[str(self.port.name)]
return cls(new_port, self.format_str)


class Expect(PortAction):
def __init__(self, port, value):
if port.isoutput():
Expand Down
4 changes: 4 additions & 0 deletions fault/magma_simulator_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def run(self):
isinstance(value, BitVector):
value = value.as_uint()
simulator.set_value(action.port, value)
elif isinstance(action, actions.Peek):
got = BitVector(simulator.get_value(action.port))
print(f'{action.port.debug_name} = {action.format_str}' %
got.as_uint())
elif isinstance(action, actions.Expect):
got = BitVector(simulator.get_value(action.port))
expected = action.value
Expand Down
12 changes: 9 additions & 3 deletions fault/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
from fault.vector_builder import VectorBuilder
from fault.value_utils import make_value
from fault.verilator_target import VerilatorTarget
from fault.actions import Poke, Expect, Step
from fault.actions import Poke, Expect, Step, Peek
from fault.circuit_utils import check_interface_is_subset
import copy


class Tester:
def __init__(self, circuit, clock=None):
def __init__(self, circuit, clock=None, default_peek_format_str="%x"):
self.circuit = circuit
self.actions = []
if clock is not None and not isinstance(clock, magma.ClockType):
raise TypeError(f"Expected clock port: {clock, type(clock)}")
self.clock = clock
self.default_peek_format_str = default_peek_format_str

def make_target(self, target, **kwargs):
if target == "verilator":
Expand All @@ -36,6 +37,11 @@ def poke(self, port, value):
value = make_value(port, value)
self.actions.append(actions.Poke(port, value))

def peek(self, port, format_str=None):
if format_str is None:
format_str = self.default_peek_format_str
self.actions.append(actions.Peek(port, format_str))

def expect(self, port, value):
value = make_value(port, value)
self.actions.append(actions.Expect(port, value))
Expand Down Expand Up @@ -69,7 +75,7 @@ def retarget(self, new_circuit, clock=None):
# Check that the interface of self.circuit is a subset of new_circuit
check_interface_is_subset(self.circuit, new_circuit)

new_tester = Tester(new_circuit, clock)
new_tester = Tester(new_circuit, clock, self.default_peek_format_str)
new_tester.actions = [action.retarget(new_circuit, clock) for action in
self.actions]
return new_tester
3 changes: 3 additions & 0 deletions fault/vector_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,8 @@ def process(self, action):
val ^= BitVector(1, 1)
self.__eval()
self.__set(indices, val)
elif isinstance(action, actions.Peek):
# Skip Peek actions for test vectors
return
else:
raise NotImplementedError(action)
4 changes: 4 additions & 0 deletions fault/verilator_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ def generate_action_code(i, action):
if isinstance(action, actions.Poke):
name = verilator_utils.verilator_name(action.port.name)
return [f"top->{name} = {action.value};"]
if isinstance(action, actions.Peek):
name = verilator_utils.verilator_name(action.port.name)
return [f'printf("{action.port.debug_name} = '
f'{action.format_str}\\n", top->{name});']
if isinstance(action, actions.Expect):
# For verilator, if an expect is "AnyValue" we don't need to perform
# the expect.
Expand Down
3 changes: 2 additions & 1 deletion tests/test_action.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from fault.actions import Poke, Expect, Eval, Step
from fault.actions import Poke, Expect, Eval, Step, Peek
import common


Expand All @@ -8,3 +8,4 @@ def test_action_strs():
assert str(Expect(circ.O, 1)) == 'Expect(BasicClkCircuit.O, 1)'
assert str(Eval()) == 'Eval()'
assert str(Step(circ.CLK, 1)) == 'Step(BasicClkCircuit.CLK, steps=1)'
assert str(Peek(circ.O, "%08x")) == 'Peek(BasicClkCircuit.O, "%08x")'
10 changes: 8 additions & 2 deletions tests/test_magma_simulator_target.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from bit_vector import BitVector
import common
from fault.actions import Poke, Expect, Eval, Step
from fault.actions import Poke, Expect, Eval, Step, Peek
from fault.magma_simulator_target import MagmaSimulatorTarget
from fault.random import random_bv

Expand Down Expand Up @@ -50,7 +50,7 @@ def test_magma_simulator_target_nested_arrays(backend):
run(circ, actions, None, backend)


def test_magma_simulator_target_clock(backend):
def test_magma_simulator_target_clock(backend, capfd):
circ = common.TestBasicClkCircuit
actions = [
Poke(circ.I, BitVector(0, 1)),
Expand All @@ -59,5 +59,11 @@ def test_magma_simulator_target_clock(backend):
# coreir simulator. Currently it does not allow this.
# Poke(circ.CLK, BitVector(0, 1)),
Step(circ.CLK, 1),
Poke(circ.I, BitVector(1, 1)),
Eval(),
Peek(circ.O),
]
run(circ, actions, circ.CLK, backend)
out, err = capfd.readouterr()
assert out.splitlines()[-1] == "BasicClkCircuit.O = 1", \
"Peek output incorrect"
22 changes: 15 additions & 7 deletions tests/test_tester.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import random
from bit_vector import BitVector
import fault
from fault.actions import Poke, Expect, Eval, Step
from fault.actions import Poke, Expect, Eval, Step, Peek
import common


Expand All @@ -15,10 +15,12 @@ def test_tester_basic():
tester = fault.Tester(circ)
tester.poke(circ.I, 0)
tester.expect(circ.O, 0)
tester.peek(circ.O, "%08x")
check(tester.actions[0], Poke(circ.I, 0))
check(tester.actions[1], Expect(circ.O, 0))
check(tester.actions[2], Peek(circ.O, "%08x"))
tester.eval()
check(tester.actions[2], Eval())
check(tester.actions[3], Eval())


def test_tester_clock():
Expand Down Expand Up @@ -48,30 +50,36 @@ def test_tester_nested_arrays():
check(tester.actions[i], exp)


def test_copy_tester():
def test_retarget_tester():
circ = common.TestBasicClkCircuit
expected = [
Poke(circ.I, 0),
Eval(),
Expect(circ.O, 0),
Poke(circ.CLK, 0),
Step(circ.CLK, 1)
Step(circ.CLK, 1),
Peek(circ.O, "%08x")
]
tester = fault.Tester(circ, circ.CLK)
tester = fault.Tester(circ, circ.CLK, default_peek_format_str="%08x")
tester.poke(circ.I, 0)
tester.eval()
tester.expect(circ.O, 0)
tester.poke(circ.CLK, 0)
tester.step()
print(tester.actions)
tester.peek(circ.O)
for i, exp in enumerate(expected):
check(tester.actions[i], exp)

circ_copy = common.TestBasicClkCircuitCopy
copy = tester.retarget(circ_copy, circ_copy.CLK)
assert copy.default_peek_format_str == "%08x"
copy_expected = [
Poke(circ_copy.I, 0),
Eval(),
Expect(circ_copy.O, 0),
Poke(circ_copy.CLK, 0),
Step(circ_copy.CLK, 1)
Step(circ_copy.CLK, 1),
Peek(circ_copy.O, "%08x")
]
for i, exp in enumerate(copy_expected):
check(copy.actions[i], exp)
3 changes: 2 additions & 1 deletion tests/test_vector_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from bit_vector import BitVector
import fault
import common
from fault.actions import Poke, Expect, Eval, Step
from fault.actions import Poke, Expect, Eval, Step, Peek
from fault.array import Array
from fault.vector_builder import VectorBuilder

Expand All @@ -22,6 +22,7 @@ def test_tester_clock():
circ = common.TestBasicClkCircuit
builder = VectorBuilder(circ)
builder.process(Poke(circ.I, BitVector(0, 1)))
builder.process(Peek(circ.O))
builder.process(Expect(circ.O, BitVector(0, 1)))
assert builder.vectors == [
[BitVector(0, 1), BitVector(0, 1), fault.AnyValue]
Expand Down
11 changes: 9 additions & 2 deletions tests/test_verilator_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from bit_vector import BitVector
import common
import random
from fault.actions import Poke, Expect, Eval, Step
from fault.actions import Poke, Expect, Eval, Step, Peek


def run(circ, actions, flags=[]):
Expand Down Expand Up @@ -37,12 +37,19 @@ def test_verilator_target_nested_arrays():
run(circ, actions)


def test_verilator_target_clock():
def test_verilator_target_clock(capfd):
circ = common.TestBasicClkCircuit
actions = [
Poke(circ.I, 0),
Expect(circ.O, 0),
Poke(circ.CLK, 0),
Peek(circ.O),
Step(circ.CLK, 1),
Poke(circ.I, BitVector(1, 1)),
Eval(),
Peek(circ.O),
]
run(circ, actions, flags=["-Wno-lint"])
out, err = capfd.readouterr()
assert out.splitlines()[-1] == "BasicClkCircuit.O = 1", \
"Peek output incorrect"

0 comments on commit 1a95a03

Please sign in to comment.