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

View File

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

View File

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

View File

@@ -294,4 +294,18 @@
end
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 %}