Fix incorrect bit-order in packed struct output of external registers. #111
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
20
tests/run.sh
20
tests/run.sh
@@ -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
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
Reference in New Issue
Block a user