Altera Remote System Update

Jun 26, 2017
Everything I've read about Altera's Remote System Update (RSU) seemed to be dis-jointed and rather confusing.  It took me a fairly long time to implement RSU for my Cyclone III project. If you look at the RSU datasheet, it mixes all the architectures and version together in one document.

The RSU is different for different architectures (Cyclone, Arria, Stratix) and sometimes different between versions.  Cyclone III is very different than Cyclone V, but I think Cyclone III and IV are very similar if not the same.  This means that if you read a forum post about how to implement and test on another chip, the specifics probably won't apply to your different chip.  So, if you are reading this post and hoping for something that will work on the latest Stratix, you may be disappointed.

The generalities of how to implement RSU do apply.  This is generally what will need to happen:
0. Setup two or more FPGA images in PROM (probably EPCS).
1. FPGA must be running an image that has an RSU component added.
2. Write the FPGA Boot Address to RSU
3. Set Watchdog Timer timeout value
4. Enable Watchdog Timer (for testing I would recommend "disable")
5. Set Reconfig bit to 1
6. Wait for new image to startup.

The six steps seem pretty simple.  This is what I did for each step.

Step 0;
Use USB Blaster to load two images (via JTAG) into the EPCS prom.

I used a JIC file with two images created with Quartus Convert Programming File.  I chose to put User image at Page_1 address 0x80000 to make things simple.
<fpag_image>.map format:
BLOCK START ADDRESS END ADDRESS

Page_0 0x00000000 0x00069D48
Page_1 0x00080000 0x000EAAAF

Factory Image located at 0x00000
User Image located at 0x80000 (I set this in the JIC file creation).

Additionally, I have a Wishbone SPI bus component connected to the EPCS which would allow writing a new User Image to the EPCS PROM.

Step 1:
You need to add the "ALTREMOTE_UPDATE" component with the MegaWizard.  It is one page of configuration and I chose the defaults.  You will also need some way to Set and Clear bits and buses for the interface; I used an embedded processor core (with serial & terminal input).  If running on a processor, you need the RSU component connected to the system bus.  The processor was using OpenCore's Wishbone bus and I wrote a simple interface for that (WB2RSU.vhdl in the GitHub link later).


Step 2:
This should be Write then Read-back.  Initially writing the address location for the Boot address using the WB2RSU looked successful when viewed with Signaltap, but Read back did not produce the correct value.  The datasheet I was using initially using had another 2-bit bus called read_source that was barely mentioned and it seemed to say 00 was for current config, 01 for previous and 11 for don't care.  I had set read_sourceto 00 (current config since I assumed that is what I was doing).  More reading of forum posts and newer datasheets said to write with read_source= 00 and Read Boot address with read_source= 11.  The data sheet was clear to say that you write the Boot address's bits 24 to 2  (right shift address 2).  I wrote 0x20000 since my Boot Address for Page_1 is 0x80000.

Step 3:
Now knowing the importance of read_source, Writing then reading back the Watchdog timer values is straightforward.  Write with read_source= 00 and read with read_source= 11.  You will be writing the top 12 bits of the Timer's 29-bit Start value so plan accordingly.

Step 4:
Write with read_source= 00 and read with read_source= 11.  This is to enable the Watchdog timer ON reconfigure, not right now.  I disabled WD timer for ease of use during testing.

Step 5:
Write with read_source= 00 ... Just kidding, this would make too much sense.
Just write a 1 to the Reconfig signal.

Step 6:
Wait for the Reconfig to complete and load the new FPGA image.  If the image is not loadable for any reason and your watchdog timer is configured and enabled, the FPGA will reload starting at Boot Address 0x0.  If not power-cycle the board and try again.

There other things to configure with the RSU component like "Force Early Config Check" and "Internal Oscillator" that I don't know how important it is so I didn't use it.

Oh, and the RSU core clock has to be less than 40MHz.

With the WB2RSU.vhdl compontet, a processor with UART and memory, I created a test program that runs bare-metal.  Github Repository for RSU.

Questions? Contact me through my Contact page.