Skip to content

Commit 489b4d1

Browse files
committed
Add 'rd_swacc' and 'wr_swacc' UDPs. #21
1 parent 17afaf1 commit 489b4d1

File tree

17 files changed

+243
-12
lines changed

17 files changed

+243
-12
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,4 @@ Links
123123
udps/intro
124124
udps/read_buffering
125125
udps/write_buffering
126+
udps/extended_swacc

docs/udps/extended_swacc.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.. _extended_swacc:
2+
3+
Read/Write-specific swacc
4+
=========================
5+
6+
SystemRDL defines the ``swacc`` property, but it does not distinguish between
7+
read and write operations - it is asserted on *all* software accesses.
8+
Similarly, the spec defines ``swmod`` which gets asserted on software writes,
9+
but can also get asserted if the field has on-read side-effects.
10+
11+
What if you just wanted a plan and simple strobe that is asserted when software
12+
reads or writes a field? The ``rd_swacc`` and ``wr_swacc`` UDPs provide this
13+
functionality.
14+
15+
16+
Properties
17+
----------
18+
These UDP definitions, along with others supported by PeakRDL-regblock can be
19+
enabled by compiling the following file along with your design:
20+
:download:`regblock_udps.rdl <../../hdl-src/regblock_udps.rdl>`.
21+
22+
``rd_swacc``
23+
If true, infers an output signal ``hwif_out..rd_swacc`` that is asserted
24+
when accessed by a software read operation. The output signal is asserted
25+
on the same clock cycle that the field is being sampled during the software
26+
read operation.
27+
28+
.. wavedrom::
29+
30+
{"signal": [
31+
{"name": "clk", "wave": "p...."},
32+
{"name": "hwif_in..next", "wave": "x.=x.", "data": ["D"]},
33+
{"name": "hwif_out..rd_swacc", "wave": "0.10."}
34+
]}
35+
36+
37+
``wr_swacc``
38+
If true, infers an output signal ``hwif_out..wr_swacc`` that is asserted
39+
as the field is being modified by a software write operation.
40+
41+
.. wavedrom::
42+
43+
{"signal": [
44+
{"name": "clk", "wave": "p....."},
45+
{"name": "hwif_out..value", "wave": "=..=..", "data": ["old", "new"]},
46+
{"name": "hwif_out..wr_swacc", "wave": "0.10.."}
47+
]}

docs/udps/intro.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,17 @@ To enable these UDPs, compile this RDL file prior to the rest of your design:
4646
- Defines the buffered write commit trigger.
4747

4848
See: :ref:`write_buffering`.
49+
50+
* - rd_swacc
51+
- field
52+
- boolean
53+
- Enables an output strobe that is asserted on sw reads.
54+
55+
See: :ref:`extended_swacc`.
56+
57+
* - wr_swacc
58+
- field
59+
- boolean
60+
- Enables an output strobe that is asserted on sw writes.
61+
62+
See: :ref:`extended_swacc`.

hdl-src/regblock_udps.rdl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,13 @@ property wbuffer_trigger {
2626
component = reg;
2727
type = ref;
2828
};
29+
30+
property rd_swacc {
31+
component = field;
32+
type = boolean;
33+
};
34+
35+
property wr_swacc {
36+
component = field;
37+
type = boolean;
38+
};

src/peakrdl_regblock/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.8.0"
1+
__version__ = "0.9.0"

src/peakrdl_regblock/dereferencer.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ def get_field_propref_value(self, field: FieldNode, prop_name: str) -> str:
161161
return self.field_logic.get_swacc_identifier(field)
162162
if prop_name == "swmod":
163163
return self.field_logic.get_swmod_identifier(field)
164+
if prop_name == "rd_swacc":
165+
return self.field_logic.get_rd_swacc_identifier(field)
166+
if prop_name == "wr_swacc":
167+
return self.field_logic.get_wr_swacc_identifier(field)
164168

165169

166170
# translate aliases

src/peakrdl_regblock/field_logic/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,30 @@ def get_swacc_identifier(self, field: 'FieldNode') -> str:
193193
strb = self.exp.dereferencer.get_access_strobe(field)
194194
return strb
195195

