Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

What is/are the right SOPC compenent(s) for my project?

Hi,

what I'm trying to do is the following:

I have an ADC which runs at say 80 MSPs. I have a Nios II that runs at 50 (or less) MHz.

I would like to have a (or more) avalon component(s) that connect to my custom ADC component and transfers the ADC data sample by sample to an onboard SRAM.

In the Nios II software I would like to set up the number of samples I would like to have transferred from the ADC to the SRAM. After the transfer is done I would like to get an interrupt in the Nios II.

After that the Nios II can slowly get the data out of the SRAM and can process it.

I think I should use something like scatter gather DMA and streaming components. But I don't exactly know if they really suite my needs.

I imagine that my ADC avalon component ist the data stream source. The scatter gather DMA reads this source and copies the data to a memory block in the SRAM. The scatter gather DMA is configured by the Nios II and interrupts it after the transfer is done.

Am I going into the right direction or is there a better way to implement this functionality?

It would be great if somebody can point me to the exact SOPC components and avalon interface specification I need for this task.

Thanks in advance,

Maik

18 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    So if I understand you correctly, then it is not the SGDMA who is adressing the SRAM memory in a "strange" way but it is the read back of my routine?

    The SGDMA placed the 32 bit of ADC data beginning at address 0x00 in the memory to 0x00-length?

    Regards,

    Maik
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I believe so. If you pass in offsets 0, 1, 2, 3, 4, 5, etc... to the cache bypassing _32DIRECT macros what I would expect is aliasing/undefined behavior since the CPU and fabric do not support unaligned accesses. So the DMA in x32 bit configuration with stride turned off (stride = 1) is supposed to walk through the memory space starting at byte offset 0, then 4, 8, 12, 16, etc...

    The first word from your ADC will be placed at address 0x0-0x3

    The second word from your ADC will be placed at address 0x4-0x7

    The third word from your ADC will be placed at address 0x8-0xC

    etc...

    The last access would be at address "length-4" - "length -1" assuming the entire transfer started at address 0x0
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This toppic bothers me so much that I have to discuss this a little bit further even if it's a quarter past 9 in the evening . . . ;-)

    I still don't understand this behavior.

    I have a SRAM memory that has 19 address bits which defines a memory addres space from 0 to 524287. My memory data sheet tells me that at each address I can put 32 bits of data (+ some bits for parity, etc).

    This leads to a total memory size of 524287 * 32 bits -> 16,7Mbit which is 2MByte which is exactly what I told my hardware designer what I want to have . . .

    So when I use my _32DIRECT macros I still belive that when I write at address SRAM_BASE + offset, that I write 32 bits of data at this very addres. And this I think I can do up to 524287. If I increase the address by 1 I really belive that I'm on the next address to write the next 32 bits. But maybe I'm totally wrong on this which I will try to confirm this, tomorrow.

    I also don't understand, why I can read like this from the SRAM:

    IORD_32DIRECT(SRAM_BASE, 0x01)

    and get the data that I have written with IOWR_32DIRECT(SRAM_BASE, 0x01, 0x01), wheras If I write IORD_32DIRECT(SRAM_BASE, 0x00) or IORD_32DIRECT(SRAM_BASE, 0x04) I get the full 32 bit of data the SGDMA has written.

    Somehow this is not clear to me . . . .
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    A x32 SRAM that has 19 address bits should cover 2MB of data storage space. They only provide 19 bits instead of 21 because they provide byte enables as well. So when the access goes off-chip to the memory the address is supplied as a word address and the individual byte lanes for each word are accessed using the byte enable signal to qualify the writes.

    So the behavior in SOPC Builder is that all addresses provided by a master are byte addressed. All addresses into a slave are word addressed with byte lanes controlled by the byte enable signal. This means that the access Nios II performs to the fabric should always be an address that is a multiple of 4 (i.e. the two LSBs are always low) and the byte enables control the lanes being accessed. Since the memory uses word addressing what the fabric does is takes the Nios II address line and performs a right shift of two bits and sends that into the slave port of the memory. The idea of the Avalon specification is you just need to follow it for masters and slaves and not have to care about what it is doing internally.

    The reason why the master needs to use byte addressing is because you can have different width masters in your system so if everything was word addressed the increments necessary for each master would map to different locations in memory.

    This read "IORD_32DIRECT(SRAM_BASE, 0x01)" will most likely alias into offset 0 of the SRAM because the fabric will take the 0x1 and shift it right two bits resulting in an SRAM word address offset of 0. The same aliasing would happen if you use IORD_32DIRECT for offsets 2 and 3 as well, both of those should alias into address 0 which is not what your intention is. Really at the end of the day if you stick to byte addresses in your C code, the pointers you send to the DMA, specify the transfer length in bytes (four bytes for every ADC word) you should end up with a working system.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks again BadOmen, but honestly you got me now at a point where I have to stop and continue tomorrow . . . ;)

    Tomorrow, I will analyse this last post of yours line by line and at the end of the day I will have understood (hopefully) what they mean. I'm sure you are right!

    Maik
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    in order to understand what is really going on on the address lines to the SRAM, I made some Signal Tap measurements. The results are a basis for a new discussion:

    In the attachment I put three screenshots. One shows the SRAM test with the IOWR_32DIRECT macro used. I write 32 bit testdata at the first 16 addresses of the SRAM (0x00 - 0x0F).

    Everything works as expected. The SRAM is addressed from 0x00 to 0x0F and the data is succesfully written.

    The second screenshot shows the SGDMA transfer of also 16 write cycles. It is very impressive to see that in the view with the same scale as the IOWR_32DIRECT view, the performence is very much improved.

    The third screenshot is zoomed into the SGDMA transfer. There, one can see that the first two addres bits are unused which leads exactly to the behaviour that I've described earlier when I read the SRAM back with IORD_32DIRECT.

    BUT, I don't understand why the SGDMA behaves this way (even if I look at your last post from yesterday). My SRAM has a size of 512kx32 which I never can fully use with this kind of addressing mode the SGDAM is doing. However, if I use the _32DIRECT macros, I do can use the whole memory space.

    You are right that if I do the addressing in the IORD_32DIRECT macro like this: (SRAM_BASE, 4*offset), I can read the correct values that the SGDMA has written to the meory but all in all I can only use a quarter of the available memory of my system.

    If I'm wrong at some point or if there is a solution for this problem, please let me know.

    Regards,

    Maik
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You hooked up the SSRAM off-chip address bits 18..0 it seems. The tri-state address bus is byte addressed but since you have a x32 SSRAM you need to connect the 20..2 to your 19 off-chip address lines. It happens to be working with IOWR/RD_32DIRECT because there are two issues cancelling out.

    The tri-state addresses are byte addressed because it needs to work with multiple off-chip devices with varying widths. See page 54 in this doc for more details: http://www.altera.com/literature/manual/mnl_avalon_spec.pdf

    In a nutshell you probably need to take the 21 bit SSRAM address coming out of SOPC builder and right shift it 2 bits and connect it to the SSRAM. Then you would have to fix the code performing the IORD/WR_32DIRECT accesses. You can take a look at this design to see what to do at the top level to ensure you are sending the correct address bits off-chip: http://www.altera.com/support/examples/nios2/exm-high-perf-bridge.html