testcase framework

This commit is contained in:
Alex Mykyta
2021-11-21 19:00:47 -08:00
parent d3c876a491
commit f70bdf774c
69 changed files with 1730 additions and 403 deletions

View File

@@ -14,7 +14,6 @@ class APB3_Cpuif(CpuifBase):
class APB3_Cpuif_flattened(APB3_Cpuif):
@property
def port_declaration(self) -> str:
# TODO: Reference data/addr width from verilog parameter perhaps?
lines = [
"input wire " + self.signal("psel"),
"input wire " + self.signal("penable"),

View File

@@ -57,11 +57,11 @@ class Dereferencer:
# must be a constant value as defined by its reset value
reset_value = obj.get_property('reset')
if reset_value is not None:
return f"'h{reset_value:x}"
return self.get_value(reset_value)
else:
# No reset value defined!
# Fall back to a value of 0
return "'h0"
# Callers shall ensure this is impossible
raise RuntimeError
if isinstance(obj, SignalNode):
# Signals are always inputs from the hwif

View File

@@ -72,8 +72,8 @@ class RegblockExporter:
package_name = kwargs.pop("package_name", module_name + "_pkg")
# Pipelining options
retime_read_response = kwargs.pop("retime_read_response", True)
retime_read_fanin = kwargs.pop("retime_read_fanin", False)
retime_read_response = kwargs.pop("retime_read_response", True)
# Check for stray kwargs
if kwargs:

View File

@@ -109,7 +109,7 @@ class FieldLogic:
set or clear side effect).
"""
w_modifiable = field.is_sw_writable
r_modifiable = (field.get_property("onread") is not None)
r_modifiable = (field.get_property('onread') is not None)
strb = self.exp.dereferencer.get_access_strobe(field)
if w_modifiable and not r_modifiable:

View File

@@ -74,13 +74,13 @@ class FieldLogicGenerator(RDLForLoopGenerator):
for signal in conditional.get_extra_combo_signals(node):
extra_combo_signals[signal.name] = signal
sig = node.get_property("resetsignal")
sig = node.get_property('resetsignal')
if sig is not None:
resetsignal = RDLSignal(sig)
else:
resetsignal = self.exp.default_resetsignal
reset_value = node.get_property("reset")
reset_value = node.get_property('reset')
if reset_value is not None:
reset_value_str = self.exp.dereferencer.get_value(reset_value)
else:
@@ -106,38 +106,39 @@ class FieldLogicGenerator(RDLForLoopGenerator):
# Field value output
if self.exp.hwif.has_value_output(node):
output_identifier = self.exp.hwif.get_output_identifier(node)
value = self.exp.dereferencer.get_value(node)
self.add_content(
f"assign {output_identifier} = field_storage.{field_path};"
f"assign {output_identifier} = {value};"
)
# Inferred logical reduction outputs
if node.get_property("anded"):
if node.get_property('anded'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "anded")
value = self.exp.dereferencer.get_field_propref_value(node, "anded")
self.add_content(
f"assign {output_identifier} = {value};"
)
if node.get_property("ored"):
if node.get_property('ored'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "ored")
value = self.exp.dereferencer.get_field_propref_value(node, "ored")
self.add_content(
f"assign {output_identifier} = {value};"
)
if node.get_property("xored"):
if node.get_property('xored'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "xored")
value = self.exp.dereferencer.get_field_propref_value(node, "xored")
self.add_content(
f"assign {output_identifier} = {value};"
)
if node.get_property("swmod"):
if node.get_property('swmod'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "swmod")
value = self.field_logic.get_swmod_identifier(node)
self.add_content(
f"assign {output_identifier} = {value};"
)
if node.get_property("swacc"):
if node.get_property('swacc'):
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "swacc")
value = self.field_logic.get_swacc_identifier(node)
self.add_content(

View File

@@ -10,7 +10,7 @@ if TYPE_CHECKING:
class _OnRead(NextStateConditional):
onreadtype = None
def is_match(self, field: 'FieldNode') -> bool:
return field.get_property("onread") == self.onreadtype
return field.get_property('onread') == self.onreadtype
def get_predicate(self, field: 'FieldNode') -> str:
strb = self.exp.dereferencer.get_access_strobe(field)

View File

@@ -13,7 +13,7 @@ if TYPE_CHECKING:
class _OnWrite(NextStateConditional):
onwritetype = None
def is_match(self, field: 'FieldNode') -> bool:
return field.get_property("onwrite") == self.onwritetype
return field.is_sw_writable and field.get_property('onwrite') == self.onwritetype
def get_predicate(self, field: 'FieldNode') -> str:
strb = self.exp.dereferencer.get_access_strobe(field)

View File

@@ -80,7 +80,7 @@ class Hwif:
empty_array_suffix="x"
)
if is_input:
return f'{base}_in_t'
return f'{base}__in_t'
return f'{base}__out_t'
def _do_struct_addressable(self, lines:list, node:AddressableNode, is_input:bool = True) -> bool:
@@ -159,22 +159,22 @@ class Hwif:
contents.append(f"logic {prop_name};")
# Generate any implied counter inputs
if node.get_property("counter"):
if not node.get_property("incr"):
if node.get_property('counter'):
if not node.get_property('incr'):
# User did not provide their own incr component reference.
# Imply an input
contents.append("logic incr;")
if not node.get_property("decr"):
if not node.get_property('decr'):
# User did not provide their own decr component reference.
# Imply an input
contents.append("logic decr;")
width = node.get_property("incrwidth")
width = node.get_property('incrwidth')
if width:
# Implies a corresponding incrvalue input
contents.append(f"logic [{width-1}:0] incrvalue;")
width = node.get_property("decrwidth")
width = node.get_property('decrwidth')
if width:
# Implies a corresponding decrvalue input
contents.append(f"logic [{width-1}:0] decrvalue;")

View File

@@ -104,4 +104,4 @@ class ReadbackAssignmentGenerator(RDLForLoopGenerator):
super().pop_loop()
# Advance current scope's offset to account for loop's contents
self.current_offset += n_regs * dim - 1
self.current_offset = start_offset + n_regs * dim

View File

@@ -5,10 +5,10 @@ logic [{{cpuif.data_width-1}}:0] readback_array[{{array_size}}];
{% if do_fanin_stage %}
// fanin stage
logic [31:0] readback_array_c[{{fanin_array_size}}];
logic [{{cpuif.data_width-1}}:0] readback_array_c[{{fanin_array_size}}];
for(genvar g=0; g<{{fanin_loop_iter}}; g++) begin
always_comb begin
automatic logic [31:0] readback_data_var;
automatic logic [{{cpuif.data_width-1}}:0] readback_data_var;
readback_data_var = '0;
for(int i=g*{{fanin_stride}}; i<((g+1)*{{fanin_stride}}); i++) readback_data_var |= readback_array[i];
readback_array_c[g] = readback_data_var;
@@ -18,14 +18,14 @@ end
assign readback_array_c[{{fanin_array_size-1}}] = readback_array[{{array_size-1}}];
{%- elif fanin_residual_stride > 1 %}
always_comb begin
automatic logic [31:0] readback_data_var;
automatic logic [{{cpuif.data_width-1}}:0] readback_data_var;
readback_data_var = '0;
for(int i={{(fanin_array_size-1) * fanin_stride}}; i<{{array_size-1}}; i++) readback_data_var |= readback_array[i];
for(int i={{(fanin_array_size-1) * fanin_stride}}; i<{{array_size}}; i++) readback_data_var |= readback_array[i];
readback_array_c[{{fanin_array_size-1}}] = readback_data_var;
end
{%- endif %}
logic [31:0] readback_array_r[{{fanin_array_size}}];
logic [{{cpuif.data_width-1}}:0] readback_array_r[{{fanin_array_size}}];
logic readback_done_r;
always_ff @(posedge clk) begin
if(rst) begin
@@ -39,8 +39,8 @@ end
// Reduce the array
always_comb begin
automatic logic [31:0] readback_data_var;
readback_done = decoded_req & ~decoded_req_is_wr;
automatic logic [{{cpuif.data_width-1}}:0] readback_data_var;
readback_done = readback_done_r;
readback_err = '0;
readback_data_var = '0;
for(int i=0; i<{{fanin_array_size}}; i++) readback_data_var |= readback_array_r[i];

View File

@@ -22,7 +22,7 @@ class DesignScanner(RDLListener):
def enter_Reg(self, node: 'RegNode') -> None:
# The CPUIF's bus width is sized according to the largest register in the design
self.cpuif_data_width = max(self.cpuif_data_width, node.get_property("regwidth"))
self.cpuif_data_width = max(self.cpuif_data_width, node.get_property('regwidth'))
# TODO: Collect any references to signals that lie outside of the hierarchy
# These will be added as top-level signals

View File

@@ -50,11 +50,11 @@ class RDLSignal(SignalBase):
@property
def is_async(self) -> bool:
return self.rdl_signal.get_property("async")
return self.rdl_signal.get_property('async')
@property
def is_activehigh(self) -> bool:
return self.rdl_signal.get_property("activehigh")
return self.rdl_signal.get_property('activehigh')
@property
def width(self) -> int: