I have a Zynq 7020 chip with 250 MB of DDR memory attached to it put in ECC mode (so 125 MB effectively). It's attached to NAND flash memory and has a series of bootloaders which eventually load VxWorks to run some stuff.
I have another [small] program that I will install via JTAG after the run and have it write out the rest of the RAM, then all the flash and FPGA configuration memory. This program is compiled by the Xilinx SDK and is bare-metal (no OS/bootloader).
When I load this program, I reset the processor (JTAG command), run a ps7_init.tcl script that sets all the CPU registers to a good configuration as set by Vivado, load the elf file onto the device, then run the processor. This program then tries to read memory starting at the address 0x0, but it crashes quickly. I told it to start at an address of 1 MB (1
There is a template project that Xilinx provides that is close to exactly what you are trying to do. It is the "Memory Tests" template, and it runs through attached memory ranges and tests read/write operations. By default it tests DDR memory range and ps7_ram_1. The linker script for the application puts the program in ps7_ram_0, and doesn't test that range since you can't overwrite instruction and data memory for the application.
To answer your question more directly: You are likely running into problems with the processors MMU (memory management unit) and cache management. If your application is being loaded into DDR, then it is possible that it is blocking you from accessing application instruction and data memory. If your application is loaded into OCM (like the template) there may be access problems with the memory in cache. If you disable cache using
Then you should be able to read from the entire DDR memory space (as long as it exists). Make sure that you configure your applications linker script (*.ld) so that the application knows which memory devices are out there, their base addresses and size.
I'm a PhD student working on a project that requires some fairly fast data acquisition and we have settled on the AD9613. We're trying to interface it with a zynq 7020 FPGA and I'm struggling to find specifics on how one goes about doing that. Could someone direct ?
I have a good deal of coding experience in c,c++, php, etc and did some FPGA programming in an undergraduate coursework but we didn't do much high speed ADC interfacing. What I really need is a few book recommends and perhaps some good tutorials (Modern ones, many of the ones I've found dont apply well w/ the Vivado 2017 suites). I've gone through the basic VHDL books, basic Zync interfacing, but haven't really found what I need for this particular thing.
We would need a bit more info about your setup and what exactly you are trying to accomplish. From a quick skim of the AD9613 datasheet it looks like your data interface is a 12-bit LVDS bus. You'll need to tie these to LVDS-compatible pins on your FPGA and properly constrain these connections. Then they will be accessible within the PL (programmable logic) side of your Zynq. You'll then need to define how the data is collected, stored, processed etc. which depends heavily on what you're actually trying to do with the data. I assume you are going to want to do some processing of this data, which requires you to build an interface between the PL side where the data is collected, and the PS side where your software can access and manipulate the data. This can be accomplished in quite a few ways and will ultimately depend, again, on your end goal for this project. A relatively straightforward solution might be to write your data into BRAM as it's collected, where you can then access it in software.
If you can provide some more information, myself and other members of the forum can try to point you in the right direction. To bring up a physical connection between data converter and FPGA you'll need to know how they connect (FMC card?), how you are controlling the converter (USB+GUI or SPI from the FPGA), and what converter signals you'll want to access in the FPGA.
I have gone through enough Zynq tutorials to feel fairly confident on pin routing the connectors from the AD9613 eval board (LVDS, control signals) to the pins on the PL side so I think I'm ok there. I just havn't done much w/ DMAs or BRAM, or any kind of high-speed data capture actually (other than simple SPI at 5Mhz ish).
The AD9613 on the eval board is setup in 'dumb' mode so I dont even have to use SPI to control it, however I have the snickerdoodle talking SPI (and I2C) no problem from the PS side if needed (Linux w/ C and python, and bare bones w/ C).
Thanks for the setup info, that narrows it down a lot. I have never worked with (or even heard of) the Snickerdoodle board, looks like a pretty neat piece of hardware.. It sounds like you are doing fine with the physical connection side of things so I'll skip straight to the good stuff.
There are a few factors that might influence your decision here. As you said, your best options for memory interfacing boil down to either DMA or a BRAM controller. DMA is more complex than BRAM on the software side, and you'll have to familiarize yourself with it's AXI-Streaming data interface. This will enable you to use the 512Mb of DDR2 on the Snickerdoodle, which should be plenty of space for your purposes. BRAM is a simpler interface to use on the software side, but the Xilinx BRAM controller IP is a PS interface, and in order to get your data into BRAM in the first place you'll need to write your own BRAM controller. This is way easier than it sounds though, the BRAM interface is just the address/data/enable signals. You can implement this with an FSM that auto-increments the address up to a specified number of samples. Double check me on this, but I am seeing that the Zynq-7020 has 4.9Mb of BRAM, which should also be sufficient.
It really is a matter of preference, both are valid options. I am a fan of the simplicity of BRAM for projects that don't suffer from using most of your BRAM on the PL side. Plus, this will take the DMA control load off your processor.
Are you planning to use the Xilinx FFT IP? I've never used it, but maybe you could just stream your raw data into that block (may need a FIFO to make sure you don't lose samples) and write the phase and amplitude data to BRAM...
Here's a picture of what your setup might look like. You have your Zynq processing system, and the tools can auto-generate a system reset and AXI interconnect block for you. The AXI BRAM controller allows software access to BRAM. You'll want to define your block memory generator for true Dual-Port, and use the other port for your custom controller. With this setup though I would recommend trying to do most of your heavy processing on the PL side of things, as AXI reads from BRAM are multi-cycle per operation and thus can be pretty slow.
Thanks again for your reply! I like the BRAM controller idea due to the simplicity. I was doing a back of the envelop to see if 4.9Mbits would store the data we need (7020 does indeed have 4.9Mb). I forgot to mention I need to sweep 100ish frequencies (or more). As an example, if I wanted to take 2048 samples, with both channels of the ADC, at 12 bits, say I wanted to sweep 100 frequencies, say 8 times (for averaging), I think I cruise right over the 4.9mbits, 2048*2*12*100*8 = 39,321,600 bits. (and we may want to take 8000 samples possibly, or 200-300 frequencies) So unless I can stream that data off, BRAM may be short. So I may have to use the DMA. Does this sound reasonable? I'm unfamiliar with exactly how I might stream the data off the BRAM, so I could be totally wrong in this. So for the DMA/AXI/LVDS setup, what would be a good place to start? Or do you know of a resource (book, tutorial) that could bring me up to speed? I love learning about this stuff, but so far w/ my deep dive into forums a the two books I've gone through, I haven't found a good resource.
I have a demo license for the FFT IP but I haven't looked into how it is setup quite yet. I had read it can take something like 4 hours or more to synthesize for the 1024 sample size, so I backed off until I could get the PL/Memory/PS link up and running first .
Depending on how your collection/processing is controlled, then you're right about BRAM potentially being too small to hold the data you need. I don't want to recommend a certain path for you because I don't know the ins and outs of your system. Sadly, it might be necessary to figure out the FFT IP and how you'll be interacting with it, as that will likely put some architectural requirements on your system. Something to keep in mind though, since you are more comfortable in the software side of things, maybe it's worth looking into some caching mechanics, specifically the invalidate/flush functions on a chunk of BRAM... You might be able to trick the cache controller into doing the heavy lifting from BRAM to DDR for you...
For hardware tutorials, I would highly recommend a visit to fpgadeveloper.com as there are some great tutorials to get you comfortable with all sorts of different topics. They've got a good one on the DMA core, might be a good place to start if you choose that route. Another thing that you may already know is that you can generate an example design for just about any Xilinx IP, complete with simulations and a test bench. Whenever I am learning a new IP I always do this.
I'll attach some files for a bare-bones BRAM controller on the PL side. I added some comments to explain what exactly is going on. It's a burst-write controller that auto-increments the address for a preset number of samples. Here's what the test bench looks like:
I've got it set up to burst 16 samples, starting at address 0x0 and incrementing by 1 each time. The start/end addresses and address increment can be adjusted as needed, as well as all bus widths. You can use this with the block diagram in my last post and connect the controller outputs to Port B of the block memory generator. Then hook up your sampling clock and ADC lines and you'll be able to burst samples in real-time to BRAM and access them in your software via the AXI interface. Might be a good starting place for initial testing and figuring out the other IP's you'll need.
c01484d022