• 0
davec

How to program Arty flash

Question

So I created a microblaze design on Arty in Vivado 2015.3 with lwIP axiether and some GPIO to control my external hardware.  I wrote my C code in SDK.  From SDK, I can download the FPGA config and then run my C code on Arty by doing Run -> Run As -> 1. Launch On Hardware.  Everything works great!

Now I want to put this all in flash so it will come up on power-up reset.  I read Xilinx #63605, how to create an MCS boot image, but I am confused.  Do I need to include an axi_quad_spi in my block design, or does the SDK flash programmer take care of this? (I don't need SPI in my design otherwise).  I'm not sure what files to combine into the mcs.  Is there a tutorial on this subject? Thanks-  Arty is a great product!

Share this post


Link to post
Share on other sites

35 answers to this question

Recommended Posts

  • 0

Hello davec,

You can find a simple tutorial on how to program the Arty using Quad SPI in step 4 of the Arty Programming Guide. Vivado has the option to program the flash with a .bin file using the Hardware Manager. You can consult the Arty's reference manual, section 4.1 for more Quad SPI configuration information. Hope this helps!

Mikel

Commanderfranz likes this

Share this post


Link to post
Share on other sites
  • 0

Thanks mskreen, but it looks like that only puts the FPGA bit file from Vivado into the flash.  I also need my code from SDK to load on bootup.  I have been reading xilinx AR #63605 and AR#64238, but still don't have it right.

 

 

Share this post


Link to post
Share on other sites
  • 0

I'm still spinning my wheels on this one.  I need to put the bootloader program, my FPGA design, and my application program into the flash on Arty so that the bootloader will load my code on power up. I am trying to do this from the SDK but haven't got it to work yet.

Any ideas?

 

Share this post


Link to post
Share on other sites
  • 0

Hi davec,

I've let mskreen know that this thread isn't closed. Both he (and I) misread your original question, so we were under the impression that this was solved.

I apologize for the confusion.

Thanks,
JColvin

Share this post


Link to post
Share on other sites
  • 0

Thank you J,

Part of the question may be when the bootloader runs and it loads my .mcs into the Quad SPI Flash should it be clocking the flash via FPGA pin L16?  I don't see that this pin is configured.  I understand that normally when the FPGA loads, it uses CCLK, etc, but I am talking about when I am programming the bootloader and my code into the flash.  When I run the bootloader code, I get the opening prompt "SREC SPI Bootloader", but when tracing the code,  it fails when initializing and/or accessing the SPI flash.

Also, I am confused as to what to use for FLASH_IMAGE_BASE_ADDR.  Is that the offset into flash where my user code starts (after the FPGA bits and bootloader code) or where the bootloader sits?

Surely someone has been successful in booting an FPGA design with bootloader and user code from flash on the Arty?

TNX

 

Share this post


Link to post
Share on other sites
  • 0

Sorry for the late response and the confusion davec. So I have never saved an SDK project in flash before but you should be able to load your SDK project along with your verilog/board design into flash fairly easily. Assuming that you have your Vivado and SDK project completed the workflow is such; in Vivado inside of the Sources container you want to link your .elf file found in the SDK (projectFolder -> Debug -> project.elf) to your block design and generate your bin file just like in the Arty programming guide I referenced in my earlier post.

In order to do this, right click inside of the sources box in vivado and select Add Sources..., select Add or create constraints hit next, and add your .elf file. Once your .elf file has successfully been added to your project you will need to right click your block design (design.bd) and select Associate ELF files..., and select your .elf file. Now you should be all set to regenerate your Bistream and flash your ARTY. Hope this solves your problem.

 

Mikel

Share this post


Link to post
Share on other sites
  • 0

Thanks, mskreen.  I managed to load the FPGA along with a bootloader program (srec_bootloader) from flash!  The user code that I ultimately want to run does not fit into block ram, hence it must be moved from flash to DDRAM by the bootloader that is running in blockram.  Now my problem is that as I mentioned above, I am not seeing the SCK run once the bootloader executes. My block design has an axi_quad_spi, but the sck_o and sck_t signals don't come out to the outside world, only io[3:0] and ss signals.  I tried adding the signals in the hdl wrapper, but they get blown away when I resynthesize because they don't appear on my block design.

Any ideas- from anyone who has implemented flash on the Arty?

TNX

Edited by davec

Share this post


Link to post
Share on other sites
  • 0

I figured out why the sck signal is not getting implemented-  For some reason, "PARAM_VALUE.C_USE_STARTUP" is not set to zero, so when the file "board.xit" does not see this variable =0, it does not implement the sck pin (L16).   I cheated and took out this test in "board.xit" (because I don't know where that PARAM_VALUE gets set).  I added constraints for the pin:

set_property PACKAGE_PIN L16 [get_ports qspi_flash_0_sck_io]
set_property IOSTANDARD LVCMOS33 [get_ports qspi_flash_0_sck_io]


and I now get a clock to the QSPI flash when the bootloader runs. :)

