sifive / freedom

Source files for SiFive's Freedom platforms
Apache License 2.0
1.11k stars 284 forks source link

Attaching custom IP to freedom U500 #154

Closed jalezeta closed 4 years ago

jalezeta commented 4 years ago

Hi,

I have recently implemented the Freedom U500 into the VC707 as explained in this repo. I am interested in attaching a symbolic custom IP block (a simple adder or mul block) and communicate it with the Freedom u500 through AXI (The main goal is to access this simple block from the Linux OS). I have seen that there is an existing TLtoAXI bridge (ToAXI4.scala) that would help me in that purpose. However, I have been trying and I am struggling to understand how the Chisel is generated and what is the file hierarchy in order to write my simple block in chisel and connect it to the Tilelink bus through the TLtoAXI bridge.

Maybe this question is pretty basic for this place. I am really excited about this and willing to get introduced into this open HW design :)

Thanks in advance!

erikdanie commented 4 years ago

Hello,

If you are writing an ip block in chisel and want to simply connect it to a TL bus, you just need a chain of adapters. One example is here in the nvdla block: https://github.com/sifive/block-nvdla-sifive/blob/1ec9ccfb7de85902f544b9235350fd18068ad0ad/src/main/scala/devices/nvdla/NVDLA.scala#L40

Using something similar will probably work, though it might be a bit more complicated than you need. You would just need to connect it to one of the busses in the system and it would be accessible from the core.

jalezeta commented 4 years ago

Thanks Erik for sharing this example for attaching the Nvidia DL accelerator using AXI with the TLtoAXI converter. Coming back to the previous question. I am trying to understand the how chisel is compiling and understanding the file hierarchy/dependencies. I can see that al the HW generation is done by the rocket chip generator, but I do not see where these scala files are being called/wrapped. I can see that some main parameters such as the number of cores etc, but I cannot see where all the HW is being glued up for example the coreplex and all the HW elements. I can see that an intermediate representation firrtl is generated from the scala files under rocket-chip/firrtl/src/main/scala and these files act as a sort of a library, that I believe should be called/glued up from somewhere. I am not sure if I am interpreting this in the right way.

Thanks in advance.

erikdanie commented 4 years ago

You should look in the generated verilog for the VC707Shell. That is the top level, and the hierarchy goes from there. There should be a DevKitFPGADesignWrapper below it which contains the DevKitFPGADesign that then has all the glue logic between the core complex and the peripherals.

jalezeta commented 4 years ago

Thank you @erikdanie! I have replicated the nvdla block in order to treat my verilog IP block as a blackbox. Now I should be ready to call it from the wrapper and attach it to the TileLink bus. I am not sure about where exactly I should attach it. I can see that the "Makefile.vcu118-iofpga-nvdla" uses its own Designkey under FreedomU500Config ("IOFPGADesign" class). The NVDLA is connected to the TL bus inside that class. Should I create my own Designkey as well in to attach my own IP to the TL bus? It looks a little messy for the first time at least. My final goal is to connect my IP to the U500 for the VC707 FPGA.

Thanks in advance.

erikdanie commented 4 years ago

You don't need to have a special DesignKey, that is just done for this example. You can do the instantiation directly in the DevKitFPGADesign class, which is the top level system for the u500. It will be essentially the same as the NVDLA way except ignoring the NVDLAKey, and just placing it unilaterally. The Key is added so that the same class can be used whether or not there is an NVDLA, and if there is not, none of the nvdla connection code gets executed.

jalezeta commented 4 years ago

Thank you very much @erikdanie! It has helped me a lot. Also, I have used Chipyard's documentation on MMIO peripherals as well. They include an example of a GCD block attached to the TL bus through AXI4. I am including the link here just in case someone is interested in the future. https://chipyard.readthedocs.io/en/latest/Customization/MMIO-Peripherals.html