move docs

This commit is contained in:
Alex Mykyta
2021-12-12 17:10:32 -08:00
parent 3dee090467
commit ee8d74b455
37 changed files with 32 additions and 114 deletions

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

9
docs/addressing.rst Normal file
View File

@@ -0,0 +1,9 @@
CPU Interface Addressing
========================
TODO: write about the following:
* cpuif addressing is always 0-based (aka relative to the block's root)
* It is up to the decoder to handle the offset
* Address bus width is pruned down
* recommend that the decoder/interconnect reserve a full ^2 block of addresses to simplify decoding

26
docs/architecture.rst Normal file
View File

@@ -0,0 +1,26 @@
Register Block Architecture
===========================
TODO: Add full block diagram
CPU Interface
-------------
TODO: describe boundary signals. Timing diagrams
Address Decode
--------------
TODO: describe boundary signals. Timing diagrams
Field Logic
-----------
TODO: describe boundary signals. Timing diagrams
Readback
--------
TODO: describe boundary signals. Timing diagrams
Retiming options

77
docs/conf.py Normal file
View File

@@ -0,0 +1,77 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import datetime
# -- Project information -----------------------------------------------------
project = 'PeakRDL-regblock'
copyright = '%d, Alex Mykyta' % datetime.datetime.now().year
author = 'Alex Mykyta'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinxcontrib.wavedrom",
]
render_using_wavedrompy = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []
rst_epilog = """
.. |iERR| image:: /img/err.svg
:width: 18px
:class: no-scaled-link
.. |iWARN| image:: /img/warn.svg
:width: 18px
:class: no-scaled-link
.. |iOK| image:: /img/ok.svg
:width: 18px
:class: no-scaled-link
.. |NO| replace:: |iERR| Not Supported
.. |EX| replace:: |iWARN| Experimental
.. |OK| replace:: |iOK| Supported
"""

7
docs/cpuif/advanced.rst Normal file
View File

@@ -0,0 +1,7 @@
Advanced Topics
===============
TODO:
* How to override an interface's name, modport, signal names, whatever
* Creating your own custom CPU interface definition

11
docs/cpuif/apb3.rst Normal file
View File

@@ -0,0 +1,11 @@
AMBA APB3
=========
TODO: Describe the following
* List of interface signals
* interface name & modports (link to advanced topics in case user wants to override)
* flattened equivalents
* Download link to SV interface definition

View File

@@ -0,0 +1,10 @@
Holy smokes this is complicated
Keep this exporter in Alpha/Beta for a while
Add some text in the readme or somewhere:
- No guarantees of correctness! This is always true with open source software,
but even more here!
Be sure to do your own validation before using this in production.
- Alpha means the implementation may change drastically!
Unlike official sem-ver, I am not making any guarantees on compatibility
- I need your help! Validating, finding edge cases, etc...

View File

