• 0
Zermelo

Questions on: "How To Store Your SDK Project in SPI Flash" tutorial

Question

Hi,

First of all , thanks to the digilent guys and all the users of the forums for the info provided here. I am a newbie to Microblaze, and Vivado , but experienced with ISE and traditional RTL design flow. I am just trying to cut my path down through some of the tutorials to see what I can use for a project I need to do.

By now I am stuck with the "How To Store Your SDK ..." tutorial. Have a couple of questions:

1- I built the Microblaze system with the Quad SPI core mentioned in the intro and exported to SDK. When I generate the linker script of the "Hello World.c" , I see I should have a memory area devoted to a MIG peripheral. But, why? Should 'nt the block diagram look like this ? Shouldn't I we have a memory area devoted to the AXI Quad SPI peripheral and no MIG at all?

spi_flash.jpg

This is puzzling me a lot , because now that I come to think, there is also a DDR MIG in the other two Microblaze tutorials and I don't have a clue why it's there.

Regards

Z

 

 

 

Share this post


Link to post
Share on other sites

15 answers to this question

Recommended Posts

  • 0

@Zermelo,

The MIG portion of the design is about creating memory for your CPU (MIG = Xilinx's Memory Interface Generator).  You haven't mentiond which system you are working with, but if you at all have any memory, such as a DDR, DDR2, or even DDR3 SDRAM, you'll really want that memory for your CPU.  (DDR = Dual Data Rate, memory to/from the chip transfers on both positive and negative edges of the clock, SDRAM = Synchronous Dynamic Random Access Memory but defining that takes longer than a parenthetical.)  A good boot loader will copy your program from the flash into the SDRAM memory, and then run your program from memory instead of from flash.

While it is also possible to run your design from block RAM within the FPGA, block RAM tends to be small and thus limited when compared with an external SDRAM chip.  Further, because block RAM is much faster, it often makes sense for the CPU designer to reserve this RAM for their cache's and thus put all of their RAM in the block RAM.

Dan

Share this post


Link to post
Share on other sites
  • 0

Hi Dan, 

Thanks for the feedback, my question is not about MIG and DDRs (I have used DDR2 ad DDR3 with the MIG in Virtex 4/5 and old ISE 13.1 CoreGen) , but I don´t see the need of a DDR for a bootloading task. I am a noob in embedded software, but should nt the Quad SPI Flash in the Nexys 4 DDR enough to allocate the program? Why is the DDR needed for application program at all?

 

 

Share this post


Link to post
Share on other sites
  • 0

@Zermelo,

I'm not sure I completely understand you. 

CPU's need memory.  They run programs that are stored in memory.  These programs modify memory as they run.  What memory will your CPU use if not the DDR3 memory?  You can't use the flash ... that acts more like a ROM (read only memory) than a RAM.

A bootloader works by copying the CPU instructions from a slow memory (such as flash, ROM, or a disk drive), into a faster memory (such as block RAM within the FPGA, or an external SDRAM).  If you want to run a bootloading task ... what memory are you copying your instructions into?

Let me try another guess at following you: are you familiar with how a flash works?  I'm currently in the process of building a new flash controller, so I've worked with these a couple of times.  Of the flash controller's I've built, I can run programs off of them--but they act like ROMs when I do so.  The reason is because flash memories are so difficult to change.  In general, there are basically two ways to change flash memory and you'll need both:  The first is to erase it.  Erasing turns all the bits to one's in a given region.  I've seen flashes that can erase the entire flash (bulk erase command), sectors (64kB ea), or subsectors (4kB each) at a time.  The other way to change flash memory is to program it.  Programming turns ones to zeros.  Program operations operate on a page (256B) of memory at a time.  Thus, to set a region, you often find yourself erasing and then programming the region.  Worse, each of these operations takes a long time to complete (170s for a bulk erase, 0.7-3s for a sector erase, 0.25-0.8s for a sector erase, and 0.5-5ms for a page program).  The point is, 1) it is slow and costly to change flash memory, and 2) you often end up changing more than the single byte (or 4-byte word) you are working with.  For these reasons, flash is ... not a suitable memory for a CPU.

Two more points--1) it is an error to read from a flash while it is erasing or programming, and 2) when powered down, only your flash memory will retain its state.

Thus, when you set up your board, it may take you several seconds to "program" your configuration and program into the flash.  Once this is complete, you can now run your program from the flash--as long as you aren't changing what's in the flash.  Everytime you power down, and then power up your board, it will power up now with both your configuration (if stored in the flash), and your computer code (if stored in flash).  Your CPU may then start and run instructions ... but it still needs memory to work with.

I feel like I'm shooting in the dark here--have I managed to guess and answer your question?

Dan

Share this post


Link to post
Share on other sites
  • 0

Hi Dan!

