Ease of adapting Ibex memory protocol to tilelink for non 32-bit access
Nobody has claimed this yet.
- Dominant language
- SystemVerilog
- Stars
- 2.1k
- Forks
- 810
- Avg merge
- 5d 23h
- Merged PRs (30d)
- 9
Description
Tilelink has a `size` field it its message payload, that the native Ibex protocol does not have.
When accessing 'standard' memory this is not a big problem. An Ibex -> Tilelink adapater could just always use 32-bit sizes and set all byte-enables for read (`Get` in Tilelink terms) and for writes take the byte-enables from the `data_be_o` from Ibex.
However this could give some difficulties around reads to devices where a read could trigger some action. Specifically if a device triggers some action on particular byte reads and the simple adapter described above is used a single `lb` instruction will turn into a 4-byte `Get` in Tilelink. The device might then trigger an action because certain bytes have been read but from a programmer's perspective these bytes haven't been touched.
In Tilelink for a `Get` message you cannot partially set the byte mask, so you must use the `size` field to communicate what bytes you actually intend to read where this matters. Ibex (from a quick look at the RTL anyway) does generate `data_be_o` that indicates the precise bytes you want so it would be possible to build some logic that can work out an appropriate `size` from the `data_be_o`.
You may also find that your TileLink devices only respond to `PutFullData` so in order to do a byte-write to such a device you'd need to generate `PutFullData` with a byte size. Again the logic mentioned above could be employed to ensure the correct `size` field is generated along with some logic to understand if it's a `PullFullData` or not.
This logic would be a little fiddly, add extra area and increase the depth of logic. In some sense it's simply undoing what `ibex_load_store_unit` has done internally (taking the size and address and generating a be). We could introduce a `data_size_o` to the Ibex top-level interface allowing simpler adaption to Tilelink and other similar protocols.
We probably also want a requirement that `data_be_o` matches tilelink requires for its `mask` field but I think this is already the case, but worth documenting.
Another potential addition would a `data_full_o` that indicates `data_be_o` is set for every byte that's covered by `data_size_o`. This would allows a simple way to choose `PutPartialData` vs `PutFullData` on the tilelink interface. However it may be the adapter would always emit `PutPartialData` anyway. I will open an OpenTitan issue to discuss this point.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing ibex_load_store_unit and the Ibex top-level interface, focusing on how data_be_o represents accessed bytes. Define whether data_size_o and data_full_o are needed for TileLink adaptation, and document the required relationship between data_be_o and TileLink's mask and size fields.
Written by the indexing model from the issue text.
Assessment
- Domain
- embedded-iot
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100