@@ -0,0 +1,67 @@
--------------------------------------------------------------------------------
Preserve Hierarchy
--------------------------------------------------------------------------------
I *reaaaally* want to be able to make deferred RDL parameters a reality in the
future. (https://github.com/SystemRDL/systemrdl-compiler/issues/58)
Proactively design templates to retain "real" hierarchy. This means:
- Do not flatten/unroll signals. Use SV structs & arrays
- Do not flatten/unroll logic. Use nested for loops
Sticking to the above should make adding parameter support somewhat less painful.
--------------------------------------------------------------------------------
Indexing & references
--------------------------------------------------------------------------------
Need to define a consistent scheme for referencing hierarchical elements.
When inside a nesting of for loops, and array indexes are intended to increment,
always use an incrementing indexing scheme when generating iterators:
i0, i1, i2, i3, ... i9, i10, i11, etc...
For example:
access_strb.2d_array[i0][i1].array[i3]
Sometimes, an RDL input may create the need to reference an element with
partially constant indexes.
For example, given this RDL:
addrmap top {
regfile {
reg {
field {} f1;
} x[8];
reg {
field {} f2;
} y;
y.f2->next = x[3].f1;
} rf_loop[16];
};
The 'next' assignment will have a reference that has the following hierarchcial
path:
top.rf_loop[].x[3].f1
| |
| +--- known index
+--- unknown index
It is provable that any RDL references will always follow these truths:
- a reference may have a mix of known/unknown indexes in its path
- unknown indexes (if any) will always precede known indexes
- unknown indexes are not actually part of the relative reference path, and
represent replication of the reference.
It is impossible for the reference itself to introduce unknown indexes.
When generating SystemVerilog, be sure to generate code such that "unknown" indexes
are always implicitly known due to the reference being used from within a for loop.
For example:
for(int i0=0; i0<16; i0++) begin : rf_loop_array
top.rf_loop[i0].y.f2 = top.rf_loop[i0].x[3].f1
end
This should be a reasonable thing to accomplish, since unknown indexes should
only show up in situations where the consumer of the reference is being
replicated as well, and is therefore implicitly going to be inside a for loop.

18
docs/dev_notes/Interrupts Normal file
View File

@@ -0,0 +1,18 @@
Interrupts seem to be pretty well-described.
Basically...
- If a register contains one or more fields that use the intr property,
then it is implied to be an interrupt register
--> Add RegNode.has_intr and RegNode.has_halt properties?
- This register implies that there is an output irq signal that is propagated to the top, and it is the OR of all interrupt field bits
- BUT in the multilevel interrupt example, perhaps this output gets suppressed?
Suppress the output signal if Reg->intr gets referenced, since this means
the user is doing a multi-level interrupt.
This means that the register's interrupt signal is "consumed" by a second-level interrupt register
- WTF about the "halt" concept?
I assume this does NOT auto-imply an output?
Mayby only imply a default halt output if:
- an interrupt register has fields that use haltenable/haltmask
- AND the interrupt register's reg->halt has not been referenced

View File

@@ -0,0 +1,23 @@
1. Scan design. Collect information
- Check for unsupported constructs. Throw errors as appropriate
- Uniform regwidth, accesswidth, etc.
- Collect reset signals
cpuif_reset, field_reset
explicitly assigned to field->resetsignal
- Collect any other misc user signals that are referenced in the design
- Top-level interrupts
Collect X & Y:
X = set of all registers that have an interrupt field
Y = set of all interrupt registers that are referenced by a field
Top level interrupt registers are the set in X, but not in Y
(and probably other caveats. See notes)
2. Create intermediate template objects
3. Render top-level IO struct package (if applicable)
4. Render top-level module template

11
docs/dev_notes/Resets Normal file
View File

@@ -0,0 +1,11 @@
================================================================================
Resets
================================================================================
use whatever is defined in RDL based on cpuif_reset and field_reset signals
Otherwise, provide configuration that defines what the default is:
a single reset that is active high/low, or sync/async
If cpuif_reset is specified, what do fields use?
I assume they still use the default reset separately?
YES. Agnisys appears to be wrong.
cpuif_reset has no influence on the fields' reset according to the spec

View File

@@ -0,0 +1,22 @@
I need some sort of signal "dereferencer" that can be easily used to translate references
to stuff via a normalized interface.
For example, if RDL defines:
my_field->next = my_other_field
Then in Python (or a template) I could do:
x = my_field.get_property('next')
y = dereferencer.get(x)
and trust that I'll get a value/identifier/whatever that accurately represents
the value being referenced
Values:
If X is a field reference:
... that implements storage, return its DFF value reference
... no storage, but has a hw input, grab from the hwif input
... no storage, and no hw input, return its constant reset value?
If X is a property reference... do whats right...
my_field->anded === (&path.to.my_field)
if X is a static value, return the literal
See `Hierarchy and Indexing` on details on how to build path references to stuff

View File

@@ -0,0 +1,45 @@
================================================================================
Signal wrapper classes
================================================================================
Define a signal wrapper class that is easier to use in templates.
Provides the following properties:
.is_async
.is_activehigh
.identifier
Returns the Verilog identifier string for this signal
.activehigh_identifier
Normalizes identifier to active-high logic
same as .identifier, but prepends '~' if is_activehigh = False
.width
Default reset class instance:
Extends the base class
Hardcodes as follows:
.is_async = True
.is_activehigh = True
.identifier = "rst"
.width = 1
Wrapper classes
Wrap around a systemrdl.SignalNode
================================================================================
CPU Interface Class
================================================================================
Entry point class for a given CPU interface type (APB, AXI, etc..)
Does the following:
- Provide linkage to the logic implementation Jinja template
- Interface signal identifier properties
Aliases for signal identifiers to allow flat or sv-interface style
eg:
self.psel --> "s_apb_psel" or "s_apb.psel"
if sv interface, use the interface name class prpoerty
- Port declaration text property
declare as sv interface, or flat port list
If flattened, should use signal identifier properties
If sv interface, I should breakout the interface & modport name as
class properties for easy user-override

View File

@@ -0,0 +1,168 @@
================================================================================
Things that need validation by the compiler
================================================================================
Many of these are probably already covered, but being paranoid.
Make a list of things as I think of them.
Keep them here in case I forget and re-think of them.
Mark these as follows:
X = Yes, confirmed that the compiler covers this
! = No! Confirmed that the compiler does not check this, and should.
? = TBD
--------------------------------------------------------------------------------
X resetsignal width
reset signals shall have width of 1
X Field has no knowable value
- does not implement storage
- hw is not writable
- sw is readable
- No reset value specified
--> emit a warning?
X References to a component or component property must use unambiguous array indexing
For example, if "array_o_regs" is an array...
The following is illegal:
my_reg.my_field->next = array_o_regs.thing
my_reg.my_field->next = array_o_regs.thing->anded
This is ok:
my_reg.my_field->next = array_o_regs[2].thing
my_reg.my_field->next = array_o_regs[2].thing->anded
NEVERMIND - compiler does not allow indefinite array references at all!
References are guaranteed to be unambiguous:
"Incompatible number of index dimensions after 'CTRL'. Expected 1, found 0."
X Clause 10.6.1-f (wide registers cannot have access side-effects)
X multiple field_reset in the same hierarchy
there can only be one signal declared with field_reset
in a given hierarchy
X multiple cpuif_reset in the same hierarchy
there can only be one signal declared with cpuif_reset
in a given hierarchy
X Mutually-exclusive property checking
--> Yes. compiler now auto-clears mutex partners on assign, so it is
implicitly handled
X incrwidth/incrvalue & decrvalue/decrwidth
these pairs are mutually exclusive.
Make sure they are not both set after elaboration
Compiler checks for mutex within the same scope, but
i dont think I check for mutexes post-elaborate
... or, make these properties clear each-other on assignment
X Illegal property references:
- reference any of the counter property references to something that isn't a counter
decrsaturate / incrsaturate / saturate
overflow / underflow
- reference hwclr or hwset, but the owner node has them set to False
means that the actual inferred signal doesnt exist!
- reference swwe/swwel or we/wel, but the owner node has them, AND their complement set to False
means that the actual inferred signal doesnt exist!
- only valid to reference if owner has this prop set
enable/mask
haltenable/haltmask
hwenable
hwmask
decr/incr, decr../incrthreshold/..value
- others references that may not always make sense:
intr/halt - target must contain interrupt/halt fields
next
is this ever illegal?
X If a node ispresent=true, and any of it's properties are a reference,
then those references' ispresent shall also be true
This is an explicit clause in the spec: 5.3.1-i
X Flag illegal sw actions if not readable/writable
The following combinations dont get flagged currently:
sw=w; rclr;
sw=w; rset;
sw=r; woset;
sw=r; woclr;
their counterparts do get flagged. such as:
sw=w; onread=rclr;
X Signals marked as field_reset or cpuif_reset need to have activehigh/activelow
specified. (8.2.1-d states that activehigh/low does not have an implied default state if unset!)
Also applies to signals referenced by resetsignal
! hwclr/hwset/we/wel probably shouldn't be able to reference itself
y->hwclr = y;
y->we = y;
... it works, but should it be allowed? Seems like user-error
X incrvalue/decrvalue needs to be the same or narrower than counter itself
! singlepulse and next properties cannot both be used.
Both are hard overrides of the field's next value.
singlepulse is basically an alias for next=0 that takes lowest priority
! counter field that saturates should not set overflow
counter; incrsaturate; overflow;
counter; decrsaturate; underflow;
Flag this as an error on the overflow/underflow property.
overflow/underflow property is meaningless since it can never happen.
Same goes to prop references to overflow/underflow
! incrwidth/decrwidth must be between 1 and the width of the counter
================================================================================
Things that need validation by this exporter
================================================================================
List of stuff in case I forget.
X = Yes! I already implemented this.
! = No! exporter does not enforce this yet
--------------------------------------------------------------------------------
X Contents of target are all internal. No external regs
X Does not contain any mem components
X Warn/error on any signal with cpuif_reset set, that is not in the top-level
addrmap. At the very least, warn that it will be ignored
! "bridge" addrmap not supported
export shall refuse to process an addrmap marked as a "bridge"
Only need to check top-level. Compiler will enforce that child nodes arent bridges
! async data signals
Only supporting async signals if they are exclusively used in resets.
Anyhting else declared as "async" shall emit a warning that it is ignored
I have zero interest in implementing resynchronizers
! Error if a property references a non-signal component, or property reference from
outside the export hierarchy
! regwidth/accesswidth is sane
! accesswidth == regwidth
Enforce this for now. Dont feel like supporting fancy modes yet
X regwidth < accesswidth
This is illegal and is enforced by the compiler.
! regwidth > accesswidth
Need to extend address decode strobes to have multiple bits
this is where looking at endinaness matters to determine field placement
Dont feel like supporting this yet
! constant regwidth?
For now, probably limit to only allow the same regwidth everywhere?
! Do not allow unaligned addresses
All offsets & strides shall be a multiple of the regwidth used
- each reg needs to be aligned to its width
- each regfile/addrmap/stride shall be aligned to the largest regwidth it encloses
--> Should i promote this check to the compiler? At least as a warnable condition
Currently i think I only do the more stringent case of block alignment.

View File

@@ -0,0 +1,51 @@
--------------------------------------------------------------------------------
Port Declaration
--------------------------------------------------------------------------------
Generates the port declaration of the module:
- Parameters
- rd/wr error response/data behavior
Do missed accesses cause a SLVERR?
Do reads respond with a magic value?
- Pipeline enables
Enable reg stages in various places
- RDL-derived Parameters:
Someday in the future if i ever get around to this: https://github.com/SystemRDL/systemrdl-compiler/issues/58
- Clock/Reset
Single clk
One or more resets
- CPU Bus Interface
Given the bus interface object, emits the IO
This can be flattened ports, or a SV Interface
Regardless, it shall be malleable so that the user can use their favorite
declaration style
- Hardware interface
Two options:
- 2-port struct interface
Everything is rolled into two unpacked structs - inputs and outputs
- Flattened --> NOT DOING
Flatten/Unroll everything
No. not doing. I hate this and dont want to waste time implementing this.
This will NEVER be able to support parameterized regmaps, and just
creates a ton of corner cases i dont care to deal with.
Other IO Signals I need to be aware of:
any signals declared, and used in any references:
field.resetsignal
field.next
... etc ...
any signals declared and marked as cpuif_reset, or field_reset
These override the default rst
If both are defined, be sure to not emit the default
Pretty straightforward (see 17.1)
Also have some notes on this in my general Logbook
Will have to make a call on how these propagate if multiple defined
in different hierarchies
interrupt/halt outputs
See "Interrupts" logbook for explanation
addrmap.errextbus, regfile.errextbus, reg.errextbus
???
Apparently these are inputs

View File

@@ -0,0 +1,77 @@
================================================================================
Summary
================================================================================
RTL interface that provides access to per-field context signals
Regarding signals:
I think RDL-declared signals should actually be part of the hwif input
structure.
Exceptions:
- if the signal instance is at the top-level, it will get promoted to the
top level port list for convenience, and therefore omitted from the struct
================================================================================
Naming Scheme
================================================================================
hwif_out
.my_regblock
.my_reg[X][Y]
.my_field
.value
.anded
hwif_in
.my_regblock
.my_reg[X][Y]
.my_field
.value
.we
.my_signal
.my_fieldreset_signal
================================================================================
Flattened mode? --> NO
================================================================================
If user wants a flattened list of ports,
still use the same hwif_in/out struct internally.
Rather than declaring hwif_in and hwif_out in the port list, declare it internally
Add a mapping layer in the body of the module that performs a ton of assign statements
to map flat signals <-> struct
Alternatively, don't do this at all.
If I want to add a flattened mode, generate a wrapper module instead.
Marking this as YAGNI for now.
================================================================================
IO Signals
================================================================================
Outputs:
field value
If hw readable
bitwise reductions
if anded, ored, xored == True, output a signal
swmod/swacc
event strobes
Inputs:
field value
If hw writable
we/wel
if either is boolean, and true
not part of external hwif if reference
mutually exclusive
hwclr/hwset
if either is boolean, and true
not part of external hwif if reference
incr/decr
if counter=true, generate BOTH
incrvalue/decrvalue
if either incrwidth/decrwidth are set
signals!
any signal instances instantiated in the scope

View File

@@ -0,0 +1,72 @@
--------------------------------------------------------------------------------
CPU Bus interface layer
--------------------------------------------------------------------------------
Provides an abstraction layer between the outside SoC's bus interface, and the
internal register block's implementation.
Converts a user-selectable bus protocol to generic register file signals.
Upstream Signals:
Signal names are defined in the bus interface class and shall be malleable
to the user.
User can choose a flat signal interface, or a SV interface.
SV interface shall be easy to tweak since various orgs will use different
naming conventions in their library of interface definitions
Downstream Signals:
- cpuif_req
- Single-cycle pulse
- Qualifies the following child signals:
- cpuif_req_is_wr
1 denotes this is a write transfer
- cpuif_addr
Byte address
- cpuif_wr_data
- cpuif_wr_biten
per-bit strobes
some protocols may opt to tie this to all 1's
- cpuif_rd_ack
- Single-cycle pulse
- Qualifies the following child signals:
- cpuif_rd_data
- cpuif_rd_err
- cpuif_wr_ack
- Single-cycle pulse
- Qualifies the following child signals:
- cpuif_wr_err
Misc thoughts
- Internal cpuif_* signals use a strobe-based protocol:
- Unknown, but fixed latency
- Makes for easy pipelining if needed
- Decided to keep cpuif_req signals common for read write:
This will allow address decode logic to be shared for read/write
Downside is split protocols like axi-lite can't have totally separate rd/wr
access lanes, but who cares?
- separate response strobes
Not necessary to use, but this lets me independently pipeline read/write paths.
read path will need more time if readback mux is large
- On multiple outstanding transactions
Currently, cpuif doesnt really support this. Goal was to make it easily pipelineable
without having to backfeed stall logic.
Could still be possible to do a "fly-by" pipeline with a more intelligent cpuif layer
Not worrying about this now.
Implementation:
Implement this mainly as a Jinja template.
Upstream bus intf signals are fetched via busif class properties. Ex:
{{busif.signal('pready')}} <= '1;
This allows the actual SV or flattened signal to be emitted
What protocols do I care about?
- AXI4 Lite
- Ignore AxPROT?
- APB3
- APB4
- Ignore pprot?
- AHB?
- Wishbone
- Generic
breakout the above signals as-is (reassign with a prefix or something)

View File

@@ -0,0 +1,51 @@
--------------------------------------------------------------------------------
Address Decode layer
--------------------------------------------------------------------------------
A bunch of combinational address decodes that generate individual register
req strobes
Possible decode logic styles:
- Big case statement
+ Probably more sim-efficient
- Hard to do loop parameterization
- More annoying to do multiple regs per address
- Big always_comb + One if/else chain
+ Easy to nest loops & parameterize if needed
- sim has a lot to evaluate each time
- More annoying to do multiple regs per address
- implies precedence? Synth tools should be smart enough?
- Big always_comb + inline conditionals <---- DO THIS
+ Easy to nest loops & parameterize if needed
- sim has a lot to evaluate each time
+ Multiple regs per address possible
+ implies address decode parallelism.
?? Should I try using generate loops + assigns?
This would be more explicit parallelism, however some tools may
get upset at multiple assignments to a common struct
Implementation:
Jinja is inappropriate here
Very logic-heavy. Jinja may end up being annoying
Also, not much need for customization here
This may even make sense as a visitor that dumps lines
- visit each reg
- upon entering an array, create for loops
- upon exiting an array, emit 'end'
Make the strobe struct declared locally
No need for it to leave the block
Error handling
If no strobe generated, respond w error?
This is actually pretty expensive to do for writes.
Hold off on this for now.
Reads get this effectively for free in the readback mux.
Implement write response strobes back upstream to cpuif
Eventually allow for optional register stage for strobe struct
Will need to also pipeline the other cpuif signals
ok to discard the cpuif_addr. no longer needed
Downstream Signals:
- access strobes
Encase these into a struct datatype
- is_write + wr_data/wr_bitstrobe

View File

@@ -0,0 +1,163 @@
--------------------------------------------------------------------------------
Field storage / next value layer
--------------------------------------------------------------------------------
Where all the magic happens!!
Any field that implements storage is defined here.
Bigass struct that only contains storage elements
Each field consists of:
- Entries in the storage element struct
- if implements storage - field value
- user extensible values?
- Entries in the combo struct
- if implements storage:
- Field's "next" value
- load-enable strobe
- If counter
various event strobes (overflow/overflow).
These are convenient to generate alongside the field next state logic
- user extensible values?
- an always_comb block:
- generates the "next value" combinational signal
- May generate other intermediate strobes?
incr/decr?
- series of if/else statements that assign the next value in the storage element
Think of this as a flat list of "next state" conditons, ranked by their precedence as follows:
- reset
Actually, handle this in the always_ff
- sw access (if sw precedence)
- onread/onwrite
- hw access
- Counter
beware of clear events and incr/decr events happening simultaneously
- next
- etc
- sw access (if hw precedence)
- onread/onwrite
- always_comb block to also generate write-enable strobes for the actual
storage element
This is better for low-power design
- an always_ff block
Implements the actual storage element
Also a tidy place to abstract the specifics of activehigh/activelow field reset
selection.
TODO:
Scour the RDL spec.
Does this "next state" precedence model hold true in all situations?
TODO:
Think about user-extensibility
Provide a mechanism for users to extend/override field behavior
TODO:
Does the endinness the user sets matter anywhere?
Implementation
Makes sense to use a listener class
Be sure to skip alias registers
--------------------------------------------------------------------------------
NextStateConditional Class
Decribes a single conditional action that determines the next state of a field
Provides information to generate the following content:
if(<conditional>) begin
<assignments>
end
- is_match(self, field: FieldNode) -> bool:
Returns True if this conditional is relevant to the field. If so,
it instructs the FieldBuider that code for this conditional shall be emitted
TODO: better name than "is_match"? More like "is this relevant"
- get_predicate(self, field: FieldNode) -> str:
Returns the rendered conditional text
- get_assignments(self, field: FieldNode) -> List[str]:
Returns a list of rendered assignment strings
This will basically always be two:
<field>.next = <next value>
<field>.load_next = '1;
- get_extra_combo_signals(self, field: FieldNode) -> List[TBD]:
Some conditionals will need to set some extra signals (eg. counter underflow/overflow strobes)
Compiler needs to know to:
- declare these inthe combo struct
- initialize them in the beginning of always_comb
Return something that denotes the following information: (namedtuple?)
- signal name: str
- width: int
- default value assignment: str
Multiple NextStateConditional can declare the same extra combo signal
as long as their definitions agree
--> Assert this
FieldBuilder Class
Describes how to build fields
Contains NextStateConditional definitions
Nested inside the class namespace, define all the NextStateConditional classes
that apply
User can override definitions or add own to extend behavior
NextStateConditional objects are stored in a dictionary as follows:
_conditionals {
assignment_precedence: [
conditional_option_3,
conditional_option_2,
conditional_option_1,
]
}
add_conditional(self, conditional, assignment_precedence):
Inserts the NextStateConditional into the given assignment precedence bin
The last one added to a precedence bin is first in that bin's search order
init_conditionals(self) -> None:
Called from __init__.
loads all possible conditionals into self.conditionals list
This function is to provide a hook for the user to add their own.
Do not do fancy class intospection. Load them explicitly by name like so:
self.add_conditional(MyNextState(), AssignmentPrecedence.SW_ACCESS)
If user wants to extend this class, they can pile onto the bins of conditionals freely!
--------------------------------------------------------------------------------
Misc
--------------------------------------------------------------------------------
What about complex behaviors like a read-clear counter?
if({{software read}})
next = 0
elif({{increment}})
next = prev + 1
--> Implement this by stacking multiple NextStateConditional in the same assignment precedence.
In this case, there would be a special action on software read that would be specific to read-clear counters
this would get inserted ahead of the search order.
Precedence & Search order
There are two layers of priority I need to keep track of:
- Assignment Precedence
RTL precedence of the assignment conditional
- Search order (sp?)
Within an assignment precedence, order in which the NextStateConditional classes are
searched for a match
For assignment precedence, it makes sense to use an integer enumeration for this
since there really aren't too many precedence levels that apply here.
Space out the integer enumerations so that user can reliably insert their own actions, ie:
my_precedence = AssignmentPrecedence.SW_ACCESS + 1
For search order, provide a user API to load a NextStateConditional into
a precedence 'bin'. Pushing into a bin always inserts into the front of the search order
This makes sense since user overrides will always want to be highest priority - and
rule themselves out before falling back to builtin behavior

View File

@@ -0,0 +1,69 @@
--------------------------------------------------------------------------------
Readback mux layer
--------------------------------------------------------------------------------
Implementation:
- Big always_comb block
- Initialize default rd_data value
- Lotsa if statements that operate on reg strb to assign rd_data
- Merges all fields together into reg
- pulls value from storage element struct, or input struct
- Provision for optional flop stage?
Mux Strategy:
Flat case statement:
-- Cant parameterize
+ better performance?
Flatten array then mux:
- First, flatten ALL readback values into an array
Round up the size of the array to next ^2
needs to be fully addressable anyways!
This can be in a combinational block
Initialize the array to the default readback value
then, assign all register values. Use loops where necessary.
Append an extra 'is-valid' bit if I need to slverr on bad reads
- Next, use the read address as an index into this array
- If needed, I can do a staged decode!
Compute the most balanced fanin staging in Python. eg:
64 regs --mux--> 8x8 --mux--> 1
128 regs --mux--> 8x16 --mux--> 1
Favor smaller fanin first. Latter stage should have more fanin since routing congestion will be easier
256 regs --mux--> 16x16 --mux--> 1
- Potential sparseness of this makes me uncomfortable,
but its synthesis SEEMS like it would be really efficient!
- TODO: Rethink this
I feel like people will complain about this
It will likely also be pretty sim-inefficient?
Flat 1-hot array then OR reduce: <-- DO THIS
- Create a bus-wide flat array
eg: 32-bits x N readable registers
- Assign each element:
the readback value of each register
... masked by the register's access strobe
- I could also stuff an extra bit into the array that denotes the read is valid
A missed read will OR reduce down to a 0
- Finally, OR reduce all the elements in the array down to a flat 32-bit bus
- Retiming the large OR fanin can be done by chopping up the array into stages
for 2 stages, sqrt(N) gives each stage's fanin size. Round to favor
more fanin on 2nd stage
3 stages uses cube-root. etc...
- This has the benefit of re-using the address decode logic.
synth can choose to replicate logic if fanout is bad
WARNING:
Beware of read/write flop stage asymmetry & race conditions.
Eg. If a field is rclr, dont want to sample it after it gets read:
addr --> strb --> clear
addr --> loooong...retime --> sample rd value
Should guarantee that read-sampling happens at the same cycle as any read-modify
Forwards response strobe back up to cpu interface layer
TODO:
Dont forget about alias registers here
TODO:
Does the endinness the user sets matter anywhere?

View File

@@ -0,0 +1,9 @@
--------------------------------------------------------------------------------
Output Port mapping layer
--------------------------------------------------------------------------------
Assign to output struct port
Still TBD if this will actually be a distinct layer.
Cosmetically, this might be nicer to interleave with the field section above
Assign storage element & other derived values as requested by properties

8
docs/hwif.rst Normal file
View File

@@ -0,0 +1,8 @@
Hardware Interface
------------------
TODO: Describe the following
* hwif_in / hwif_out structs and their contents
* shorthand notation used in this reference: ``hwif_in..xyz``
* Example of how to peel back a sub-hierarchy struct

53
docs/img/err.svg Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 512 512"
version="1.1"
id="svg4"
sodipodi:docname="times-circle.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="983"
id="namedview6"
showgrid="false"
inkscape:zoom="0.4609375"
inkscape:cx="18.440678"
inkscape:cy="245.15254"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) -->
<path
d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"
id="path2"
style="fill:#b40000;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

