fault.verilog_target
module
Source code
from abc import abstractmethod
import magma as m
from fault.target import Target
from pathlib import Path
import fault.actions as actions
from fault.util import flatten
import os
from fault.select_path import SelectPath
from fault.verilog_utils import verilog_name
class VerilogTarget(Target):
"""
Provides reuseable target logic for compiling circuits into verilog files.
"""
def __init__(self, circuit, circuit_name=None, directory="build/",
skip_compile=False, include_verilog_libraries=[],
magma_output="verilog", magma_opts={}):
super().__init__(circuit)
if circuit_name is None:
self.circuit_name = self.circuit.name
else:
self.circuit_name = circuit_name
self.directory = Path(directory)
os.makedirs(directory, exist_ok=True)
self.skip_compile = skip_compile
self.include_verilog_libraries = include_verilog_libraries
self.magma_output = magma_output
self.magma_opts = magma_opts
if hasattr(circuit, "verilog_file_name") and \
os.path.splitext(circuit.verilog_file_name)[-1] == ".sv":
suffix = "sv"
else:
suffix = "v"
self.verilog_file = Path(f"{self.circuit_name}.{suffix}")
# Optionally compile this module to verilog first.
if not self.skip_compile:
prefix = os.path.splitext(self.directory / self.verilog_file)[0]
m.compile(prefix, self.circuit, output=self.magma_output,
**self.magma_opts)
if not (self.directory / self.verilog_file).is_file():
raise Exception(f"Compiling {self.circuit} failed")
self.assumptions = []
self.guarantees = []
def make_assume(self, i, action):
self.assumptions.append(action)
return ""
def make_guarantee(self, i, action):
self.guarantees.append(action)
return ""
def generate_array_action_code(self, i, action):
result = []
port = action.port
if isinstance(port, SelectPath):
port = port[-1]
for j in range(port.N):
if isinstance(action, actions.Print):
value = action.format_str
else:
value = action.value[j]
result += [
self.generate_action_code(
i, type(action)(port[j], value)
)]
return flatten(result)
def generate_action_code(self, i, action):
if isinstance(action, (actions.PortAction, actions.Print)) and \
isinstance(action.port, m.ArrayType) and \
not isinstance(action.port.T, m.BitKind):
return self.generate_array_action_code(i, action)
elif isinstance(action, (actions.PortAction, actions.Print)) and \
isinstance(action.port, SelectPath) and \
isinstance(action.port[-1], m.ArrayType) and \
not isinstance(action.port[-1].T, m.BitKind):
return self.generate_array_action_code(i, action)
if isinstance(action, actions.Poke):
return self.make_poke(i, action)
if isinstance(action, actions.Print):
name = verilog_name(action.port.name)
return self.make_print(i, action)
if isinstance(action, actions.Expect):
return self.make_expect(i, action)
if isinstance(action, actions.Eval):
return self.make_eval(i, action)
if isinstance(action, actions.Step):
return self.make_step(i, action)
if isinstance(action, actions.Assume):
return self.make_assume(i, action)
if isinstance(action, actions.Guarantee):
return self.make_guarantee(i, action)
raise NotImplementedError(action)
@abstractmethod
def make_poke(self, i, action):
pass
@abstractmethod
def make_print(self, i, action):
pass
@abstractmethod
def make_expect(self, i, action):
pass
@abstractmethod
def make_eval(self, i, action):
pass
@abstractmethod
def make_step(self, i, action):
pass}
Classes
class VerilogTarget (ancestors: Target, abc.ABC)
-
Provides reuseable target logic for compiling circuits into verilog files.
Source code
class VerilogTarget(Target): """ Provides reuseable target logic for compiling circuits into verilog files. """ def __init__(self, circuit, circuit_name=None, directory="build/", skip_compile=False, include_verilog_libraries=[], magma_output="verilog", magma_opts={}): super().__init__(circuit) if circuit_name is None: self.circuit_name = self.circuit.name else: self.circuit_name = circuit_name self.directory = Path(directory) os.makedirs(directory, exist_ok=True) self.skip_compile = skip_compile self.include_verilog_libraries = include_verilog_libraries self.magma_output = magma_output self.magma_opts = magma_opts if hasattr(circuit, "verilog_file_name") and \ os.path.splitext(circuit.verilog_file_name)[-1] == ".sv": suffix = "sv" else: suffix = "v" self.verilog_file = Path(f"{self.circuit_name}.{suffix}") # Optionally compile this module to verilog first. if not self.skip_compile: prefix = os.path.splitext(self.directory / self.verilog_file)[0] m.compile(prefix, self.circuit, output=self.magma_output, **self.magma_opts) if not (self.directory / self.verilog_file).is_file(): raise Exception(f"Compiling {self.circuit} failed") self.assumptions = [] self.guarantees = [] def make_assume(self, i, action): self.assumptions.append(action) return "" def make_guarantee(self, i, action): self.guarantees.append(action) return "" def generate_array_action_code(self, i, action): result = [] port = action.port if isinstance(port, SelectPath): port = port[-1] for j in range(port.N): if isinstance(action, actions.Print): value = action.format_str else: value = action.value[j] result += [ self.generate_action_code( i, type(action)(port[j], value) )] return flatten(result) def generate_action_code(self, i, action): if isinstance(action, (actions.PortAction, actions.Print)) and \ isinstance(action.port, m.ArrayType) and \ not isinstance(action.port.T, m.BitKind): return self.generate_array_action_code(i, action) elif isinstance(action, (actions.PortAction, actions.Print)) and \ isinstance(action.port, SelectPath) and \ isinstance(action.port[-1], m.ArrayType) and \ not isinstance(action.port[-1].T, m.BitKind): return self.generate_array_action_code(i, action) if isinstance(action, actions.Poke): return self.make_poke(i, action) if isinstance(action, actions.Print): name = verilog_name(action.port.name) return self.make_print(i, action) if isinstance(action, actions.Expect): return self.make_expect(i, action) if isinstance(action, actions.Eval): return self.make_eval(i, action) if isinstance(action, actions.Step): return self.make_step(i, action) if isinstance(action, actions.Assume): return self.make_assume(i, action) if isinstance(action, actions.Guarantee): return self.make_guarantee(i, action) raise NotImplementedError(action) @abstractmethod def make_poke(self, i, action): pass @abstractmethod def make_print(self, i, action): pass @abstractmethod def make_expect(self, i, action): pass @abstractmethod def make_eval(self, i, action): pass @abstractmethod def make_step(self, i, action): pass}
Methods
def generate_action_code(self, i, action)
-
Source code
def generate_action_code(self, i, action): if isinstance(action, (actions.PortAction, actions.Print)) and \ isinstance(action.port, m.ArrayType) and \ not isinstance(action.port.T, m.BitKind): return self.generate_array_action_code(i, action) elif isinstance(action, (actions.PortAction, actions.Print)) and \ isinstance(action.port, SelectPath) and \ isinstance(action.port[-1], m.ArrayType) and \ not isinstance(action.port[-1].T, m.BitKind): return self.generate_array_action_code(i, action) if isinstance(action, actions.Poke): return self.make_poke(i, action) if isinstance(action, actions.Print): name = verilog_name(action.port.name) return self.make_print(i, action) if isinstance(action, actions.Expect): return self.make_expect(i, action) if isinstance(action, actions.Eval): return self.make_eval(i, action) if isinstance(action, actions.Step): return self.make_step(i, action) if isinstance(action, actions.Assume): return self.make_assume(i, action) if isinstance(action, actions.Guarantee): return self.make_guarantee(i, action) raise NotImplementedError(action)}
def generate_array_action_code(self, i, action)
-
Source code
def generate_array_action_code(self, i, action): result = [] port = action.port if isinstance(port, SelectPath): port = port[-1] for j in range(port.N): if isinstance(action, actions.Print): value = action.format_str else: value = action.value[j] result += [ self.generate_action_code( i, type(action)(port[j], value) )] return flatten(result)}
def make_assume(self, i, action)
-
Source code
def make_assume(self, i, action): self.assumptions.append(action) return ""}
def make_eval(self, i, action)
-
Source code
@abstractmethod def make_eval(self, i, action): pass}
def make_expect(self, i, action)
-
Source code
@abstractmethod def make_expect(self, i, action): pass}
def make_guarantee(self, i, action)
-
Source code
def make_guarantee(self, i, action): self.guarantees.append(action) return ""}
def make_poke(self, i, action)
-
Source code
@abstractmethod def make_poke(self, i, action): pass}
def make_print(self, i, action)
-
Source code
@abstractmethod def make_print(self, i, action): pass}
def make_step(self, i, action)
-
Source code
@abstractmethod def make_step(self, i, action): pass}
Inherited members