Add support for wide registers (where accesswidth < regwidth)

This commit is contained in:
Alex Mykyta
2022-10-12 20:44:22 -07:00
parent 21a4e5a41c
commit e07e7d26b2
18 changed files with 687 additions and 206 deletions

18
tests/.coveragerc Normal file
View File

@@ -0,0 +1,18 @@
[run]
branch = True
#relative_files = True
[paths]
source =
../src/peakrdl_regblock/
*/site-packages/*/peakrdl_regblock
*/site-packages/peakrdl_regblock
[report]
exclude_lines =
pragma: no cover
raise RuntimeError
raise NotImplementedError
if TYPE_CHECKING:
precision = 1

View File

@@ -4,3 +4,5 @@ pytest-parallel
jinja2-simple-tags
pylint
mypy
pytest-cov
coverage

View File

@@ -15,12 +15,17 @@ pip install -r $this_dir/requirements.txt
# Install dut
cd $this_dir/../
pip install .
python $this_dir/../setup.py install
cd $this_dir
# Run unit tests
export SKIP_SYNTH_TESTS=1
pytest --workers auto
#export STUB_SIMULATOR=1
export NO_XSIM=1
pytest --workers auto --cov=peakrdl_regblock
# Generate coverage report
coverage html -i -d $this_dir/htmlcov
# Run lint
pylint --rcfile $this_dir/pylint.rc ../src/peakrdl_regblock

View File

@@ -31,4 +31,14 @@ addrmap regblock {
};
subrf sub2[2] @ 0x2000 += 0x40;
subreg r3 @ 0x2080;
reg {
field {} f1[19:12] = 0;
field {} f2[30:20] = 0;
} rw_reg @ 0x3000;
reg {
field {} f1[12:19] = 0;
field {} f2[20:30] = 0;
} rw_reg_lsb0 @ 0x3004;
};

View File