53
docs/img/ok.svg Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 512 512"
version="1.1"
id="svg4"
sodipodi:docname="check-circle.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="983"
id="namedview6"
showgrid="false"
inkscape:zoom="0.4609375"
inkscape:cx="-402.44068"
inkscape:cy="247.32203"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) -->
<path
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
id="path2"
style="fill:#00b405;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

53
docs/img/warn.svg Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 576 512"
version="1.1"
id="svg4"
sodipodi:docname="exclamation-triangle.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="983"
id="namedview6"
showgrid="false"
inkscape:zoom="0.4609375"
inkscape:cx="46.101695"
inkscape:cy="256"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) -->
<path
d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
id="path2"
style="fill:#ffa705;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

58
docs/index.rst Normal file
View File

@@ -0,0 +1,58 @@
PeakRDL-regblock
================
.. important::
This project has no official releases yet and is still under active development!
TODO: Intro text
Installing
----------
Install from `PyPi`_ using pip
.. code-block:: bash
python3 -m pip install peakrdl-regblock
.. _PyPi: https://pypi.org/project/peakrdl-regblock
Links
-----
- `Source repository <https://github.com/SystemRDL/PeakRDL-regblock>`_
- `Release Notes <https://github.com/SystemRDL/PeakRDL-regblock/releases>`_
- `Issue tracker <https://github.com/SystemRDL/PeakRDL-regblock/issues>`_
- `PyPi <https://pypi.org/project/peakrdl-regblock>`_
- `SystemRDL Specification <http://accellera.org/downloads/standards/systemrdl>`_
.. toctree::
:hidden:
self
architecture
hwif
limitations
.. toctree::
:hidden:
:caption: CPU Interfaces
cpuif/apb3
cpuif/advanced
.. toctree::
:hidden:
:caption: Property Support
props/field
props/reg
props/addrmap
props/signal
props/rhs_props

