Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

Newbie memory question

Altera_Forum
Honored Contributor II
1,662 Views

Hi, 

I got a Terasic DE0-nano board with a Cyclone IV FPGA. My design is writing data in the memory. I use a NIOS II softcore too and I'd like it to read the FPGA memory and the data I wrote in a hardware-way. Can I do that? 

Thanks.
0 Kudos
27 Replies
Altera_Forum
Honored Contributor II
760 Views

Yes it's possible. 

 

Usually the dev kits will come with a sample design, and the NIOS tool has a simple memory checker you run to get started. 

 

Pete
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

OK I've found such an example but it seems to me (I'm not sure of that) that it's for an external memory and I want to access the internal FPGA memory. I need to know the signals and the protocol.

0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Binome, if you need to access a component (like an internal memory instance) from both hardware and software it's recommended that you use Qsys for that. You can use the "On-Chip Memory" component and connect it to your NiosII data master interface, this way the processor can read/write this memory through software. 

 

In order to access this memory using your hardware component you can adapt your component to use the Avalon Memory-Mapped interface protocol. You can found information about it in the Avalon Interface Specification: http://www.altera.com/literature/manual/mnl_avalon_spec.pdf 

 

Your hardware component can be imported into Qsys by creating a custom component. You can find information about it here: 

http://www.altera.com/literature/hb/qts/qsys_components.pdf 

 

Also, there are free online video trainings on the Altera website, please check the Introduction to Qsys and Custom IP Development Using Avalon and AXI Interfaces
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Thank you for all these explanations. 

 

What I don't understand is the differences between Quartus II,Nios II, SOPC, QSys,... 

Wouldn't it be nice if the MegaWizard of Quartus II could create a microprocessor directly? 

Can I have a symbol for my processor to make it appear in my schematic top-level? 

Why have I to create an Avalon interface for the hardware part to communicate with the memory? Can't I create the memory with the MegaWizard in Quartus II and implement the signals directly in the hardware?
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Sure Binome, let's go: 

 

Qsys is the next generation of SOPC Builder, so you can forget about SOPC Builder and use Qsys only. It's an integration tool that is potentially faster to build bigger systems with than schematics. That's because when you use schematics you must connect each wire by itself, while using Qsys you can connect interfaces with a bunch of wires and get automatic arbitration, bus width adjustment, etc. You can get a lot more information about Qsys in the "Introduction to Qsys" online training I told you about, you just have to register for free, so here's the link: 

http://www.altera.com/education/training/courses/oqsys1000 

 

There are some IPs you have in MegaWizard and are not available in Qsys, and also the opposite. So a Nios processor is one of these components: it's only available inside Qsys. And the reason why is that it's much easier to create a complet SoC system inside Qsys than schematics or HDL. You can, however, open Qsys and insert a Nios processor only and export all processor interfaces to the outside world, and then generate a symbol for this. When you try to connect this symbol in your schematic you will understand why you shouldn't ;) 

 

I think you should give Qsys a chance. Maybe you need some time to learn how to use it, but for sure it will save you much more time later, as it's really faster to integrate and reuse components. I work with Altera tools all day long and it has been some years we don't have a single project without a Qsys system on it, even when there's no processor. I think the online training I sent you the link is the right starting point for you, give it a try!
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Binome,  

I got a Terasic DE0-nano board with a Cyclone IV FPGA. My design is writing data in the memory. I use a NIOS II softcore too and I'd like it to read the FPGA memory and the data I wrote in a hardware-way. Can I do that? 

 

I have used the SDRAM with a Nios a few time. So yes it is possible.  

In fact only the other day I wrote a blog post about it here: http://geobyjmhembeddedengineer.blogspot.co.uk/2014/05/connecting-sdram-to-nios-ii-on-de0-nano.html 

 

There is also a good app note by altera: ftp://ftp.altera.com/up/pub/altera_material/11.0/tutorials/verilog/de0-nano/using_the_sdram.pdf 

 

Hope this helps 

 

geobyjmh
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Geobyjmh, 

your blog is really good for my need ! I memorize the url. Thanks. 

And do you know how the Nios II cpu can read simply the FPGA memory, not the board SDRAM?
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

You can: 

* insert your FPGA memory inside Qsys (On-Chip Memory) -- but then you would have a hard time getting your custom component outside Qsys to write to that memory, unless you use a bridge (below) 

* insert an Avalon Bridge and connect Nios to it's slave interface, then export the master interface. Use the Avalon signals to connect it to your MegaWizard memory in the top level. This is the only way I've found in years to connect your processor to something outside Qsys. I've just tried with the Avalon Pipeline Bridge but the signals won't match your memory interface, you need a bridge with the right subset of signals. As there's none, I've made one for you -- just rename to .tcl and put it in the same directory as your .qsys. 

 

It took me not more than five minutes to make this component, that's why I insist that you read the documents and watch the free trainings I told you about, as they will teach you how to do it, as you will certainly need it sooner or later.
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

There's something I don't get: 

I've read the documents and practiced some tutorials. 

I've added an Avalon-MM pipeline bridge and connected it as you told me in my Qsys system. The symbol has ten new signals (waitrequest, readdata, readdatavalid, burstcount, writedata, address, write, read, byteenable, debugaccess) but my top-level on-chip memory has only 6 (clock, data, rdaddress, wradress, wren, q). How should I connect them?
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Binome, these signals are connected automatically inside Qsys and are not necessarily meant to be exported. 

 

That's why I've attached my own custom Avalon MM Bridge in my previous reply -- it doesn't have these additional symbols for different types of Avalon MM transactions (like variable latency and bus width adjustment). 

 

