Add singlepulse support

This commit is contained in:
Alex Mykyta
2021-12-05 23:09:33 -08:00
parent 027ac99ead
commit f5b12253ad
8 changed files with 97 additions and 1 deletions

View File

@@ -17,7 +17,7 @@ See ``onread``
singlepulse
^^^^^^^^^^^
|NO|
|OK|
sw
^^^

View File

@@ -5,6 +5,7 @@ from systemrdl.rdltypes import PropertyReference, PrecedenceType
from .bases import AssignmentPrecedence, NextStateConditional
from . import sw_onread
from . import sw_onwrite
from . import sw_singlepulse
from . import hw_write
from . import hw_set_clr
@@ -189,6 +190,8 @@ class FieldLogic:
self.add_sw_conditional(sw_onwrite.WriteSet(self.exp), AssignmentPrecedence.SW_ONWRITE)
self.add_sw_conditional(sw_onwrite.Write(self.exp), AssignmentPrecedence.SW_ONWRITE)
self.add_sw_conditional(sw_singlepulse.Singlepulse(self.exp), AssignmentPrecedence.SW_SINGLEPULSE)
self.add_hw_conditional(hw_write.AlwaysWrite(self.exp), AssignmentPrecedence.HW_WRITE)
self.add_hw_conditional(hw_write.WELWrite(self.exp), AssignmentPrecedence.HW_WRITE)
self.add_hw_conditional(hw_write.WEWrite(self.exp), AssignmentPrecedence.HW_WRITE)

View File

@@ -24,6 +24,7 @@ class AssignmentPrecedence(enum.IntEnum):
# Software access assignment groups
SW_ONREAD = 5000
SW_ONWRITE = 4000
SW_SINGLEPULSE = 3000
# Hardware access assignment groups
HW_WRITE = 3000

View File

@@ -0,0 +1,23 @@
from typing import TYPE_CHECKING, List
from .bases import NextStateConditional
if TYPE_CHECKING:
from systemrdl.node import FieldNode
class Singlepulse(NextStateConditional):
comment = "singlepulse clears back to 0"
def is_match(self, field: 'FieldNode') -> bool:
return field.get_property('singlepulse')
def get_predicate(self, field: 'FieldNode') -> str:
# TODO: make exporter promote this to an "else"?
# Be mindful of sw/hw precedence. this would have to come last regardless
return "1"
def get_assignments(self, field: 'FieldNode') -> List[str]:
field_path = self.get_field_path(field)
return [
f"field_combo.{field_path}.next = '0;",
f"field_combo.{field_path}.load_next = '1;",
]

View File

View File

@@ -0,0 +1,8 @@
addrmap top {
reg {
field {
sw=rw; hw=r;
singlepulse;
} f[0:0] = 0;
} r1;
};

View File

@@ -0,0 +1,56 @@
{% extends "lib/templates/tb_base.sv" %}
{% block seq %}
{% sv_line_anchor %}
int event_count;
##1;
cb.rst <= '0;
##1;
// No pulse if writing zero
event_count = 0;
fork
begin
##0;
forever begin
@cb;
if(cb.hwif_out.r1.f.value) begin
event_count++;
end
end
end
begin
cpuif.write('h0, 'h0);
repeat(5) @cb;
end
join_any
disable fork;
assert(event_count == 0) else $error("Observed excess singlepulse events: %0d", event_count);
// single pulse
event_count = 0;
fork
begin
##0;
forever begin
@cb;
if(cb.hwif_out.r1.f.value) begin
event_count++;
end
end
end
begin
cpuif.write('h0, 'h1);
repeat(5) @cb;
end
join_any
disable fork;
assert(event_count == 1) else $error("Observed incorrect number of singlepulse events: %0d", event_count);
// auto-clears
cpuif.assert_read('h0, 'h0);
{% endblock %}

View File

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