diff --git a/src/peakrdl_regblock/hwif/generators.py b/src/peakrdl_regblock/hwif/generators.py index 5ab73db..e0b61e5 100644 --- a/src/peakrdl_regblock/hwif/generators.py +++ b/src/peakrdl_regblock/hwif/generators.py @@ -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: diff --git a/tests/lib/simulators/questa.py b/tests/lib/simulators/questa.py index 3e35667..cf97a47 100644 --- a/tests/lib/simulators/questa.py +++ b/tests/lib/simulators/questa.py @@ -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 diff --git a/tests/run.sh b/tests/run.sh index ea1b0d8..89fb176 100755 --- a/tests/run.sh +++ b/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 diff --git a/tests/test_external/tb_template.sv b/tests/test_external/tb_template.sv index a5f4029..f5a047e 100644 --- a/tests/test_external/tb_template.sv +++ b/tests/test_external/tb_template.sv @@ -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 %}