lowRISC / lowrisc-chip

The root repo for lowRISC project and FPGA demos.
http://www.lowrisc.org/
Other
596 stars 148 forks source link

How to add a new peripheral #143

Open vmesnag opened 4 years ago

vmesnag commented 4 years ago

Hello, I am working on the lowrisc frame-buffer branch and trying to understand how the VGA peripheral works. My initial objective was to increase the VGA resolution, so I started looking at the psoc and fstore2 modules, but it seem too complex.

My understanding is that, to access a peripheral, one has to write/read from the AXI BRAM controller, and the peripheral address decoding is done at periph_soc.sv. I also saw that the Memory map of the BRAM is used by the other peripherals, so is it possible to add other peripherals? And since the BRAM is almost full, can these peripherals be mapped to the DDR instead? If yes, can you advise me a direction to take?

jrrk commented 4 years ago

Dear vmesnag, The frame-buffer branch was an experiment that was never released. The best ideas from the frame buffer development have been incorporated on the ariane-v0.7 branch, which despite the name, supports Rocket as well. On this branch you will find X-windows support, frame buffer drivers for Linux, and support for 8-bit depth. The resolution problem has not been solved, as you say it would require more drastic surgery such as buffering the screen in DDR memory. This has not been done yet due to the performance impact. Another approach is to use a different board if your application is not too cost sensitive. The Genesys2 board which is supported on this branch has much larger internal RAM which could be directly used in your application. Documentation for this release is not yet on our website. You can can check it our yourself from the lowrisc-site repositiory or visit the temporary preview on:

https://www.cl.cam.ac.uk/~jrrk2/docs/docs/

Adding new peripherals is easier in this pre-release as well. You can directly connect them to an AXI to memory protocol converter, which is what I assume you were saying in an obscure way above.

vmesnag commented 4 years ago

Thank you for your help!

I checked the global functioning of arianne-v0.7 version. As we aimed at bare-metal application, the Linux and X-window features turn out not to be relevant in our case. Moreover, I can't see any bare-metal support yet in the fpga folder as it used to be for previous versions. Thus, the frame-buffer version will still be the main case study.

In order to free some BRAM, I thought about reducing the instruction/data caches' size which is significant. If I presumably free enough memory, could you indicate me the main steps to achieve for adding a new peripheral in the design please? I suppose there are unspoken rules that need to be followed.

jrrk commented 4 years ago

The bare metal boot loader has moved to fpga/src/etherboot. This has been reduced from 64K to 32K to free up more memory for graphics. You will find it a lot more convenient to add a peripheral in the new version because a dedicated AXI demux operates on the peripheral bus. You just need to add it in various places as indicated in ./fpga/src/ariane_peripherals_xilinx.sv and ./fpga/src/ariane_soc_pkg.sv. It's fine to use bare metal development, you can use gdb to debug your new application or build it into boot.bin instead of BBL. The old version wasn't really designed for expansion but if you modify periph_soc.sv around the logic one_hot_data_addr and one_hot_rdata, you can fit in another peripheral.

vmesnag commented 4 years ago

Hello again, thank you for your previous enlightment. I am still working around address decoding processes (in frame-buffer branch) and I can't manage to understand a subtility of your code.

From my understanding, given one HID register access from software part, the bits vector hid_addr[18:0] should recover the 18 LSBs of the software requested address. But most likely, all of your decoding processes occur to start on bit 3 of thehid_addr[18:0] vector instead of 0, as if hid_addr[2:0] bits are never used. It seems to me that somewhere, the address value is left-shifted by 3 bits but I might be wrong.

Please, would you mind explain me what I am missing here ?

jrrk2 commented 4 years ago

The hid_addr[2:0] is commonly not used because accesses are assumed on the AXI bus are assumed to be 64-bits wide. If you have a peripheral that needs byte level access (such as the VGA screen), then the byte strobes should be decoded appropriately. The [2:0] bits are left in there to remind the programmer that they are dealing a byte addressing CPU.