stnolting / neorv32

:desktop_computer: A small, customizable and extensible MCU-class 32-bit RISC-V soft-core CPU and microcontroller-like SoC written in platform-independent VHDL.
https://neorv32.org
BSD 3-Clause "New" or "Revised" License
1.61k stars 228 forks source link

Large demo including multiple software apps and multiple bitstreams in the external SPI flash #78

Closed umarcor closed 1 year ago

umarcor commented 3 years ago

This is an idea based on:

https://github.com/stnolting/neorv32/pull/53#issuecomment-860252670 This was I am trying right now. Put an executable to external SPI flash via the FPGA programming interface and fetch that via the bootloader to execute it. I would love to have a setup where you only need to program "one file" to the flash (bitstream(s) + executable(s)) to tinker around with the board.

By combining that with instantiating the warm boot component, it would be possible to create a "bitstream" which includes multiple bitsreams as well as multiple software applications. Depending on the currently active design, it would be possible to swap the software, or to jump to a different design while preserving BRAM/SPRAM data. So, for example, one NEORV32 could prepare data for loading an smaller NEORV32 with some custom peripheral, and then handle the control to them. Moreover, some designs might be based on NEORV32, while others on Silice's demos.

Naturally, this is just a proof of concept for illustrating features/capabilities which are technically possible on UP5K FPGAs. It's neither urgent nor necessary.

stnolting commented 3 years ago

That would be pretty cool!

I was thinking about some brute force application: Use a soft-core as interface to get a new work package into the SPRAMs, then consecutively load several accelerator bitstream that work on the data and finally use the SoC setup again to send results back to the host. Maybe some crypto mining? ๐Ÿ˜†

umarcor commented 3 years ago

Not for mining, but @tmeissner has this repo of cryptocores: tmeissner/cryptocores. I don't know whether those fit in the UP5K...

stnolting commented 3 years ago

Not for mining, but @tmeissner has this repo of cryptocores: tmeissner/cryptocores. I don't know whether those fit in the UP5K...

I cant find any synthesis results there, but that would be a nice application / proof of concept!

umarcor commented 3 years ago

The is no "global" synthesis subdir. You need to look into each subdir. For instance: https://github.com/tmeissner/cryptocores/tree/master/aes. However, there is CI for simulation but not for synthesis, and the Makefiles include Yosys only (not nextpnr or VTR or Vivado or...). That is because the main interest of @tmeissner is formal verification and (co-)simulation. So, the current focus of several of his repos are PSL, SymbiYosys and GHDL's VHPIDIRECT interface (see https://github.com/yosysHQ/symbiyosys and https://ghdl.github.io/ghdl-cosim/vhpidirect/examples/vffi_user.html#crypto). Neverthless, that is very interesting because there is room for collaboration with anyone who wants to actually try some of those cores on a low-cost FPGA using open source PnR. I vaguely remember from previous dialogues with Torsten that most of those cores will note fit in a UP5K. But I think there was some specific algorithm/mode which might small enough for a proof of concept. Note that we don't need to put it together with the NEORV32. We can use two bitstreams and warm-boot for that (thus the motivation of this issue).

juanmard commented 3 years ago

That would be pretty cool! I was thinking about some brute force application: Use a soft-core as interface to get a new work package into the SPRAMs, then consecutively load several accelerator bitstream that work on the data and finally use the SoC setup again to send results back to the host. Maybe some crypto mining? ๐Ÿ˜†

Not a crypto mining example, I know... but we've got an example of warmboot with neorv32... ๐Ÿ˜„ Here you can see it... https://twitter.com/juanmard/status/1405716286601105408 ๐Ÿ˜‰

stnolting commented 3 years ago

Here you can see it... https://twitter.com/juanmard/status/1405716286601105408

This! Is!! Awesome!!! ๐Ÿคฉ:heart:

So now we do have a template for dynamic reconfiguration!! :+1: The next cool thing would be to insulate instantiate a single EBR to test passing of data between bitstreams.

umarcor commented 3 years ago

That's the first thing that @juanmard said after posting that achievement ๐Ÿ˜† ๐Ÿ˜† ๐Ÿ˜†

See gitter.im/im-tomu/warmboot?at=609175f9d261cc4d74a95edd.

stnolting commented 3 years ago

๐Ÿ˜„ :+1:

The placement might be a problem. But as a workaround we could also use all 4 SPRAMs as simple memory dump module and access them in parallel. So all SPRAMs will get the same data. This data could then be examined by a consecutive bitstream to check if the written data is still available.

But: I remember from the ice40up memory-something guide that the SPRAMs provide low-power options that "disconnects" the memory core from the supply voltage which will lead to memory loss. Since ice40 is designed for low-power, the bitstream might cut this power line to save some ยตW ๐Ÿค”

umarcor commented 3 years ago

@stnolting if you scroll down in that reference above, you'll find a nice surprise:

@sylefeb, I could not try this thoroughly in the last weeks. However, I was just reading through the documentation and I found the following:

MemoryUsageGuideforiCE40Devices.pdf Pre-loading EBR Data

The data contents for an EBR block can be optionally pre-loaded during iCE40 configuration. If not pre-loaded dur-ing configuration, then the EBR contents must be initialized by the iCE40 application before the EBR contents are valid. EBR initialization data can be done in the RTL code. Pre-loading the EBR data in the configuration bitstream increases the size of the configuration image accordingly.

EBR Contents Preserved During Configuration

