Fix incorrect bit-order in packed struct output of external registers. #111

This commit is contained in:
Alex Mykyta
2024-12-18 21:17:31 -08:00
parent 399f942201
commit 11d9f65dff
4 changed files with 43 additions and 30 deletions

View File

@@ -110,27 +110,27 @@ class InputStructGenerator_Hier(HWIFStructGenerator):
# External reg is 1 sub-word. Add a packed struct to represent it # External reg is 1 sub-word. Add a packed struct to represent it
type_name = self.get_typdef_name(node, "__fields") type_name = self.get_typdef_name(node, "__fields")
self.push_struct(type_name, "rd_data", packed=True) self.push_struct(type_name, "rd_data", packed=True)
current_bit = 0 current_bit = width - 1
for field in node.fields(): for field in reversed(list(node.fields())):
if not field.is_sw_readable: if not field.is_sw_readable:
continue continue
if field.low > current_bit: if field.high < current_bit:
# Add padding # Add padding
self.add_member( self.add_member(
f"_reserved_{field.low - 1}_{current_bit}", f"_reserved_{current_bit}_{field.high + 1}",
field.low - current_bit current_bit - field.high
) )
self.add_member( self.add_member(
kwf(field.inst_name), kwf(field.inst_name),
field.width field.width
) )
current_bit = field.high + 1 current_bit = field.low - 1
# Add end padding if needed # Add end padding if needed
if current_bit != width: if current_bit != -1:
self.add_member( self.add_member(
f"_reserved_{width - 1}_{current_bit}", f"_reserved_{current_bit}_0",
width - current_bit current_bit + 1
) )
self.pop_struct() self.pop_struct()
else: else:
@@ -237,27 +237,27 @@ class OutputStructGenerator_Hier(HWIFStructGenerator):
# External reg is 1 sub-word. Add a packed struct to represent it # External reg is 1 sub-word. Add a packed struct to represent it
type_name = self.get_typdef_name(node, "__fields") type_name = self.get_typdef_name(node, "__fields")
self.push_struct(type_name, name, packed=True) self.push_struct(type_name, name, packed=True)
current_bit = 0 current_bit = width - 1
for field in node.fields(): for field in reversed(list(node.fields())):
if not field.is_sw_writable: if not field.is_sw_writable:
continue continue
if field.low > current_bit: if field.high < current_bit:
# Add padding # Add padding
self.add_member( self.add_member(
f"_reserved_{field.low - 1}_{current_bit}", f"_reserved_{current_bit}_{field.high + 1}",
field.low - current_bit current_bit - field.high
) )
self.add_member( self.add_member(
kwf(field.inst_name), kwf(field.inst_name),
field.width field.width
) )
current_bit = field.high + 1 current_bit = field.low - 1
# Add end padding if needed # Add end padding if needed
if current_bit != width: if current_bit != -1:
self.add_member( self.add_member(
f"_reserved_{width - 1}_{current_bit}", f"_reserved_{current_bit}_0",
width - current_bit current_bit + 1
) )
self.pop_struct() self.pop_struct()
else: else:

View File

@@ -29,6 +29,9 @@ class Questa(Simulator):
# Ignore noisy warning about vopt-time checking of always_comb/always_latch # Ignore noisy warning about vopt-time checking of always_comb/always_latch
"-suppress", "2583", "-suppress", "2583",
# Suppress "error" about use of the `line directive
"-suppress", "13465",
] ]
# Add source files # Add source files

View File

@@ -2,30 +2,26 @@
set -e set -e
this_dir="$( cd "$(dirname "$0")" ; pwd -P )" cd "$(dirname "$0")"
# Initialize venv # Initialize venv
venv_bin=$this_dir/.venv/bin python3 -m venv .venv
python3 -m venv $this_dir/.venv source .venv/bin/activate
source $this_dir/.venv/bin/activate
# Install test dependencies # Install test dependencies
pip install -U pip setuptools wheel pip install -r requirements.txt
pip install -r $this_dir/requirements.txt
# Install dut # Install dut
cd $this_dir/../ pip install -U ..
pip install -U .
cd $this_dir
# Run unit tests # Run unit tests
pytest --workers auto --cov=peakrdl_regblock --synth-tool skip pytest --workers auto --cov=peakrdl_regblock --synth-tool skip
# Generate coverage report # Generate coverage report
coverage html -i -d $this_dir/htmlcov coverage html -i -d htmlcov
# Run lint # Run lint
pylint --rcfile $this_dir/pylint.rc ../src/peakrdl_regblock pylint --rcfile pylint.rc ../src/peakrdl_regblock
# Run static type checking # Run static type checking
mypy $this_dir/../src/peakrdl_regblock mypy ../src/peakrdl_regblock

View File

@@ -294,4 +294,18 @@
end end
wait fork; wait fork;
// Check register struct bit-order
repeat(32) begin
regblock_pkg::top__my_reg_alt__external__fields__in_t fields_in;
regblock_pkg::top__my_reg_alt__external__fields__out_t fields_out;
fields_in = $urandom();
fields_out = $urandom();
assert(fields_in.whatever_a == fields_in[3:2]);
assert(fields_in.whatever_c == fields_in[15:8]);
assert(fields_out.whatever_b == fields_out[4]);
assert(fields_out.whatever_c == fields_out[15:8]);
end
{% endblock %} {% endblock %}