testcase framework
This commit is contained in:
@@ -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"),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user