EBR contents are preserved (write protected) during configuration, assuming that voltage supplies are maintained throughout. Consequently, data can be passed between multiple iCE40 configurations by leaving it in an EBR block and then skipping pre-loading during the subsequent reconfiguration

and

FPGA-TN-02022-1-3-iCE40-SPRAM-Usage-Guide.pdf SPRAM Content during Warmboot

During configuration through Warmboot, SPRAM content is not loaded. Thus, previous data on the SPRAM are retained.

Therefore, it is technically possible to preserve the content of memories between warmboot loads! That is possible regardless of the RAM type.

We need to be careful with not initialising the BRAMs in the bitstream loaded through warm-boot. Other than that, SPRAM should preserve their content, since there is no way to initialise them.


The placement might be a problem. But as a workaround we could also use all 4 SPRAMs as simple memory dump module and access them in parallel. So all SPRAMs will get the same data. This data could then be examined by a consecutive bitstream to check if the written data is still available.

That's quite clever indeed. @sylefeb tried using the placement constraints, but this brute force test might be better for proving the concept.

stnolting commented 3 years ago

if you scroll down in that reference above, you'll find a nice surprise:

I saw that :wink:

I was just concerned by this statement from "iCE40 SPRAM Usage Guide":

POWEROFF is a signal that controls the built in power switch in each memory block. This signal when driven low (1โ€™b0), shuts down the power to the memory. During the off state, there is no memory data retention. When POWEROFF is driven high (1โ€™b1), the SPRAM is powered on.

Maybe this is automatically pulled low during reconfiguration?! ๐Ÿค”

umarcor commented 3 years ago

My understanding is that it's not low by default. It's an option for users to reduce power consumption if they don't use the SPRAM. So, I wouldn't expect it to be forced off during reconfiguration. Anyway, we just need to test it :wink:

stnolting commented 3 years ago

I have just tested that with Lattice Radiant using the default bitstream options.

I am using the Upduino setup from the repository and the hex_viewer program to manually read/write data from/to the DMEM, which is mapped to 2 SPRAMs.

I am examining address 0x80008000. 0x80000000 is the base address of the DMEM. 0x80008000 is a memory region that is not used/initialized by the CPU/software at all.

After configuration via the programmer:

HEX_VIEWER:> dump
Enter base address (8 hex chars): 0x80008000
Press key to start dumping. Press any key to abort.
[0x80008000] = 0xa8b9b57d
[0x80008004] = 0x5e3e48a1
[0x80008008] = 0x59f24611
[0x8000800c] = 0x5f6d8172

Manually writing a fixed pattern and reading it back:

HEX_VIEWER:> write
Enter address (8 hex chars): 0x80008000
Enter data (8 hex chars): 0xcafebabe
[0x80008000] = 0xcafebabe
HEX_VIEWER:> dump
Enter base address (8 hex chars): 0x80008000
Press key to start dumping. Press any key to abort.
[0x80008000] = 0xcafebabe
[0x80008004] = 0x5e3e48a1
[0x80008008] = 0x59f24611
[0x8000800c] = 0x5f6d8172

After re-programming via the programmer or forcing a reconfig from the SPI flash via cRESET:

HEX_VIEWER:> dump
Enter base address (8 hex chars): 0x80008000
Press key to start dumping. Press any key to abort.
[0x80008000] = 0xa8b9b57d
[0x80008004] = 0x5e3e4aa1
[0x80008008] = 0x49d24611
[0x8000800c] = 0x5b6d8132

The memory content is lost. But maybe there is an option in Radiant that says "disconnect SPRAM from power while reconfiguration" - I have not checked that yet๐Ÿ˜…

Interestingly, there are certain similarities when comparing the SPRAM content after reconfigurations ๐Ÿค”

stnolting commented 3 years ago

But I think my reconfiguration scenario is considered "cold boot", right?

@juanmard could you maybe try this with your warm-boot setup? ๐Ÿ˜‰

umarcor commented 3 years ago

@stnolting see https://github.com/juanmard/neorv32/blob/warmboot/setups/examples/neorv32_iCESugar_BoardTop_MinimalBoot.vhd#L180-L185

stnolting commented 3 years ago

@stnolting see https://github.com/juanmard/neorv32/blob/warmboot/setups/examples/neorv32_iCESugar_BoardTop_MinimalBoot.vhd#L180-L185

Right :smile: Shouldn't be so complicated... I will try that with Radiant and use the WARMBOOT primitive to just reload the original bitstream.

juanmard commented 3 years ago

But I think my reconfiguration scenario is considered "cold boot", right?

Yes, in that scenario it is as if a "cold boot" was made. ๐Ÿ˜‰

juanmard commented 3 years ago

Right ๐Ÿ˜„ Shouldn't be so complicated... I will try that with Radiant and use the WARMBOOT primitive to just reload the original bitstream.

It's really easy. Do not forget the software program. ๐Ÿ˜ƒ https://github.com/juanmard/neorv32/tree/warmboot/sw/example/demo_warmboot

stnolting commented 3 years ago

Yes, in that scenario it is as if a "cold boot" was made. ๐Ÿ˜‰

I thought so ๐Ÿ˜… Anyway, I made the redundant discovery cold boot does not preserve SPRAM content ๐Ÿคฃ

It's really easy. Do not forget the software program. ๐Ÿ˜ƒ https://github.com/juanmard/neorv32/tree/warmboot/sw/example/demo_warmboot

Thanks! But I'll use the external memory interface and connect the WARMBOOT primitive as a simple slave so I can further use the hex_viewer program to interact with everything ๐Ÿ˜‰