Skip to content

Commit

Permalink
Merge d9727ee into 1a685f7
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardt committed May 21, 2019
2 parents 1a685f7 + d9727ee commit edfffd3
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 10 deletions.
1 change: 1 addition & 0 deletions fault/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .tester import Tester
from .power_tester import PowerTester
from .value import Value, AnyValue, UnknownValue
import fault.random
from .symbolic_tester import SymbolicTester
Expand Down
27 changes: 27 additions & 0 deletions fault/power_tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import magma as m
from fault import Tester


class PowerTester(Tester):
def __init__(self, circuit: m.Circuit, clock: m.ClockType = None):
super().__init__(circuit, clock)
self.supply0s = []
self.supply1s = []
self.tris = []

def add_power(self, port):
self.supply1s.append(port.name.name)

def add_ground(self, port):
self.supply0s.append(port.name.name)

def add_tri(self, port):
self.tris.append(port.name.name)

def run(self, target="system-verilog"):
power_args = {
"supply0s": self.supply0s,
"supply1s": self.supply1s,
"tris": self.tris,
}
self.targets[target].run(self.actions, power_args)
27 changes: 17 additions & 10 deletions fault/system_verilog_target.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from fault.verilog_target import VerilogTarget, verilog_name
import magma as m
from pathlib import Path

import fault.actions as actions
from hwtypes import BitVector
import fault.value_utils as value_utils
Expand Down Expand Up @@ -195,33 +196,39 @@ def make_step(self, i, action):
code.append(f"#5 {name} ^= 1;")
return code

def generate_recursive_port_code(self, name, type_):
def generate_recursive_port_code(self, name, type_, power_args):
port_list = []
if isinstance(type_, m.ArrayKind):
for j in range(type_.N):
result = self.generate_port_code(
name + "_" + str(j), type_.T
name + "_" + str(j), type_.T, power_args
)
port_list.extend(result)
elif isinstance(type_, m.TupleKind):
for k, t in zip(type_.Ks, type_.Ts):
result = self.generate_port_code(
name + "_" + str(k), t
name + "_" + str(k), t, power_args
)
port_list.extend(result)
return port_list

def generate_port_code(self, name, type_):
def generate_port_code(self, name, type_, power_args):
is_array_of_bits = isinstance(type_, m.ArrayKind) and \
not isinstance(type_.T, m.BitKind)
if is_array_of_bits or isinstance(type_, m.TupleKind):
return self.generate_recursive_port_code(name, type_)
return self.generate_recursive_port_code(name, type_, power_args)
else:
width_str = ""
if isinstance(type_, m.ArrayKind) and \
isinstance(type_.T, m.BitKind):
width_str = f"[{len(type_) - 1}:0] "
if type_.isoutput():
if name in power_args.get("supply0s", []):
t = "supply0"
elif name in power_args.get("supply1s", []):
t = "supply1"
elif name in power_args.get("tris", []):
t = "tri"
elif type_.isoutput():
t = "wire"
elif type_.isinput():
t = "reg"
Expand All @@ -230,11 +237,11 @@ def generate_port_code(self, name, type_):
self.declarations.append(f" {t} {width_str}{name};\n")
return [f".{name}({name})"]

def generate_code(self, actions):
def generate_code(self, actions, power_args):
initial_body = ""
port_list = []
for name, type_ in self.circuit.IO.ports.items():
result = self.generate_port_code(name, type_)
result = self.generate_port_code(name, type_, power_args)
port_list.extend(result)

for i, action in enumerate(actions):
Expand All @@ -251,11 +258,11 @@ def generate_code(self, actions):

return src

def run(self, actions):
def run(self, actions, power_args={}):
test_bench_file = Path(f"{self.circuit_name}_tb.sv")

# Write the verilator driver to file.
src = self.generate_code(actions)
src = self.generate_code(actions, power_args)
with open(self.directory / test_bench_file, "w") as f:
f.write(src)
verilog_libraries = " ".join(str(x) for x in
Expand Down
69 changes: 69 additions & 0 deletions tests/test_power_domains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import magma as m
import mantle
import fault
from hwtypes import BitVector


def test_simple_alu_pd():
type_map = {"CLK": m.In(m.Clock)}
circ = m.DefineFromVerilogFile("tests/verilog/simple_alu_pd.sv",
type_map=type_map)[0]
tester = fault.PowerTester(circ, circ.CLK)
tester.add_power(circ.VDD_HIGH)
tester.add_ground(circ.VSS)
tester.add_tri(circ.VDD_HIGH_TOP_VIRTUAL)

tester.circuit.CLK = 0

# Enable the power switch
tester.circuit.config_addr = 0x00080000
tester.circuit.config_data = 0xFFFFFFF0
tester.circuit.config_en = 1
tester.step(2)
tester.circuit.config_en = 0

# rest of test...
a, b = BitVector.random(16), BitVector.random(16)
tester.circuit.a = a
tester.circuit.b = b
tester.circuit.c.expect(a + b)

# Disable the power switch
tester.circuit.config_addr = 0x00080000
tester.circuit.config_data = 0xFFFFFFF0
tester.circuit.config_en = 1
tester.step(2)
tester.circuit.config_en = 0
# Stall global signal should be on when tile is off
tester.circuit.stall_out.expect(1)
# reset signal should be on when tile is off
tester.circuit.reset.expect(1)

# Enable the power switch
tester.circuit.config_addr = 0x00080000
tester.circuit.config_data = 0xFFFFFFF0
tester.circuit.config_en = 1
tester.step(2)
tester.circuit.config_en = 0

# rest of test...
a, b = BitVector.random(16), BitVector.random(16)
tester.circuit.a = a
tester.circuit.b = b
tester.circuit.c.expect(a + b)

try:
tester.compile_and_run(target="system-verilog", simulator="ncsim",
directory="tests/build", skip_compile=True)
except AssertionError:
# Won't run because we don't have concrete DUT or ncsim, but we check
# that the output has the right types for the special ports
with open("tests/build/simple_alu_pd_tb.sv", "r") as f:
for line in f.read().splitlines():
if "VDD_HIGH_TOP_VIRTUAL;" in line:
assert line.lstrip().rstrip() == \
"tri VDD_HIGH_TOP_VIRTUAL;"
elif "VDD_HIGH;" in line:
assert line.lstrip().rstrip() == "supply1 VDD_HIGH;"
elif "VSS;" in line:
assert line.lstrip().rstrip() == "supply0 VSS;"
9 changes: 9 additions & 0 deletions tests/verilog/simple_alu_pd.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module simple_alu_pd(input [15:0] a, input [15:0] b, output [15:0] c,
input [15:0] config_data, input [15:0] config_en,
input CLK, input VDD_HIGH, input VSS,
input VDD_HIGH_TOP_VIRTUAL, output stall_out,
output reset);

// stub to test support for reading in modules with supply1,
// supply0, and tri types
endmodule

0 comments on commit edfffd3

Please sign in to comment.