BrunoLevy / learn-fpga

Learning FPGA, yosys, nextpnr, and RISC-V
BSD 3-Clause "New" or "Revised" License
2.46k stars 235 forks source link

Faster SPI flash controller #29

Open BrunoLevy opened 3 years ago

BrunoLevy commented 3 years ago

There is (a lot of) room for improvement in the SPI flash controller:

BrunoLevy commented 3 years ago
BrunoLevy commented 3 years ago
Mecrisp commented 3 years ago

Trying the latest changes gives:

yosys -DICE_STICK -q -p "synth_ice40 -relut -top femtosoc -json femtosoc.json" RTL/femtosoc.v
Warning: Yosys has only limited support for tri-state logic at the moment. (RTL/DEVICES/MappedSPIFlash.v:50)
ERROR: Module `\EHXPLLL' referenced in module `\HDMI_clock' in cell `\pll_i' is not part of the design.
BrunoLevy commented 3 years ago

Hi Matthias, This is because the currently pushed version is configured for the ULX3S To configure it for the IceStick: Edit RTL/femtosoc_config.v and select CONFIGS/icestick_config.v instead of CONFIGS/ulx3s_config.v

BrunoLevy commented 3 years ago

I meant CONFIGS/icestick_spi_flash_config.v (and edit it as well to select the devices you want or not)

Mecrisp commented 3 years ago

I see, thank you: Up and running now, feels faster !

BrunoLevy commented 3 years ago

Cool ! Thank you for letting me know (I tested again, but I'm always afraid of breaking smthg ! When you have multiple board, it is very easy to break something without noticing !).

The current version uses 44 clocks for each 32-bits access, we could go faster:

Mecrisp commented 3 years ago

You have a lot of configuration options, I like that ! I usually have a folder for each target separately, and common folder(s) for the parts that can be reused. Maintaining all the switches for different targets in the same target-specific files is something I would avoid. You'll end up with some duplicated glue code, but it improves readability for the ones that use one target only.

Speed is acceptable now, and you should leave a few LUTs for experiments of your students.

Did you follow the idea to change the processors register set in order to get 7 kb available RAM on Icestick ?

Mecrisp commented 3 years ago

A good place to draw the line is between CPU+RAM in a common module, with options for size/SPI execution/reset vector, and a separate target-specific Verilog file to wire in the peripherals for each target.

In my experience with Mecrisp-Ice, I usually drop the same CPU/Memory/Forth module into my new projects and rewrite the IO part every time to fit the current use case, with the Forth core itself having a dependency on the terminal IO registers only.

BrunoLevy commented 3 years ago

Did you follow the idea to change the processors register set in order to get 7 kb available RAM on Icestick ? Not yet, I mainly worked on the ULX3S version and its OS in the last few days.

About files organization, I'm trying different things, no organization is perfect, I'll probably reorganize everything several times. For now it works reasonably well for the different projects, but I'll probably change it when the number of supported boards will increase.

About LUTs, I have an idea that may save 40 to 50 LUTs: the SPI flash controller has a 40 bits and a 32 bits shift register, maybe I can replace them with 8-bits shift registers used several times (but I do not like it very much, it adds some complexity...)

BrunoLevy commented 3 years ago

Pushed new version, now using a single 40 bits shifter (for both send and receive), and a single 5 bits clock counter, saves 50-80 LUTs !