196+
def get_rd_swacc_identifier(self, field: 'FieldNode') -> str:
197+
"""
198+
Asserted when field is software accessed (read)
199+
"""
200+
buffer_reads = field.parent.get_property('buffer_reads')
201+
if buffer_reads:
202+
rstrb = self.exp.read_buffering.get_trigger(field.parent)
203+
return rstrb
204+
else:
205+
strb = self.exp.dereferencer.get_access_strobe(field)
206+
return f"{strb} && !decoded_req_is_wr"
207+
208+
def get_wr_swacc_identifier(self, field: 'FieldNode') -> str:
209+
"""
210+
Asserted when field is software accessed (write)
211+
"""
212+
buffer_writes = field.parent.get_property('buffer_writes')
213+
if buffer_writes:
214+
wstrb = self.exp.write_buffering.get_write_strobe(field)
215+
return wstrb
216+
else:
217+
strb = self.exp.dereferencer.get_access_strobe(field)
218+
return f"{strb} && decoded_req_is_wr"
219+
196220
def get_swmod_identifier(self, field: 'FieldNode') -> str:
197221
"""
198222
Asserted when field is modified by software (written or read with a

src/peakrdl_regblock/field_logic/generators.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,20 +224,33 @@ def assign_field_outputs(self, node: 'FieldNode') -> None:
224224
f"assign {output_identifier} = {value};"
225225
)
226226

227+
# Software access strobes
227228
if node.get_property('swmod'):
228229
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "swmod")
229230
value = self.field_logic.get_swmod_identifier(node)
230231
self.add_content(
231232
f"assign {output_identifier} = {value};"
232233
)
233-
234234
if node.get_property('swacc'):
235235
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "swacc")
236236
value = self.field_logic.get_swacc_identifier(node)
237237
self.add_content(
238238
f"assign {output_identifier} = {value};"
239239
)
240+
if node.get_property('rd_swacc'):
241+
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "rd_swacc")
242+
value = self.field_logic.get_rd_swacc_identifier(node)
243+
self.add_content(
244+
f"assign {output_identifier} = {value};"
245+
)
246+
if node.get_property('wr_swacc'):
247+
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "wr_swacc")
248+
value = self.field_logic.get_wr_swacc_identifier(node)
249+
self.add_content(
250+
f"assign {output_identifier} = {value};"
251+
)
240252

253+
# Counter thresholds
241254
if node.get_property('incrthreshold') is not False: # (explicitly not False. Not 0)
242255
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "incrthreshold")
243256
value = self.field_logic.get_field_combo_identifier(node, 'incrthreshold')
@@ -251,6 +264,7 @@ def assign_field_outputs(self, node: 'FieldNode') -> None:
251264
f"assign {output_identifier} = {value};"
252265
)
253266

267+
# Counter events
254268
if node.get_property('overflow'):
255269
output_identifier = self.exp.hwif.get_implied_prop_output_identifier(node, "overflow")
256270
value = self.field_logic.get_field_combo_identifier(node, 'overflow')

src/peakrdl_regblock/hwif/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def get_implied_prop_output_identifier(self, node: Union[FieldNode, RegNode], pr
190190
assert prop in {
191191
"anded", "ored", "xored", "swmod", "swacc",
192192
"incrthreshold", "decrthreshold", "overflow", "underflow",
193+
"rd_swacc", "wr_swacc",
193194
}
194195
elif isinstance(node, RegNode):
195196
assert prop in {

src/peakrdl_regblock/hwif/generators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def enter_Field(self, node: 'FieldNode') -> None:
128128
self.add_member("value", node.width)
129129

130130
# Generate output bit signals enabled via property
131-
for prop_name in ["anded", "ored", "xored", "swmod", "swacc", "overflow", "underflow"]:
131+
for prop_name in ["anded", "ored", "xored", "swmod", "swacc", "overflow", "underflow", "rd_swacc", "wr_swacc"]:
132132
if node.get_property(prop_name):
133133
self.add_member(prop_name)
134134

0 commit comments

Comments
 (0)