One last step to solve- where to put my user program in flash that the bootloader will copy into DDR.  The tools don't tell me how large the FPGA config file is (with compression on).

I looked at the file size of the .bin file and rounded up to the next 1K, but I wish there was a programmatic way to do this from Vivado.

Hurray- On power-up I can now config the FPGA, run the bootloader in block ram, which then copies my large user program from flash to DDR  and executes.

 

Edited by davec
JColvin likes this

Share this post


Link to post
Share on other sites
  • 0

Hi davec,

Good catch. None of our other boards use configurable pins for the QSPI CCLK, so this one slipped through in the board files, I'll get it fixed asap.

Next up, you'll need to create a bootloader to run your program out of DDR memory. There's a brief walkthrough here, but if you have problems, feel free to ask!

Hope this helps!

davec likes this

Share this post


Link to post
Share on other sites
  • 0

Thanks Tom and J-

It's all running now.I am using the srec_bootloader from SDK.

I looked everywhere and did not see a reference to C_USE_STARTUP.  I guess it was a carry over from a previous design.

How (and where) would I set a PARAM_VALUE if I wanted to?

 

Share this post


Link to post
Share on other sites
  • 0

That's an IP configuration parameter. These parameters are tied to the GUI in the Re-customize IP window when you double click an IP in the block design. 

Share this post


Link to post
Share on other sites
  • 0

Hi,

Thanks for sharing your solution, but it is difficult to get the "whole picture". Could you please provide on your ARTY Resource Center a complete step-by-step tutorial on how to boot  and load a uBlaze application program from SPI flash? It would be really helpful!

BR

 

JColvin likes this

Share this post


Link to post
Share on other sites
  • 0

oe7aft,

 

I have just finished a simple guide on how to store a SDK/Microblaze project in flash. You can find it on the Arty Resource Center here. Please let me know if you have any additional concerns and I will do my best to assist you. 

 

Mikel

Edited by JColvin
linked to tutorial
oe7aft likes this

Share this post


Link to post
Share on other sites
  • 0

Thanks Mikel, very helpful!

in the meantime I have found that Avnet has also a tutorial on this topic here (under "Documents").

I can now move on with my SDR project ;-)

BR

Enrico

Share this post


Link to post
Share on other sites
  • 0

Great to hear Enrico! Let us know if you hit another roadblock or need anything else. Also, feel free to comment on the guide if things were not clear or if we could improve it in some way. A little constructive criticism is always welcome.

 

Mikel

JColvin likes this

Share this post


Link to post
Share on other sites
  • 0

Hello,

 

I have been reading multiple posts regarding the usage of a bootloader, and more specifically with the Arty and I think that this one is the most relevant.

I managed to get one of the tutorials working fine, but I have one problem though that I cannot figure out since a few days.

I am able to program my flash with (bitfile+bootloader) + application, and make the application run by pressing the PROG button of the Arty board. However, when I power reset the board, I see the done pin set, but it seems that the app does not start. Any ideas on the reason behind this behavior?

Thank you very much for your help

cheers

George

PS: After power reset, when I press the PROG button sometimes it loads the app and sometimes it does not.

Share this post


Link to post
Share on other sites
  • 0

At first I was thinking maybe the FPGA didn't finish loading or the power up reset isn't coming up clean, but you said the done light comes on.

If it is an intermittent problem, Is it possible that your SPI CLK is too fast for the flash part that you are using?  You can set that in the HDL code.

Maybe your application reset vector is not at the correct location or not getting loaded from cold reboot?  Does the PROG button work every time, or only after you flashed the part? 

In my design, the FPGA bit file loads, along with bootloader into FPGA RAM.  The bootloader then runs and copies my application into DRAM and then jumps to my start of application in DRAM.  With a scope, you can see if there is any activity between the flash and DRAM after DONE comes up.

Share this post


Link to post
Share on other sites
  • 0

Thank you for the answer davec.

Since it loads after programing, or after flashing the part, I think it is not a matter of addressing.

I checked the clock, and what I saw was that when I power-reset, it stops working after the DONE comes up, which means that the SPI part is not clocked. I assume it has something to do with the startup process of the configuration, but I cannot figure out what kind of settings I need to use for my programming file. I saw this post on the reference manual which troubles me:

 

"On other boards, SCK is an exception because it remains a dedicated pin even after configuration, however, on Arty the SCK signal is routed to an additional general purpose pin that can be accessed after configuration (see Figure below). This allows access to this pin without having to instantiate the special FPGA primitive called STARTUPE2. "

According to that, the clock should work even without the use of the STARTUP primitive. Did you use any special configurations on your bitstream settings?