31
docs/limitations.rst Normal file
View File

@@ -0,0 +1,31 @@
Known Issues & Limitations
==========================
Not all SystemRDL features are supported by this exporter. For a listing of
supported properties, see the appropriate property listing page in the following
sections.
External Components
-------------------
Regfiles, registers & fields instantiated using the ``external`` keyword are not supported yet.
Alias Registers
---------------
Registers instantiated using the ``alias`` keyword are not supported yet.
Unaligned Registers
-------------------
All address offsets & strides shall be a multiple of the regwidth used. Specifically:
* Each register's address and array stride shall be aligned to it's regwidth.
* Each regfile or addrmap shall use an offset and stride that is a multiple of the largest regwidth it encloses.
No partial writes
-----------------
Some protocols describe byte-level write strobes. These are not supported yet.
All write transfers must access the entire register width.

28
docs/props/addrmap.rst Normal file
View File

@@ -0,0 +1,28 @@
Addrmap/Regfile Properties
==========================
.. note:: Any properties not explicitly listed here are either implicitly
supported, or are not relevant to the regblock exporter and are ignored.
errextbus
---------
|NO|
sharedextbus
------------
|NO|
--------------------------------------------------------------------------------
Addrmap Properties
==================
bigendian/littleendian
----------------------
|NO|
rsvdset
-------
|NO|

