-
Notifications
You must be signed in to change notification settings - Fork 857
[prim,doc] Updated the main documentation for the post primgen world #27422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Primitives are slightly different to your usual hw blocks. They should probably be given their own higher level heading, like cores have. Also, sorted so that they are in alphabetical order. Signed-off-by: Hugo McNally <hugo.mcnally@gmail.com>
The style guide asks that text be one sentence per line, for clearer diffs. Changing this before planned future edits. Signed-off-by: Hugo McNally <hugo.mcnally@gmail.com>
This brings the documentation up to date with how primitives now work and are used. Signed-off-by: Hugo McNally <hugo.mcnally@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a bunch of nits. Thanks for writing this!
* Primitives with a single, generic, implementation are normal SystemVerilog modules inside the `hw/ip/prim/rtl` directory. | ||
We call these primitives *technology-independent primitives*. | ||
* Primitives with multiple implementations are called *technology-dependent primitives*. | ||
Each implementation has it's own directory within `hw/ip/` with the prefix `prim`, e.g. `hw/ip/prim_generic/` or `hw/ip/prim_xilinx/`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
Each implementation has it's own directory within `hw/ip/` with the prefix `prim`, e.g. `hw/ip/prim_generic/` or `hw/ip/prim_xilinx/`. | |
Each implementation has its own directory within `hw/ip/` with the prefix `prim`, e.g. `hw/ip/prim_generic/` or `hw/ip/prim_xilinx/`. |
properties: | ||
Collections of technology-dependent primitives are called technology libraries. | ||
The *generic* technology library contains a pure-SystemVerilog implementation of primitives' functionality. | ||
It's is commonly used for simulations and as functional reference. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
It's is commonly used for simulations and as functional reference. | |
This library is commonly used for simulations and as functional reference. |
|
||
Technology libraries collect implementations of primitives. | ||
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* are used.* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: feature
is singular
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* are used.* | |
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* is used.* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍, and I think the *
at the end should be removed.
|
||
Technology libraries collect implementations of primitives. | ||
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* are used.* | ||
These can be thought of as similar to virtual methods in C++ or SystemVerilog. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this line, we might want to describe what it means to a hardware design engineer, hehe. For example...
These can be thought of as similar to virtual methods in C++ or SystemVerilog. | |
Any implementation of a virtual core must provide the same functionality and interface. | |
The module name must be the same, and the parameter and port lists must include all the required members of the interface. | |
For an analog, virtual cores can be thought of as similar to virtual methods in C++ or SystemVerilog. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe 'analogy' or 'analogon'? ('Analog' always feels itchy to the digital designer in me 😉)
which contains a pure-SystemVerilog implementation of the functionality. This | ||
library is commonly used for simulations and as functional reference. The | ||
`generic` technology library is contained in the `hw/ip/prim_generic` directory. | ||
To find the interface of a given virtual primitive look at it's generic implementation in `hw/prim_generic/`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
To find the interface of a given virtual primitive look at it's generic implementation in `hw/prim_generic/`. | |
To find the interface of a given virtual primitive look at its generic implementation in `hw/prim_generic/`. |
|
||
If you'd like to depend on a specific implementation, you can add the specific implementation's VLNV instead of the virtual VLNV. | ||
For example, you would depend on `lowrisc:prim_xilinx:prim_fifo_sync` instead of `lowrisc:prim:prim_fifo_sync` if you wanted to forcefully use the Xilinx implementation. | ||
**This is not recommended.** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Best to provide a reason alongside recommendations.
**This is not recommended.** | |
Because this method can restrict the flexibility to swap compatible cores, **this is not recommended.** |
You can rely on the generic implementation or even another library's implementation for other primitives. | ||
|
||
Technology libraries don't have to live in the OpenTitan repository. | ||
If they are not in the OpenTitan repository, you need to make sure the path to them is given to FuseSoC with either an additional `--core-root=` argument or set in `fusesoc.conf`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
If they are not in the OpenTitan repository, you need to make sure the path to them is given to FuseSoC with either an additional `--core-root=` argument or set in `fusesoc.conf`. | |
If they are not in the OpenTitan repository, you need to make sure the path to them is given to FuseSoC with either an additional `--cores-root=` argument or set in `fusesoc.conf`. |
|
||
### Selecting a technology library | ||
|
||
You can select a technology library one of two ways. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
You can select a technology library one of two ways. | |
You can select a technology library in one of two ways. |
|
||
You can select a technology library one of two ways. | ||
|
||
If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to it's dependencies. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to it's dependencies. | |
If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to its dependencies. |
|
||
If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to it's dependencies. | ||
`hw/top_earlgrey/chip_earlgrey_cw310.core` is an example of an invokable core requiring a particular technology library, namely `lowrisc:prim_xilinx:all`. | ||
You'll notice this VLNV in it's dependencies. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
You'll notice this VLNV in it's dependencies. | |
You'll notice this VLNV in its dependencies. |
``` | ||
|
||
Notice that there aren't xilinx specific implementations for all primitives, so the generic implementation is requested. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice that there aren't xilinx specific implementations for all primitives, so the generic implementation is requested. | |
Notice that there aren't Xilinx specific implementations for all primitives, so the generic implementation is requested. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of comments, but overall LGTM. Thanks @HU90m!
Also, edit the description to better describe the specific implementation. | ||
4. For every primitive implemented by your library: | ||
1. Copy across the generic implementation into your library, e.g. `mv hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`. | ||
2. Make your changes to the implementation without modifying the module ports or removing parameters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. Make your changes to the implementation without modifying the module ports or removing parameters. | |
2. Make your changes to the implementation without modifying the module ports or parameter declarations. |
Because I don't think adding parameters would work? And I added "declarations" because otherwise people might be confused that they cannot change parameter values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding parameters can work in specific circumstances (e.g. somewhere defparam is accepted or where you know there is a specific implementation), but most of the time, it doesn't.
Change the vendor and name in this file, e.g. `lowrisc:prim_generic` would become `partner:mytech` where your organisation's name can be used in the place of 'partner'. | ||
Also, edit the description to better describe the specific implementation. | ||
4. For every primitive implemented by your library: | ||
1. Copy across the generic implementation into your library, e.g. `mv hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Copy across the generic implementation into your library, e.g. `mv hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`. | |
1. Copy across the generic implementation into your library, e.g. `cp hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`. |
Unless you've aliased mv
to cp
? 😉
4. For every primitive implemented by your library: | ||
1. Copy across the generic implementation into your library, e.g. `mv hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`. | ||
2. Make your changes to the implementation without modifying the module ports or removing parameters. | ||
3. Copy the generic primitive's core description into your library, e.g. `mv hw/ip/prim_generic/prim_generic_flop.core hw/ip/prim_mytech/prim_mytech_flop.core`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. Copy the generic primitive's core description into your library, e.g. `mv hw/ip/prim_generic/prim_generic_flop.core hw/ip/prim_mytech/prim_mytech_flop.core`. | |
3. Copy the generic primitive's core description into your library, e.g. `cp hw/ip/prim_generic/prim_generic_flop.core hw/ip/prim_mytech/prim_mytech_flop.core`. |
4. Edit this copied primitive core file so that it has the new primitive library name, e.g. replacing `lowrisc:prim_generic:flop` with `partner:prim_mytech:flop`. | ||
5. Then in the libraries main core file, e.g. `hw/ip/prim_mytech/prim_mytech.core`, replace all instances of the generic implementation with your specific implementation, e.g. replacing `lowrisc:prim_generic:flop` with `partner:prim_mytech:flop` again. | ||
|
||
You don't have to have your own implementation for every primitive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on the use case / requirements of the implementation, there are some requirements on the prim implementation. For example, if you care about security against physical attacks, you need to constrain the tools you're using to not remove a prim_buf
. This isn't (and shouldn't be) part of the generic implementation. Should we create an issue to add documentation on this topic?
```sh | ||
fusesoc --cores-root=$OT_REPO run \ | ||
--flag fileset_partner \ | ||
--mapping partner:prim_mytech:all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--mapping partner:prim_mytech:all | |
--mapping partner:prim_mytech:all \ |
This updates the documentation to how primitives are expected to be used.
The documentation doesn't cover the temporary use of a
partner:prim_tech:all
and the virtualprim_pkg
. I think the former could potentially be phased out with a commit in this PR removing lines likefileset_partner ? (partner:prim_tech:all)
. Unless I'm missing something?As
prim_pkg
may be hanging around a little longer than we'd like. A paragraph could be added in a follow up PR explaining how to provide your own prim_pkg as a stop gap. Effort would probably be better spent transitioning away from it rather than documenting it, lest it become an immortal temporary solution.