Ok, now I think I get (hard head here!), so I probably need an external dynamic memory for run time tasks of the CPU application. (could run in internal FPGA BRAM if extremely simple, right?) And for sure the 128 Mb DDR2 of the Nexys4 DDR gives for much more room than the required for the Hello World UART example. 

I want to use the Nexys4 DDR to prototype a final product, the FPGA part will need about 4 Mbyte of external RAM for temp FFT result storage. The SW application for the Ethernet communication and peripheral control is not clear for me by the time, but guess will be really far from the 128 Mbyte  DDR2, probably a 16 Mbyte SDRAM will do by far!

Share this post


Link to post
Share on other sites
  • 0

Gosh, this sounds familiar to a GPS project I was working on once--both needed the RAM for the FFT storage, and then I'll bet that both need to be able to feed that RAM into the FFT at high speed, am I right?  If you were using a wishbone bus, I could show you a DMA core that you might find useful for that purpose.  However, I'm not sure how you'd get the DDR memory on the wishbone bus in the first place (that's one of my projects right now ...)

Sonar doesn't tend to be as high speed as radar, or I'd offer you a link to a Verilog FFT core than can handle two samples per clock (Xilinx's core only handles one ...)  (Really, it's a C++ core generator, rather than the core itself, but ... close enough.)

You might also wish to look through this example of creating a microblaze server--you might find the connections to the ethernet phy useful for your purpose.

Dan

Share this post


Link to post
Share on other sites
  • 0

Ok, going on with the tutorial: I flashed the Quad SPI (the flashing screen capture has to be corrected to show the part ID: s25fl128sxxxxxx0) and reset the board. Teraterm shows SREC SPI Bootloader (first VERBOSE msg in bootloader app) an nothing else. 

If I set breakpoints in the bootloader code,I see that the following call is problematic: 

Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);

This returns Status = 1, so I guess the bootloader exits here. Any hint what can go wrong?

Z

 

Edited by Zermelo

Share this post


Link to post
Share on other sites
  • 0

@Zermelo,

I have ideas about what can go wrong, but no ideas about what is going wrong.  I've actually never done the tutorial, and I was being quiet for a day in the hopes that someone more familiar with it than I might pipe up.

Another user, following a similar path to yours, struggled to get the various peripherals mapped properly.  As a result, when he tried to access peripherals--even those he didn't think he needed, he was getting a bus error and the whole thing failed.  He was convinced the problem was in the library he was importing, when IIRC it was actually in how he had done the peripheral mapping on his bus.

Dan

Share this post


Link to post
Share on other sites
  • 0

Hello,

I have asked some of applications engineers to take a look at this; they will get back to you here on the Forum.

Thanks,
JColvin

Share this post


Link to post
Share on other sites
  • 0

 

Hi and thanks Dan &JColvin,

I've been away from my Nexys DDR4 for a day (sigh). Just now,I  tried the library patch approach suggested by Xilinx here. Result , the same , the bootloader hangs at the Xislf driver call.

Dan the wrong memory map approach could make sense, I assume that the call to the Xilsf initialization is translated in an AXI access which might not reach the AXI Quad SPI slave. Any hints on what to check regarding the memory map definition?

By the way , this is the Vivado System I am using:spi_flash.jpg

 

There both s_axi_clk and ext_spi_clk are tied to clk_out1 (100 MHz). It is mentioned in the AXI Quad SPI that the ext_spi_clk should be set to max value of 2x max frequency at the SPI interface. In the Flash datasheet it is mentioned that the normal read mode has a max fclk frequency of 50 MHz, so maybe I am a little bit on the edge here...

I think I am going to use the Vivado Analyzer at the AXI  and ext SPI interface, and see what is going on. Any other hints?

 

 

 

 

 

Share this post


Link to post
Share on other sites
  • 0

I'm looking forward to hearing the answer from Digilent's applications engineer--this may be beyond me at this point.

But for what I know, I'll comment:

1. If this were my project, my next task would involve trying to get a scope onto the bus to see what is going on.  (Of course, my favorite scope is designed for a Wishbone Bus, not an AXI bus ...)  I would also be trying to reverse engineer the Xslt_ function, again in an effort to try to find out what's going on.  At the same time, if this were my project, I'd be using all open sources rather than Xilinx cores and sources so the reverse engineering task would be a lot easier.  :D  (My open source DDR3 SDRAM controller isn't working yet, so there is a tradeoff to be made there ...)

2. There's got to be a memory map description file created from your project files.  Since I don't normally use the schematic build approach that you are using, I'm not sure where that memory map definition file is going to be located.  At the same time, in order to be useful, there would need to be either a C header, .h, file or a linker definition, .ld, file somewhere with this information.  A search through your Xilinx directory might find these files--if they follow the formats I know of, both would be text.  (The linker format I know of is that for the GNU binutils linker, and there's no reason the Xilinx would feel compelled to follow that lead.)