thanks again for your help!

Share this post


Link to post
Share on other sites
  • 0

@George,

Yes, the SPI CLK pin should still work, but pay attention to how it was wired: Digilent tied an FPGA I/O pin (L16) to the CCLK pin (E9) in the FPGA.  The schematic doesn't show this very well, but basically L16 and and E9, found roughly at location B2 on page 6 of the schematic are tied together with a simple resistor between them.  A better reference for what is going on can be found in the project reference manual here.  That means that you can now drive the flash using the I/O pin (L16) while ignoring the CCLK pin (E9). 

It also brings up a simple problem: are you anywhere in your design trying to drive both pins?  You'll probably need the STARTUPE2 primitive to drive the CCLK pin (E9), but the other I/O pin would be configured/treated just like any normal I/O pin and assigned in your XDC file.  Were you to do so, configuration would continue to work just fine, since the user logic is disabled until configuration is complete, but if your user logic then tries to use both the CCLK pin and FPGA I/O pin, you might have problems.  (I'm guessing at the cause, but it's probably still worth checking.)

Dan

Share this post


Link to post
Share on other sites
  • 0

Hi Dan,

Thank you for your feedback. I am using L16 as is indicated to most of the examples, so I guess I should not need to use either the STARTUPE2 primitive.

I tried with a smaller clock as davec suggested (25MHz), but still no luck. I tried with different addresses to flash the ELF file, tried even on different addresses with the configuration itself. Nothing seems to work. What I observed, is that the SPI clock does not have always a good response, even during normal programming phase. Sometimes it blocks. And what I also observed is that at power up, the bootloader does not start either, so it does not even reach that point. Only when I press the PROG button, and even then, not always.

cheers

George

Share this post


Link to post
Share on other sites
  • 0

If you have both L16 and STARTUPE2 in your design, then let me know what happens when you remove STARTUPE2.

I'm not sure what you mean about the SPI clock blocking.  If you aren't familiar with the SPI protocol, this clock should normally be stopped when the port is not in use.  Further, you can halt the clock if you need to in order to finish preparing your logic for ... whatever.  SPI is supposed to allow that, and the QSPI flash on the Arty is no different.

If you are at all curious about how the QSPI flash on the arty can or should work, please feel free to check out the EQSPI flash core within this project.  (EQSPI = Extended Quad Serial Peripheral Interconnect, the type of chip on the Arty.)  There I do exactly as I just mentioned above: I stop the SPI clock between transactions, and I stop/pause the clock mid transaction if the controller can't yet tell if the transaction is complete.  There's even a Verilator simulation (eqspiflash_tb) showing how the EQSPI flash may be used in many situations.  (It'll spit a *lot* of debugging type output to your screen though ...)

Hope this helps,

Dan

Share this post


Link to post
Share on other sites
  • 0

Oh, almost forgot, one more thing to mention: The flash is supposed to work up to 108MHz.  I've tested it using a 100MHz clock, although I'm currently using a 40MHz clock for it.  Others routinely use a 50MHz clock.  In other words, dropping to 25MHz won't hurt --- but it's not your problem either.

Dan

Share this post


Link to post
Share on other sites
  • 0

Sorry, wrong language from my side. By blocking I mean that there is a low speed at the clock which seems to be infinit loop (the board does not program). I am familiar with the protocol.

I am not using both L16 and STARTUP, only L16. To come back to my original problem, I dont see the reason why the board works when I press the PROG button, ano not on power reset. They should have the same effect on the operation of the FPGA/bitstream configuration etc. when I press the PROG button, I can see on the osciloscope the programming of the FPGA, and then the loading of the SREC porgram (by means of SPI clock cycles). When I power reset, I can see the programing of the FPGA, but nothing else. The bootloader does not seem to work either, so it is like the design is totally frozen. I do not see the difference on the operation between power reset and setting the PROG button

Share this post


Link to post
Share on other sites
  • 0

Okay, thanks, that clears up my understand ... a bit.  Perhaps just enough to be as confused as you are.

I'm still not certain I yet understand, "low speed at the clock which seems to be infinit loop".  I know the board programs with a lower flash clock speed, and that it can read from the flash for extended periods of time, but if you are familiar with the protocol then I doubt that's what you meant.  What clock is in low speed?  When?  What is in the infinite loop?

I know others have had issues with getting the reset logic right.  All I remember has been some issue about active high versus active low, but you might wish to check your reset logic against the design examples.

I also know that for the design I am working on, I needed to integrate the DDR3 SDRAM controller (MIG) into my reset logic, since there's a finite time that this controller takes to start up, and nothing else can be allowed to start until all of it's clocks are locked.  In my case, I wait until the DDR3 SDRAM is completely up and running.  Indeed, I've got the reset push button wired into the DDR3 SDRAM controller, and only then into my logic.

Dan

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now