prop reference infrastructure, and other things

This commit is contained in:
Alex Mykyta
2021-07-16 12:43:58 -07:00
parent 0d5b663f98
commit 5f2319860f
14 changed files with 338 additions and 68 deletions

View File

@@ -27,3 +27,19 @@ the template would do something like:
{{output_signal(field, "anded")}} = &{{field_value(field)}};
Basically, i'd define a ton of helper functions that return the signal identifier.
================================================================================
Dev Todo list
================================================================================
- Lots to do in HWIF layer
- reorg base.py+struct.py.
- I have no desire to do flattened I/O. No need to split off a base class
- User Signals
Generate these in the io struct? I forget what I decided
- get_input/output_identifier() functions
- Field logic
Basically need all aspects of the dereferencer to be done first

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.

View File

@@ -17,3 +17,6 @@ Values:
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 onhow to build path references to stuff

View File

@@ -4,11 +4,12 @@ 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
(blank) = TBD
! = No! Confirmed that the compiler does not check this, and should.
? = TBD
--------------------------------------------------------------------------------
@@ -23,11 +24,26 @@ X Field has no knowable value
--> emit a warning?
! multiple field_reset in the same hierarchy
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
! multiple cpuif_reset in the same hierarchy
X multiple cpuif_reset in the same hierarchy
there can only be one signal declared with cpuif_reset
in a given hierarchy
@@ -39,13 +55,26 @@ X Field has no knowable value
... or, make these properties clear each-other on assignment
? If a node ispresent=true, and any of it's properties are a reference,
then thse references' its ispresent shall also be true
Pretty sure this is an explicit clause in the spec.
Make sure it is actually implemented
? Illegal property references:
- reference any of the counter property references to something that isn't a counter
- 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!
================================================================================
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 = Yes! I already implemented this.
--------------------------------------------------------------------------------
! "bridge" addrmap not supported
@@ -56,5 +85,25 @@ cpuif_resets
! 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
! multiple cpuif_reset
there can be only one cpuif reset
! async data signals
Only supporting async signals if they are exclusively used in resets.
Anyhting else declared as "async" shall be an error
I have zero interest in implementing resynchronizers
! regwidth/accesswidth is sane
! accesswidth is the same for all registers in the regblock
- accesswidth is what implies the cpuif bus width
! 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
! Contents of target are all internal. No external regs
! Does not contain any mem components
! Do not allow unaligned addresses
All offsets & strides shall be a multiple of the accesswidth used

View File

@@ -28,6 +28,16 @@ TODO:
this may actually only apply to counters...
This is trivial in a 2-process implementation, but i'd rather avoid the overheads
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

View File

@@ -62,4 +62,8 @@ WARNING:
Forwards response strobe back up to cpu interface layer
Dont forget about alias registers here
TODO:
Dont forget about alias registers here
TODO:
Does the endinness the user sets matter anywhere?