Add support for wide registers (where accesswidth < regwidth)
This commit is contained in:
18
tests/.coveragerc
Normal file
18
tests/.coveragerc
Normal 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
|
||||
@@ -4,3 +4,5 @@ pytest-parallel
|
||||
jinja2-simple-tags
|
||||
pylint
|
||||
mypy
|
||||
pytest-cov
|
||||
coverage
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
0
tests/test_wide_regs/__init__.py
Normal file
0
tests/test_wide_regs/__init__.py
Normal file
93
tests/test_wide_regs/regblock.rdl
Normal file
93
tests/test_wide_regs/regblock.rdl
Normal 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;
|
||||
};
|
||||
111
tests/test_wide_regs/tb_template.sv
Normal file
111
tests/test_wide_regs/tb_template.sv
Normal 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 %}
|
||||
5
tests/test_wide_regs/testcase.py
Normal file
5
tests/test_wide_regs/testcase.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from ..lib.sim_testcase import SimTestCase
|
||||
|
||||
class Test(SimTestCase):
|
||||
def test_dut(self):
|
||||
self.run_test()
|
||||
Reference in New Issue
Block a user