453
docs/props/field.rst Normal file
View File

@@ -0,0 +1,453 @@
Field Properties
================
.. note:: Any properties not explicitly listed here are either implicitly
supported, or are not relevant to the regblock exporter and are ignored.
Software Access Properties
--------------------------
onread/onwrite
^^^^^^^^^^^^^^
|OK|
rclr/rset
^^^^^^^^^
See ``onread``
singlepulse
^^^^^^^^^^^
|OK|
If set, field will get cleared back to zero after being written.
.. wavedrom::
{signal: [
{name: 'clk', wave: 'p.....'},
{name: '<swmod>', wave: '0.10..'},
{name: 'hwif_out..value', wave: '0..10.'}
]}
sw
^^^
|OK|
swacc
^^^^^
|OK|
If true, infers an output signal ``hwif_out..swacc`` that is asserted on the
same clock cycle that the field is being sampled during a software read
operation.
.. wavedrom::
{signal: [
{name: 'clk', wave: 'p....'},
{name: 'hwif_in..value', wave: 'x.=x.', data: ['D']},
{name: 'hwif_out..swacc', wave: '0.10.'}
]}
swmod
^^^^^
|OK|
If true, infers an output signal ``hwif_out..swmod`` that is asserted as the
field is being modified by software.
.. wavedrom::
{signal: [
{name: 'clk', wave: 'p.....'},
{name: 'hwif_out..value', wave: '=..=..', data: ['old', 'new']},
{name: 'hwif_out..swmod', wave: '0.10..'}
]}
swwe/swwel
^^^^^^^^^^
Provides a mechanism that allows hardware to override whether the field is
writable by software.
boolean
|OK|
If True, infers an input signal ``hwif_in..swwe`` or ``hwif_in..swwel``.
reference
|OK|
woclr/woset
^^^^^^^^^^^
See ``onwrite``
--------------------------------------------------------------------------------
Hardware Access Properties
--------------------------
anded/ored/xored
^^^^^^^^^^^^^^^^
|OK|
If true, infers the existence of output signal: ``hwif_out..anded``,
``hwif_out..ored``, ``hwif_out..xored``
hw
^^^
|OK|
Controls hardware access to the field.
If readable, enables output signal ``hwif_out..value``. If writable, enables
input ``hwif_in..value``.
hwclr/hwset
^^^^^^^^^^^
If both ``hwclr`` and ``hwset`` properties are used, and both are asserted at
the same clock cycle, then ``hwset`` will take precedence.
boolean
|OK|
If true, infers the existence of input signal: ``hwif_in..hwclr``, ``hwif_in..hwset``
reference
|OK|
hwenable/hwmask
^^^^^^^^^^^^^^^
|OK|
Reference to a component that provides bit-level control of hardware writeability.
we/wel
^^^^^^
Write-enable control from hardware interface.
If true, infers the existence of input signal: ``hwif_in..we``, ``hwif_in..wel``
.. wavedrom::
{signal: [
{name: 'clk', wave: 'p....'},
{name: 'hwif_in..value', wave: 'x.=x.', data: ['D']},
{name: 'hwif_in..we', wave: '0.10.',},
{name: 'hwif_in..wel', wave: '1.01.',},
{name: '<field value>', wave: 'x..=.', data: ['D']}
]}
boolean
|OK|
If true, infers the existence of input signal ``hwif_in..we`` or ``hwif_in..wel``
reference
|OK|
--------------------------------------------------------------------------------
Counter Properties
------------------
counter
^^^^^^^
|OK|
If true, marks this field as a counter. The counter direction is inferred based
based on which properties are assigned. By default, an up-counter is implemented.
If any of the properties associated with an up-counter are used, then up-counting
capabilities will be implemented. The same is true for down-counters and up/down
counters.
Unless alternate control signals are specified, the existence of input signals
``hwif_in..incr`` and ``hwif_in..decr`` will be inferred depending on the type
of counter described.
incr
^^^^
|OK|
Assign a reference to an alternate control signal to increment the counter.
If assigned, the inferred ``hwif_in..incr`` input will not be generated.
incrsaturate/saturate
^^^^^^^^^^^^^^^^^^^^^
If assigned, indicates that the counter will saturate instead of wrapping.
If an alternate saturation point is specified, the counter value will be
adjusted so that it does not exceed that limit, even after non-increment actions.
boolean
|OK|
If true, saturation point is at the counter's maximum count value. (2^width - 1)
integer
|OK|
Specify a static saturation value.
reference
|OK|
Specify a dynamic saturation value.
incrthreshold/threshold
^^^^^^^^^^^^^^^^^^^^^^^
If assigned, infers a ``hwif_out..incrthreshold`` output signal. This signal is
asserted if the counter value is greater or equal to the threshold.
.. wavedrom::
{
signal: [
{name: 'clk', wave: 'p......'},
{name: 'hwif_in..incr', wave: '01...0.'},
{name: '<counter>', wave: '=.=3==..', data: [4,5,6,7,8,9]},
{name: 'hwif_out..incrthreshold', wave: '0..1....'}
],
foot: {
text: "Example where incrthreshold = 6"
}
}
boolean
|OK|
If true, threshold is the counter's maximum count value. (2^width - 1)
integer
|OK|
Specify a static threshold value.
reference
|OK|
Specify a dynamic threshold value.
incrvalue
^^^^^^^^^
Override the counter's increment step size.
integer
|OK|
reference
|OK|
incrwidth
^^^^^^^^^
|OK|
If assigned, infers an input signal ``hwif_in..incrvalue``. The value of this
property defines the signal's width.
overflow
^^^^^^^^
|OK|
If true, infers an output signal ``hwif_out..overflow`` that is asserted when
the counter is about to wrap.
.. wavedrom::
{
signal: [
{name: 'clk', wave: 'p.......'},
{name: 'hwif_in..incr', wave: '0101010.'},
{name: '<counter>', wave: '=.=.=.=.', data: [14,15,0,1]},
{name: 'hwif_out..overflow', wave: '0..10...'}
],
foot: {
text: "A 4-bit counter overflowing"
}
}
decr
^^^^
|OK|
Assign a reference to an alternate control signal to decrement the counter.
If assigned, the inferred ``hwif_in..decr`` input will not be generated.
decrsaturate
^^^^^^^^^^^^
If assigned, indicates that the counter will saturate instead of wrapping.
If an alternate saturation point is specified, the counter value will be
adjusted so that it does not exceed that limit, even after non-decrement actions.
boolean
|OK|
If true, saturation point is when the counter reaches 0.
integer
|OK|
Specify a static saturation value.
reference
|OK|
Specify a dynamic saturation value.
decrthreshold
^^^^^^^^^^^^^
If assigned, infers a ``hwif_out..decrthreshold`` output signal. This signal is
asserted if the counter value is less than or equal to the threshold.
.. wavedrom::
{
signal: [
{name: 'clk', wave: 'p......'},
{name: 'hwif_in..decr', wave: '01...0.'},
{name: '<counter>', wave: '=.=3==..', data: [9,8,7,6,5,4]},
{name: 'hwif_out..decrthreshold', wave: '0..1....'}
],
foot: {
text: "Example where incrthreshold = 7"
}
}
boolean
|OK|
If true, threshold is 0.
integer
|OK|
Specify a static threshold value.
reference
|OK|
Specify a dynamic threshold value.
decrvalue
^^^^^^^^^
Override the counter's decrement step size.
integer
|OK|
reference
|OK|
decrwidth
^^^^^^^^^
|OK|
If assigned, infers an input signal ``hwif_in..decrvalue``. The value of this
property defines the signal's width.
underflow
^^^^^^^^^
|OK|
If true, infers an output signal ``hwif_out..underflow`` that is asserted when
the counter is about to wrap.
.. wavedrom::
{
signal: [
{name: 'clk', wave: 'p.......'},
{name: 'hwif_in..decr', wave: '0101010.'},
{name: '<counter>', wave: '=.=.=.=.', data: [1,0,15,14]},
{name: 'hwif_out..underflow', wave: '0..10...'}
],
foot: {
text: "A 4-bit counter underflowing"
}
}
--------------------------------------------------------------------------------
Interrupt Properties
--------------------
enable
^^^^^^
|NO|
haltenable
^^^^^^^^^^
|NO|
haltmask
^^^^^^^^
|NO|
intr
^^^^
|NO|
mask
^^^^
|NO|
sticky
^^^^^^
|NO|
stickybit
^^^^^^^^^
|NO|
--------------------------------------------------------------------------------
Misc
----
encode
^^^^^^
|NO|
next
^^^^
|NO|
paritycheck
^^^^^^^^^^^
|NO|
precedence
^^^^^^^^^^
|EX|
reset
^^^^^
integer
|OK|
reference
|EX|
resetsignal
^^^^^^^^^^^
|EX|