If you use my bridge it should be straightforward to connect the signals, otherwise you might like to read more about Avalon Interface -- http://www.altera.com/literature/manual/mnl_avalon_spec.pdf
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

I've used another method: 

In Qsys I've instantiated a dual-port memory. One is connected to the data_master for reading purpose, the other is exported and connected to the logic in the symbolic top-level for writing. 

Tell me if that's bad.
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Sorry to bother you once more but I don't know how to use the tcl script. I've saved it in the same folder as my .qsys file but I don't know how to import this component in Qsys. 

 

Another thing: you didn't tell me why I can't use a dual-port memory in Qsys and simply export one of the ports to use it in Quartus II.
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

No problem, I'm sorry I didn't notice your previous post. 

 

Exporting an Avalon Slave interface of a dual port memory is fine, that's a good idea I haven't thought about. As long as you get the subset of Avalon signals you want there's no problem about it. 

 

The TCL script, when put in your Qsys folder, should be listed on the left side panel (library). It should be the first one listed. Remember to rename from .tcl.txt to .tcl and, if you're not using Quartus 13.1, please comment out the first line (package require -exact qsys 13.1). If you put the file there with Qsys running you have to refresh (F5) so it will appear in the library, otherwise it will be read when Qsys loads.
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

OK, 

I've created a system with a dual-port ram but (after recreating everything) it won't run the software: Eclipse is opening a window entitled "Create, manage and run configurations" with a pannel on the left side and five tabs on the right. 

Going back to a single-port ram and rebuilding everything is ok and the software works. 

Any idea of why?
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

After many tries and reprogramming, it finally works. 

Thank you for the explanations and your patience.
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

Nice, Binome! I'm glad to know that. 

 

Sorry for taking longer than expected to reply, it seems email notifications for forum replies are delayed, I've seen complains about it already... I hope it gets fixed soon
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

I think the different times are making the conversation difficult (I'm in France, you are in California, I think). 

 

I have another question: my Qsys design is instantiating a dual-port memory. s2 is exported so the hardware part can control different signals to write on it. Now I want the cpu to read on the s1 port. How can the software access all the signals to read on a specific address?
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

I'm in Brazil, that's GMT-3 so I guess we're four hours apart... 

 

You can access that memory in software using pointers. In your BSP you should have a system.h where the memory address is defined, like 

 

# define MEMORYNAME_BASE 0x08000000 

 

Then in your code you can: 

 

unsigned char *pmem = (unsigned char *)MEMORYNAME_BASE; 

 

You can cast your memory address to whatever pointer type you need. 

 

Be aware that access to this memory will be cached, so there's a risk that you're reading old data because it's on processor data cache (if your Nios is configured with data cache). 

 

In order to avoid caching you can set the first address bit. Nios has 32bit address space but it can address only 2GB, because the first address bit is used to bypass data cache. 

 

To make uncached memory access you can: 

 

unsigned char *pmem = (unsigned char *)(0x80000000 | MEMORYNAME_BASE);
0 Kudos
Altera_Forum
Honored Contributor II
760 Views

I don't exactly have that line. What seems to be the same is# define ONCHIP_MEM_BASE 0x8000 

It's only a matter of name but there's a matter of address too. I use a 32000 bytes memory so I need 15 bits for the address. Does 0x8000 mean that the memory is uncached and the 15 LSBs represant the address? 

So I could read the nth word with printf("%d\n",ONCHIP_MEM_BASE+(n-1))? 

 

I tried that in the HelloWorld template but a window open claiming "Errors exist in a required project." I don't have more information. What can I do?
0 Kudos
Altera_Forum
Honored Contributor II
738 Views

The 32nd NiosII Processor Data Master address bit is used to make uncached memory-mapped peripheral access. It means whichever slave you want to make uncached access, either a memory or another device, must have it's address bit 31 set to 1, that's why we do ADDR | 0x80000000 (pay attention to the number of zeroes used here!). So if you have 

# define ONCHIP_MEM_BASE 0x8000 

when you access the address 0x80008000 you will be making an uncached access to your memory. 

 

The line you suggested would print and address rather than memory content, and it would cache its contents. 

printf("%d\n",ONCHIP_MEM_BASE+(n-1)) 

You should make it a pointer of the correct type and then deference it, like this: 

printf("%d\n",*((int *)((0x80000000|ONCHIP_MEM_BASE)+(n-1)*4))); 

Note that I'm multiplying the index by four, that's because I'm casting the address to int, then each new int would be located for bytes apart from the other. 

 

You might as well prefer to use my explicit pointer aproach, where you would 

int *pmem = (int *)(0x80000000 | ONCHIP_MEM_BASE); 

and then 

printf("%d\n",pmem[n-1]); 

which would be much more convenient. 

 

The "Errors exist in a required project." should be further researched upon in order to be fixed. You should look for additional info in the "Problems" tab or in the "Console" tab. In the "Problems" tab you may see old compilation errors, so you may want to delete the errors before each compilation. In the "Console" tab you should click on the "screen" icon in the right side of the tabs bar, with the tooltip "Display Selected Console", and the select the console containing the compiler output. You may look for compilation errors there. 

 

I'm not very comfortable with Eclipse. If you prefer you can switch to the command line interface in order to debug. You can right click the project and select "Nios II" and then "Nios II Command Shell" in order to open a console where you can work from. You can then "make clean_all; make" and look for errors there. This is my preferred work flow (though I don't even open Eclipse).
0 Kudos
Reply