@@ -61,4 +61,20 @@
assert(cb.hwif_out.r2.a.value == 'h0);
assert(cb.hwif_out.r2.b.value == 'h0);
assert(cb.hwif_out.r2.c.value == 'h0);
// rw_reg
cpuif.assert_read('h3000, 0);
cpuif.write('h3000, 'h4DEAB000);
@cb;
assert(cb.hwif_out.rw_reg.f1.value == 8'hAB);
assert(cb.hwif_out.rw_reg.f2.value == 11'h4DE);
cpuif.assert_read('h3000, 'h4DEAB000);
// rw_reg_lsb0
cpuif.assert_read('h3004, 0);
cpuif.write('h3004, 'h4DEAB000);
@cb;
assert({<<{cb.hwif_out.rw_reg_lsb0.f1.value}} == 8'hAB);
assert({<<{cb.hwif_out.rw_reg_lsb0.f2.value}} == 11'h4DE);
cpuif.assert_read('h3004, 'h4DEAB000);
{% endblock %}

View File

@@ -19,7 +19,7 @@ class TestSynth(SynthTestCase):
self.run_synth()
@pytest.mark.skipif(os.environ.get("STUB_SIMULATOR", False), reason="user skipped")
@pytest.mark.skipif(os.environ.get("STUB_SIMULATOR", False) or os.environ.get("NO_XSIM", False), reason="user skipped")
@parameterized_class(TEST_PARAMS)
class TestVivado(SimTestCase):
"""

View File

View File

@@ -0,0 +1,93 @@
addrmap top {
reg {
regwidth = 64;
accesswidth = 16;
default sw=rw;
default hw=r;
field {} f1[7:0] = 0;
field {} f2[14:12] = 0;
field {} f3[36:36] = 0;
field {} f4[47:40] = 0;
} rw_reg1;
reg {
regwidth = 64;
accesswidth = 16;
default sw=rw;
default hw=r;
field {} f1[19:16] = 0;
field {} f2[63:48] = 0;
} rw_reg2;
reg {
regwidth = 64;
accesswidth = 16;
default sw=rw;
default hw=r;
field {} f1[0:7] = 0;
field {} f2[12:14] = 0;
field {} f3[36:36] = 0;
field {} f4[40:47] = 0;
} rw_reg1_lsb0;
reg {
regwidth = 64;
accesswidth = 16;
default sw=rw;
default hw=r;
field {} f1[16:19] = 0;
field {} f2[48:63] = 0;
} rw_reg2_lsb0;
reg {
regwidth = 32;
accesswidth = 16;
default sw=r;
default hw=w;
field {
sw=w; hw=r;
} f0[3:3] = 0;
field {} f1[19:12];
field {} f2[30:20];
} r_reg;
reg {
regwidth = 32;
accesswidth = 16;
default sw=r;
default hw=w;
field {} f1[12:19];
field {} f2[20:30];
} r_reg_lsb0;
reg {
regwidth = 64;
accesswidth = 16;
default sw=r;
default hw=w;
field {} f1[31:12];
field {} f2[49:48];
} r_reg2;
reg {
regwidth=16;
field {
sw=r; hw=na;
counter;
} f1_cnt[7:0] = 0;
field {
sw=r; hw=na;
counter;
} f2_cnt[15:8] = 0;
} counter_reg;
counter_reg.f1_cnt->incr = r_reg2.f1->swacc;
counter_reg.f2_cnt->incr = r_reg2.f2->swacc;
};

View File

@@ -0,0 +1,111 @@
{% extends "lib/tb_base.sv" %}
{% block seq %}
{% sv_line_anchor %}
##1;
cb.rst <= '0;
##1;
// rw_reg1
assert(cb.hwif_out.rw_reg1.f1.value == 0);
assert(cb.hwif_out.rw_reg1.f2.value == 0);
assert(cb.hwif_out.rw_reg1.f3.value == 0);
assert(cb.hwif_out.rw_reg1.f4.value == 0);
cpuif.write('h0, 'h1234);
cpuif.write('h2, 'h5678);
cpuif.write('h4, 'h9ABC);
cpuif.write('h6, 'hDEF1);
@cb;
assert(cb.hwif_out.rw_reg1.f1.value == 8'h34);
assert(cb.hwif_out.rw_reg1.f2.value == 3'h1);
assert(cb.hwif_out.rw_reg1.f3.value == 1'h1);
assert(cb.hwif_out.rw_reg1.f4.value == 8'h9A);
cpuif.assert_read('h0, 'h1034);
cpuif.assert_read('h2, 'h0000);
cpuif.assert_read('h4, 'h9A10);
cpuif.assert_read('h6, 'h0000);
// rw_reg2
assert(cb.hwif_out.rw_reg2.f1.value == 0);
assert(cb.hwif_out.rw_reg2.f2.value == 0);
cpuif.write('h8, 'h1234);
cpuif.write('hA, 'h5678);
cpuif.write('hC, 'h9ABC);
cpuif.write('hE, 'hDEF1);
@cb;
assert(cb.hwif_out.rw_reg2.f1.value == 4'h8);
assert(cb.hwif_out.rw_reg2.f2.value == 16'hDEF1);
cpuif.assert_read('h8, 'h0000);
cpuif.assert_read('hA, 'h0008);
cpuif.assert_read('hC, 'h0000);
cpuif.assert_read('hE, 'hDEF1);
// rw_reg1_lsb0
assert(cb.hwif_out.rw_reg1_lsb0.f1.value == 0);
assert(cb.hwif_out.rw_reg1_lsb0.f2.value == 0);
assert(cb.hwif_out.rw_reg1_lsb0.f3.value == 0);
assert(cb.hwif_out.rw_reg1_lsb0.f4.value == 0);
cpuif.write('h10, 'h1234);
cpuif.write('h12, 'h5678);
cpuif.write('h14, 'h9ABC);
cpuif.write('h16, 'hDEF1);
@cb;
assert({<<{cb.hwif_out.rw_reg1_lsb0.f1.value}} == 8'h34);
assert({<<{cb.hwif_out.rw_reg1_lsb0.f2.value}} == 3'h1);
assert({<<{cb.hwif_out.rw_reg1_lsb0.f3.value}} == 1'h1);
assert({<<{cb.hwif_out.rw_reg1_lsb0.f4.value}} == 8'h9A);
cpuif.assert_read('h10, 'h1034);
cpuif.assert_read('h12, 'h0000);
cpuif.assert_read('h14, 'h9A10);
cpuif.assert_read('h16, 'h0000);
// rw_reg2_lsb0
assert(cb.hwif_out.rw_reg2_lsb0.f1.value == 0);
assert(cb.hwif_out.rw_reg2_lsb0.f2.value == 0);
cpuif.write('h18, 'h1234);
cpuif.write('h1A, 'h5678);
cpuif.write('h1C, 'h9ABC);
cpuif.write('h1E, 'hDEF1);
@cb;
assert({<<{cb.hwif_out.rw_reg2_lsb0.f1.value}} == 4'h8);
assert({<<{cb.hwif_out.rw_reg2_lsb0.f2.value}} == 16'hDEF1);
cpuif.assert_read('h18, 'h0000);
cpuif.assert_read('h1A, 'h0008);
cpuif.assert_read('h1C, 'h0000);
cpuif.assert_read('h1E, 'hDEF1);
// r_reg
cpuif.assert_read('h20, 0);
cpuif.assert_read('h22, 0);
cb.hwif_in.r_reg.f1.next <= 8'hAB;
cb.hwif_in.r_reg.f2.next <= 11'h4DE;
@cb;
cpuif.assert_read('h20, 'hB000);
cpuif.assert_read('h22, 'h4DEA);
// r_reg_lsb0
cpuif.assert_read('h24, 0);
cpuif.assert_read('h26, 0);
cb.hwif_in.r_reg_lsb0.f1.next <= {<<{8'hAB}};
cb.hwif_in.r_reg_lsb0.f2.next <= {<<{11'h4DE}};
@cb;
cpuif.assert_read('h24, 'hB000);
cpuif.assert_read('h26, 'h4DEA);
// r_reg2
cpuif.assert_read('h28, 0);
cpuif.assert_read('h2a, 0);
cpuif.assert_read('h2c, 0);
cpuif.assert_read('h2e, 0);
cb.hwif_in.r_reg2.f1.next <= 20'hABCDE;
cb.hwif_in.r_reg2.f2.next <= 2'h3;
@cb;
cpuif.assert_read('h28, 'hE000);
cpuif.assert_read('h2a, 'hABCD);
cpuif.assert_read('h2c, 'h0000);
cpuif.assert_read('h2e, 'h0003);
// counter_reg
cpuif.assert_read('h30, 16'h0204);
{% endblock %}

View File

@@ -0,0 +1,5 @@
from ..lib.sim_testcase import SimTestCase
class Test(SimTestCase):
def test_dut(self):
self.run_test()