15
docs/props/reg.rst Normal file
View File

@@ -0,0 +1,15 @@
Register Properties
===================
.. note:: Any properties not explicitly listed here are either implicitly
supported, or are not relevant to the regblock exporter and are ignored.
accesswidth
-----------
|NO|
Only ``accesswidth`` that is equal to the ``regwidth`` is supported (default if unset)
regwidth
--------
|OK|

213
docs/props/rhs_props.rst Normal file
View File

@@ -0,0 +1,213 @@
RHS Property References
=======================
SystemRDL allows some properties to be referenced in the righthand-side of
property assignment expressions:
.. code-block:: systemrdl
some_property = my_reg.my_field -> some_property;
The official SystemRDL spec refers to these as "Ref targets" in Table G1, but
unfortunately does not describe their semantics in much detail.
The text below describes the interpretations used for this exporter.
--------------------------------------------------------------------------------
Field
-----
field -> swacc
^^^^^^^^^^^^^^
|EX|
Single-cycle strobe that indicates the field is being sampled during a software
read operation.
field -> swmod
^^^^^^^^^^^^^^^
|EX|
Single-cycle strobe that indicates the field is being modified during a software
access operation.
field -> swwe/swwel
^^^^^^^^^^^^^^^^^^^
|OK|
Represents the signal that controls the field's swwe/swwel behavior.
field -> anded/ored/xored
^^^^^^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the current and/or/xor reduction of the field's value.
field -> hwclr/hwset
^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the signal that controls the field's hwclr/hwset behavior.
field -> hwenable/hwmask
^^^^^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the signal that controls the field's hwenable/hwmask behavior.
field -> we/wel
^^^^^^^^^^^^^^^
|EX|
Represents the signal that controls the field's we/wel behavior.
field -> next
^^^^^^^^^^^^^
|EX|
field -> reset
^^^^^^^^^^^^^^
|EX|
field -> resetsignal
^^^^^^^^^^^^^^^^^^^^
|EX|
--------------------------------------------------------------------------------
Field Counter Properties
------------------------
field -> incr
^^^^^^^^^^^^^
|EX|
Represents the signal that controls the field's counter increment control.
field -> incrsaturate/saturate
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the internal 1-bit event signal that indicates whether the counter is saturated
at its saturation value.
.. wavedrom::
{
signal: [
{name: 'clk', wave: 'p......'},
{name: 'hwif_in..decr', wave: '0101010'},
{name: '<counter>', wave: '=.=....', data: [1,0]},
{name: '<decrsaturate>', wave: '0.1....'}
],
foot: {
text: "A 4-bit counter saturating"
}
}
field -> incrthreshold/threshold
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the 1-bit event signal that indicates whether the counter has met or
exceeded its incrthreshold.
field -> incrvalue
^^^^^^^^^^^^^^^^^^
|EX|
Represents the value that was assigned to this property.
field -> overflow
^^^^^^^^^^^^^^^^^
|OK|
Represents the event signal that is asserted when the counter is about to wrap.
field -> decr
^^^^^^^^^^^^^
|EX|
Represents the signal that controls the field's counter decrement control.
field -> decrsaturate
^^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the internal 1-bit event signal that indicates whether the counter is saturated
at its saturation value.
.. wavedrom::
{
signal: [
{name: 'clk', wave: 'p......'},
{name: 'hwif_in..incr', wave: '0101010'},
{name: '<counter>', wave: '=.=....', data: [14,15]},
{name: '<incrsaturate>', wave: '0.1....'}
],
foot: {
text: "A 4-bit counter saturating"
}
}
field -> decrthreshold
^^^^^^^^^^^^^^^^^^^^^^
|EX|
Represents the 1-bit event signal that indicates whether the counter has met or
exceeded its incrthreshold.
field -> decrvalue
^^^^^^^^^^^^^^^^^^
|EX|
Represents the value that was assigned to this property.
field -> underflow
^^^^^^^^^^^^^^^^^^
|OK|
Represents the event signal that is asserted when the counter is about to wrap.
--------------------------------------------------------------------------------
Field Interrupt Properties
--------------------------
field -> enable
^^^^^^^^^^^^^^^
|EX|
field -> haltenable
^^^^^^^^^^^^^^^^^^^
|EX|
field -> haltmask
^^^^^^^^^^^^^^^^^
|EX|
field -> mask
^^^^^^^^^^^^^
|EX|
--------------------------------------------------------------------------------
Register
--------
reg -> intr
^^^^^^^^^^^
|NO|
reg -> halt
^^^^^^^^^^^
|NO|

25
docs/props/signal.rst Normal file
View File

@@ -0,0 +1,25 @@
Signal Properties
=================
.. note:: Any properties not explicitly listed here are either implicitly
supported, or are not relevant to the regblock exporter and are ignored.
activehigh/activelow
--------------------
|EX|
sync/async
----------
|EX|
Only supported for signals used as resets to infer edge-sensitive reset.
Ignored in all other contexts.
cpuif_reset
-----------
|EX|
field_reset
-----------
|EX|

2
docs/requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
pygments-systemrdl
sphinxcontrib-wavedrom