3. Is it possible to read/write from the QuadSPI flash without the Xilinx initialization function?  If you need something to test, the beginning of the flash should look a lot like the .bin file you created for your configuration--assuming that you loaded it into the flash.  'od -t x4 <filename>.bin | head -10' should give you plenty of test data to examine.

4. I wouldn't worry too much about being on the edge of the supported flash speed.  A lot of the flash chips can run faster than their supported flash speed.  As an example, I just got a flash driver running for the Arty at 100MHz, even though the officially supported flash driver speed is only 50MHz.  (The chip claims to be able to go up to 108MHz.)  In other words, if you are trying to run your flash at a 50MHz clock speed then I wouldn't expect any problems due to being too close to the edge.

Hope this helps,

Dan

Share this post


Link to post
Share on other sites
  • 0

Zermelo,

 

I ran through the demo, changing the Flash Type to s25fl128sxxxxxx0, and loading a simple "Hello World" program into flash and it worked just fine. I tried the demo twice, using a 50MHz clk for one and a 100Mhz for the other (just like in your Block Design). Are you using the same offset as in the guide (0x00C00000) in both steps 1.3 and 4.1? If you change the offset in blconfig.h at any point you will need to regenerate your Download.bit by reprogramming the FPGA. You can verify that your program works at this point because it should mimic the behavior of a power cycle. The error you are getting most commonly occurs when the address for the bootloader and program overlap or don't have adequate space in Flash.

 

Mikel

Share this post


Link to post
Share on other sites
  • 0

Hi Mikel, Dan thanks for the answers,

I tried to use the same offset (0x00C00000) at first, and followed the tutorial steps.Triple checked that to make sure. Then tried other offsets , with the same result. No matter what, the bootloader hangs at the Xilsf initialize call. I did not modify the address map in Vivado.

Dan, I tried to comment out the Xilsf line, and get another error from the bootloader, so I guess initialization is needed. I checked the linker script for both the bootloader and Hello_World apps. Both have only two sections : local_bram : Base : 0x50 , Size : 0x7FB0 . i don't understand why the bootloader linker script does not have a section for the SPI Flash.

I moved to more time pressing stuff, but will be back when I finish the first version of a design and start testing it with the board.

Z

 

 

 

Edited by Zermelo

Share this post


Link to post
Share on other sites
  • 0

Hai, @[email protected] @Zermelo @mskreen @JColvin

I'm trying to follow tutorial from How To Store Your SDK Project in SPI Flash in Basys 3. I have difficulty to run generate linker script from  xilinx tools->generate linker script because it's said that "no appliction selected". I also try from right clicking in project application but there is no option for generate linker script. Do you know how to select the application? (sorry for dumb question)

Like @[email protected] say :

Quote

A bootloader works by copying the CPU instructions from a slow memory (such as flash, ROM, or a disk drive), into a faster memory (such as block RAM within the FPGA, or an external SDRAM).

Do you have any sugestion how to using block RAM in basys 3? i'm trying using MIG 7 series, but when re-customize it, it say that "selected device is not suported by MIG version 4.0". Basys 3 only have block memory.

Is there any possibilities to just save .elf file in qspi flash without using faster memory like block memory or SDRAM?

unable to generate a linker script.PNG

diagram block.PNG

Share this post


Link to post
Share on other sites
  • 0

@pratikto.sulthoni.h,

Since you asked, I'll answer.  However, be aware, my answer comes from a design that doesn't have any microblaze within it.  I use a ZipCPU instead.  This also means that I've never followed the tutorial above.

  1. I instantiate my block RAM with a Verilog memory module.  Vivado infers the block RAM from there.
  2. The MIG fails because you are using block RAM.  The MIG is designed for SDRAM--something you don't have.  Don't worry --- you don't need MIG to do this.
  3. Is it possible to just save the ELF file to QSPI flash?  Yes.  I used to do this for many of my projects.  In the end, I adjusted my linker script to place a part of my program within the flash that would then later be placed into RAM--the CPU was just too slow otherwise.  (16 flash clocks to fetch a 32-bit instruction from flash, 50MHz flash clock, so 32 clocks at 10ns each per CPU instruction ... you get the picture.)
  4. I also connect the flash to a wishbone bus, and then command that bus externally.  For the Basys3, I used a TCP/IP port to command an internal bus within the Basys3, a bus that had a flash device connected, and then I just used software to read/write the flash from there.
  5. My solution to the Basys3 problem doesn't use any of the microblaze tools, or any proprietary flash loader other than the initial configuration loader.  Once I have an initial configuration, I then use that to write my program to the flash and then I command the FPGA to start running the CPU.  As a second step, if you want the CPU to start automatically, you can write a configuration to flash that will do that--once you know where to place the CPU instructions into the flash so that they don't sit on top of the FPGA configuration.
  6. You might wish to keep an eye on your resource utilization.  A good high speed MicroBlaze CPU with all its peripherals might just consume your entire board.  Something to think about.

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