Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20684 Discussions

Beginners problems. i need assistance...

Altera_Forum
Honored Contributor II
1,466 Views

Before you read this: it may look like i am ranting and raving. That is not the case.  

I am just frustrated after a week of problems, that's all. 

 

All the questions i have are very simple basic questions. Things that take 1 click or 1 line of code in the IDE and C compilers from Keil or Tasking, yet turn out to be a complete nightmare in this NIOS IDE if you are starting with this tool coming from a diffrent environment ( 8051 C compiler from Keil ) 

 

I am sure that they are very easy for someone who knows this development environment. But for a starting idiot like me this is a friggin nightmare.  

 

For the past week i have been trying to get support from Altera on my questions. 

 

The mysupport is no good. I have now 6 open cases. None of them have been answered to my satisfaction. I have been playing ping-pong with them and ave only gotten half answers. I want to move forward. 

 

I have serious 'beginners' problems with the nios development tools. 

 

a simple example: 

 

Make a new C/C++ project. 

Add a file called main_program.c with the following code : void main(void) {} 

Click build. The builder crashes with some cryptic error. Now what ? 

 

Other questions i have that go unanswered : 

 

- How do i assign a variable to a specific address. ( like the _at_ directive in Keil's C51 ) 

- How do i write an interrupt handler ? ( in the 8051 world this is easy just write 'interrupt x) after your function header and you are done. the linkers know what to do) 

 

- What is the layout in memory of a progam ? I need to know exactly how a program is stored in RAM and how to put a binary file there. All the solutions given are only half solutions that either don't work or are plain wrong. Solutions like 'you need to make an SREC file' are not solutions. I need to see a step by step example. I don't know these command line tools. It took me a while to find out that this is a motorola S record and i need to use some tool called nios2-elf-objcopy to generate one. I played with the nios2-elf-objcopy a bit but can't get it to work. First it crashed because it couldnt find some DLL ( cygwin-whatever) after finding that and putting it in the same directory it still crashes.  

 

I want a step by step example. Besides, i don't want a motorola format. i need a simple binary file or intel hex file i can load into ram. ( i have access to the nios main SRAM through an avalon master. So i can read 4 bytes from the binary file at a time and store them as 32 bit words. When all is done i bring the nios out of reset and the program should begin executing. ( hopefully ... ) 

 

I want to know what the layout of the file is. If i read the first four bytes in the binary file  

these should go to the first 32 bit word ( my SRAM is 32 bit wide ) What is the byte layout ? 

suppose the file looks like this 

 

0xaa 

0xbb 

0xcc 

0xdd 

 

do i store DDCCBBAA into the first 32 bit word or do is store AABBCCDD into the first 32 bit word ? 

 

 

On the demo program : I don't need an operating system , i dont need the jtag debugger, i dont need 'printf' ( why is the printf demo 70 kilobyte when compiled ? it should be 25 bytes ... 12 to store the string 'hello world' and a couple of instructions to send them one by one to the uart and wait for the transmit flag to clear. anyway , back tot he point) 

 

i need nothing. The demo program i need is 20 lines of C code ( if i have such a demo i can adapt and extend it to handle the real job i want to run on the nios. i don't expect anyone to write my whole system. I have the system running on an 8051 but want to port to nios so i can do 32 bit arithmetic faster.  

 

All i need is a simple skeleton. I can take it from there.  

 

The program needs to react to 2 hardware interrupts, read data from some memory locations, do some simple calculations ( integer math ) perform a simple decision and write some output to some other memory locations. The compiled machine language program is maybe 30 instructions. 

 

here is the program in pseudo code : 

 

int a _at_ 0x00100000; // in the DPRAM 

int b _at_ 0x00100004; // in the DPRAM 

int c _at_ 0x00100008; // in the DPRAM 

int d _at_ 0x001F0008; // a hardware IO port ( register ) 

int e _at_ 0x001F0000; // a hardware IO port ( combinatorial block) 

 

void int_1_handler(void) handles interrupt 1 

c = ((b+1) << 4) +a; 

e=1; 

 

void int_2_handler(void) handles interrupt 2 

if c > 0 : c = c -1; 

e=1; 

 

void main (void) 

{ while 1  

if (d == 1) d = 0 else d =1; 

 

I have the nio shardwar ealready defined in SOPc builder and it synthesizes 

 

The nios has SRAM from 0000000 to 001FFFFF That is where the program ,stack and all other stuff needs to resides. 

 

0x001F00008 is a hardware io port. ( there is a peripheral mapped there ) 

Locations 0x001000000 and the others reside in an on board dual port ram. an external system loads data into A and B and triggers either interrupt 1 or 2. 

0x001F00008 is also a hardware port. (a custom peripheral. there is no 'memory' there. no flipflops are there, only an address decoder and some combinatorial logic. if a write is detected to bit 0 if that address a block of hardware is triggered that reads memory location 8 in the dual port ram to retrieve the data belonging to variable 'c'. 

 

After posting on various forums someone explained that i can use a define construction like : 

 

# define a (*(volatile unsigned int *) (0x00100000)) 

# define b (*(volatile unsigned int *) (0x00100004)) 

 

etcetera. is this correct ? Will the linker know it needs to stay away form those locations ? Will it know that it can not use those specific addresses to store anything ? 

What if i map variables in the main memory ( the main SRAM ) lets say i map something like this : 

# define global_q (*(volatile unsigned int *) (0x00004000)) 

 

this falls in the middle of the SRAM. will the linker know that this is no-go area and map both program and data around this specific location ? 

 

i have a bunch of variables that need to reside at very specific locations in SRAM because they get written through an avalon master port that can stop the NIOS, change the contents of those locations and let the NIOS resume. For some other storage is use dual port ram so i don't need to stop the nios. ( the nios will be busy in another memory region at that time. that is guaranteed by the way my hardware is built. ) DMA is not an option. i wan ttht nios to do one thing while i load a part of its memory with information for the next thing. 

 

More questions : 

How can i see the compiled output as machine language ( ASM opcodes ) (The Keil compiler can show you every single line of 'c' code and the machine language created for it. I would like to see what the compiler does with the code i write.) 

 

 

Is there ANYONE available who can spend half a day sitting next to me and guide me step by step on how to create a blank project with only an empty main routine and 2 interrupt handlers. I really need to 'see' how it is done. 

 

A big thanks upfront for the brave soul who want to help me. Oh, and it doesn't need to be for free. I am located in San Jose. 

 

desperate ...
0 Kudos
14 Replies
Altera_Forum
Honored Contributor II
654 Views

Hi, 

 

You should be able to find a good help related to Nios II questions in the "Nios Forum".  

 

-BD
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

yes i should.... unfortunately not. 

 

I have been playing hide and seek with the NIOs support and altera support for 2 weeks now. I have posted so many mysupport tickets and questions on forums ....
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

1. I have run into the system crash before as well. I find that if you build the project before you *** any files the problem goes away. 

 

2. NIOS II HAL already has an interrupt handler you can find information on how to use it here (http://www.altera.com/literature/hb/nios2/n2sw_nii52006.pdf).  

 

3. I don't think you can put a variable at a specfic address (some else may correct me); however, you can put it into a specific memory area. 

 

example: 

 

alt_u32 foo __attribute__((.section(".sdram"))); // usually a global variable  

 

you can find out which memory areas there are in the system library properties. 

 

4. Most of your question can be anwered in the nios ii software development handbook (http://www.altera.com/literature/hb/nios2/n2sw_nii5v2.pdf). 

 

5. Also I suggest you take the time to watch the Altera Demonstrations Course: nios ii integrated development environment (ide) overview (http://www.demosondemand.com/trainingapp/player/index.asp?sessid=alt075&promotion_id=1626&starttime=0), it will help you better understand the NIOS II IDE. 

 

6. All NIOS II Literature is here (http://www.altera.com/literature/lit-nio2.jsp). 

 

Hope this will answer your questions.
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

Thanks for replying. 

 

1) ok . i'll try that. 

 

2) HAL.... that leads me to believe 'operating system' which is not something i want.... ( i also have visions of a faint glowing red eye .. but that may be a figment of my imagination :) ). I read page 8-9 in that ISr document. 485 cycles to enter the interrupt and 222 to clean up? and 10 before it even vectors off ? what is wrong with the world.... 

an 8051 takes 4 clockpulses to vector off... and that thing is a 25 year old 8 bit 'toy' .... 

All that the cpu does is push the return vector on the stack and 1 or 2 registers. and off it goes. returning is the reverse. it takes a maximum of 10 cycles to enter and exit. Whats the point of having a 32 bit 500 MHz processor if an 12 MHz 8 bit runs faster... In my application the NIOs will get bombarded with interrupts. ( about 60.000 a second... ) this means i need a minimum of 60.000 x 700 ... 42 MHz just to enter exit the handler.... yikes. my system clock is 48 MHz .... looks like the good people form altera will have some explaining to do here .... 

 

3) The lack of a method to 'lock' a variable to a specific address would make the compiler for the NIOS the biggest piece of useless junk available. So i can't believe that this does not exist...  

Anyone who does memory mapped IO needs such a construction. My whole system is built around memory mapped IO. Heck, all the systems i have built the last 20 years use memoy mapped io. Whether they used 6802 6809 68000 8051 8096 i960 80166 80188 ARM in all its flavours , MIPS and a number of other processors as their base is irrelevant. All the compilers i have used ( assembly , PL/M , C ) have a provision to do this. 

 

4) i have no time to read all this stuff. I have a block of code that runs on an 8051 . it needs porting to NIOS so i can speed up the 32 bit arithmetic. The code is very very simple. ( about 1 kilobyte when compiled on an 8051 ) It just needs to be able to handle a couple of interrupts and deal with memory mapped i/o. And those 2 things seem to be a virtual impossibility on the NIOS 'monstrosity'... I have always been told that 'c' is the most portable language in the world .... right. and pigs can fly when the temperature in hell drops below 0 ... anyone has a BASIC compiler for this thing ? it would have been written in 2 minutes... 

 

5) i have watched that completely.But even that thing assumes to much. I have never used GCC in my life ( right now i am disgusted at that toolchain. Its full of loose ends and very poorly documented. Support is inexisting. All you can do is post your question on the internet and hope someone will answer .. I prefer tools i have to pay lots of money for. At least then i can call someone and yell at them if it does't work ( It may accomplish nothing, but it makes me feel better :) haha ) and they can solve the problem. 

 

Anyway, thanks for the suggestions.
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

[LIST] 

HAL is just a set of code that has drivers, file system, interrupt handler functions. It can be used in an OS but it does not need it to run. I am not sure if you can re-write the interrupt handler, if the NIOS II interrupt handler is too slow. Some else may know that answer.  

[/LIST] 

[LIST] 

You may have to change you methodology with the NIOS II CPU. The "system.h" holds all the memory mapping for the system (on the FPGA). This file is generated when you first build the project or with the ptf file changes. If you want to read/write to any device or port you can use IOWR/IORD macros in "io.h" header. 

[/LIST] 

[LIST] 

Your lack of knowledge on how the tool works is building your frustration. The debugging module from the NIOS II is setup in SOPC Builder if you want that removed you have to do it there. Also if you goto the project properties (right click on the folder) you can set the optimization for the project in the "C/C++ Build" Menu that should reduce you could size. In addition, The "System Library" menu, there are other settings you can use to reduce your code size. Such as, "Small C Library" or "Reduce device drivers". All of this is in the NIOS II Software Development Handbook. I suggest taking an hour to skim through it. 

[/LIST] 

[LIST] 

C is the most portable language in the world. Your code will compile for NIOS II, it just may not the way you want it to. Evey CPU is different so you may have to modified especially if your accessing memory at a specific location or an off chip devices. You can't assume if it works on an 8051 or ARM it's going to work on NIOS II the way you intended it to. 

[/LIST]
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

OK. Maybe I can help. 

 

You must keep this in mind. This is a fully configurable embedded system on an FPGA. In the end it is only an FPGA. Every compile of the FPGA is equivalent to a different single chip Microcontroller solution from any given uC vendor. 

 

Their tools do not have to deal with the complexity of an embedded system on an FGPA! They have all the time in the world to tweak and fix bugs for any given single uController they create - most haven't been changed in decades! 

 

The Nios tools must be able to handle the variability since no two systems are probably going to be alike. This will cause frustration for the uController casual user. 2 weeks is typically not nearly enough time to grasp all the complexity involved. Give yourself a break. Take a deep breath and open your mind to learning some real cool stuff. You are not going to benefit by comparing an arcane system like an 8051 to a dynamic environment in which soft processors in a configuratble hunk of silicon this gives you.

 

 

Add a file called main_program.c with the following code : void main(void) {}

Click build. The builder crashes with some cryptic error. Now what ?

Post the error message and I can try to help you there. BTW, it may be just as simple as adding a ; to the program (in between the { } like this: {;}. Most compilers really don't like an empty main() function anyways and it's not real world anyways. You may have better luck just putting in a while loop wiht a simple statement in the body. This is a typical ANSI-C type problem.

 

Other questions i have that go unanswered :

 

- How do i assign a variable to a specific address. ( like the _at_ directive in Keil's C51 )

Totally unnecessary in the Nios environment. The 8051 requires this since you typically have only 256 bytes of RAM and that is the way to access SFR's. This fine grain access (with the use of NON-ANSI standard constructs like '_at_') is necessary for severly limited resource processors like the 8051.

 

 

- How do i write an interrupt handler ? ( in the 8051 world this is easy just write 'interrupt x) after your function header and you are done. the linkers know what to do)

Again, the 8051 is a severly limited processor. The Keil construct is NON-ANSI standard because of this. With the Nios the HAL contains the interrupt vector handler. You do not need to write one. All Altera and most vendor IP peripherals have their own drivers as well. But in the cases where you need to write your own handler (for your custom peripheral) then the HAL API provides for this. You can review the API here. Pay attention to the collection of functions around alt_irq_register() on page 12-34.

 

 

- What is the layout in memory of a progam ? ... 

 

I want a step by step example. ...

The need you require depends on an understanding of the system you are creating. In terms of compiling and debugging you don't need to do anything. The debugger in the IDE knows how to read your elf file (elf is the binary format output for the Nios) and write it to the correct memory for debugging. The Nios flash programmer knows how to program tye CFI flash in your system if you decide to use one (highly recommended). All in all you should never have to mess with the elf file or the .flash file other than compiling, debugging and programming the flash.

 

You can use many of the command line tools to do what you want in the case you need something special. FOr the most part there is nothing you can't do.

 

If you get errors with cygwin then your quartus/nios installation is hosed. Uninstall everything and re-install in this order: Quartus, Megafunctions IP, Nios, Modelsim (if you want to do HDL simulations).

 

Note for a step by step example see the tutorial link at the end of my post.

 

I want to know what the layout of the file is. ...

Nios is little endian. You would store 0xDDCCBBAA into the first word.

 

...All i need is a simple skeleton. I can take it from there. ...

Since you are a beginner I highly recommend you walk before running. Focus on learning the tools and then use the tools to get what you want. I'm not saying you can't do what you are asking. It can be done. But you will go through a process of "why, why,why" everytime you see somthing you are not familiar with. 

 

It may seem that what you are trying to do is simpler but in fact it isn't. You are trying to use the tools in a non-standard way (remember soft processor in a programmable FPGA - no where near as simple as working with a 40 year old architecture like an 8051) which makes the development process much more complicated.

 

BTW, You absolutely do need the JTAG debugger. Trust me on this. Turn it on and leave it on until you are an expert enough with the tools and systems and know the consequences of turning it off. You will need to use the debugger and you cannot debug without the JTAG debugger.

 

...After posting on various forums someone explained that i can use a define construction like :

 

#define a (*(volatile unsigned int *) (0x00100000))

#define b (*(volatile unsigned int *) (0x00100004))

This is correct. This is the proper ANSI accepted way of accessing specific memory locations. No need for a NON-ANSI construct like "_at_" with a full ANSI compliant compiler (note the Keil compiler uses a non standard implementation of pointers which is one of the reasons it uses many NON-ANSI constructs. Being an expert in Keil C for the 8051 does not make one an expert in ANSI C).

 

Will the linker know it needs to stay away form those locations ? ...

The linker will only link to the RAM you define in the <project>_syslib properties in the IDE. 

 

Again, you do not need to place variables at specific locations with the Nios. 

 

i have a bunch of variables that need to reside at very specific locations in SRAM because they get written through an avalon master port that can stop the NIOS, change the contents of those locations and let the NIOS resume. ...

In this case you need 2 seperate RAM's. One for the Nios code, heap and stack and the other for your custom implementation. Define the Nios RAM for use with the linker in the <project>_syslib properties dialog box. Note that onchip memory is available to you if you only have a single off chip SRAM/SDRAM/etc.

 

... How can i see the compiled output as machine language ( ASM opcodes ) ...

Use the output of objectdump. You can turn it on by going to the Windows menu bar in the ide and selecting the "preferences" menu option. In the dialog box that comes up, click on Nios on the left hand side. On the right side there will be a checkbox for "objdumP" turn it on. The objdump file will reside in the same place as your elf file (typically here: <project>/Debug/<project>.elf.objdump).

 

This text file has a full link map, symbol map and the 'C' code interspersed with the assembler output.

 

...desperate ...

I know some of my answers may frustrate you. I apologize up front for that but I want to make sure you understand why you will get a lot more out of the tools by understanding how they work first and then how to do what you want to do. 

 

Based on your questions it would seem the 8051 might be all you have worked with. Nios on an FPGA is a different universe than that. You have only scratched the surface of the differences. Understanding the tools better will help you determine if the approach to your designeven makes sense.

 

Here are some resources to help you better:

 

Nios II Development Kits. If you don't have one get one. You can't do any tutorials without it and all of the quartus design examples will work with these kits out of the box. This is absolutely necessary to develop a comfort level with the tools. ALso having a kit will allow you the freedom to explore without troubleshooting a PCB on top of an FPGA and SW all at once. 

 

Nios processor reference manual - Read it cover to cover.

Software Developers handbook - Read it cover to cover.

 

Nios II HW tutorial - You must do this tutorial.

 

Nios II Processor Online Demonstrations - You must view as many of these as you can

 

With some patience you can discover how the Nios II on an FPGA is soooo much more than a simple 8051. There is no free lunch. Once you get a good grasp you will see how the flexibility of this design methodolgy can help you in ways you never before thought possible. 

 

Good Luck!

 

Rick

0 Kudos
Altera_Forum
Honored Contributor II
654 Views

 

--- Quote Start ---  

 

2) HAL.... that leads me to believe 'operating system' which is not something i want.... ( i also have visions of a faint glowing red eye .. but that may be a figment of my imagination :) ). I read page 8-9 in that ISr document. 485 cycles to enter the interrupt and 222 to clean up? and 10 before it even vectors off ? what is wrong with the world.... 

an 8051 takes 4 clockpulses to vector off... and that thing is a 25 year old 8 bit 'toy' .... 

All that the cpu does is push the return vector on the stack and 1 or 2 registers. and off it goes. returning is the reverse. it takes a maximum of 10 cycles to enter and exit. Whats the point of having a 32 bit 500 MHz processor if an 12 MHz 8 bit runs faster... In my application the NIOs will get bombarded with interrupts. ( about 60.000 a second... ) this means i need a minimum of 60.000 x 700 ... 42 MHz just to enter exit the handler.... yikes. my system clock is 48 MHz .... looks like the good people form altera will have some explaining to do here .... 

 

--- Quote End ---  

 

 

The HAL gets involved only as deep the peripherals you use. You can eliminate all peripheral drivers and effectively the HAL is eliminated. It is an advanced subject as to how to do this but I can explain later. 

 

There is an interrupt accelerator available to help speed up the handler time. For most high performance systems interrupts are simply not used. DMA's are used. And for good reason.  

 

It makes no sense to use a processor for only handling interrupts. That's why it is not a critical issue for the Nios - even with the numbers you pointed out. The DMA controller is a very simple device and can do what you need. Again, like my previous post, you are going to need to learn the tools to get the best and most effective use of them. 

 

 

--- Quote Start ---  

 

 

3) The lack of a method to 'lock' a variable to a specific address would make the compiler for the NIOS the biggest piece of useless junk available. So i can't believe that this does not exist...  

Anyone who does memory mapped IO needs such a construction. My whole system is built around memory mapped IO. Heck, all the systems i have built the last 20 years use memoy mapped io. Whether they used 6802 6809 68000 8051 8096 i960 80166 80188 ARM in all its flavours , MIPS and a number of other processors as their base is irrelevant. All the compilers i have used ( assembly , PL/M , C ) have a provision to do this. 

 

 

--- Quote End ---  

 

 

Most high performance systems like the ARM use the (*(volatile unsigned int *)0xXXXXXXXX) construct as well. This is an industry standard not found typically in low performance systems like limited resource 8 bit processors. 

 

 

--- Quote Start ---  

 

 

4) i have no time to read all this stuff. I have a block of code that runs on an 8051 . it needs porting to NIOS so i can speed up the 32 bit arithmetic. The code is very very simple. ( about 1 kilobyte when compiled on an 8051 ) It just needs to be able to handle a couple of interrupts and deal with memory mapped i/o. And those 2 things seem to be a virtual impossibility on the NIOS 'monstrosity'... I have always been told that 'c' is the most portable language in the world .... right. and pigs can fly when the temperature in hell drops below 0 ... anyone has a BASIC compiler for this thing ? it would have been written in 2 minutes... 

 

5) i have watched that completely.But even that thing assumes to much. I have never used GCC in my life ( right now i am disgusted at that toolchain. Its full of loose ends and very poorly documented. Support is inexisting. All you can do is post your question on the internet and hope someone will answer .. I prefer tools i have to pay lots of money for. At least then i can call someone and yell at them if it does't work ( It may accomplish nothing, but it makes me feel better :) haha ) and they can solve the problem. 

 

Anyway, thanks for the suggestions. 

--- Quote End ---  

 

 

I am sorry you feel this way. I would highly recommend you terminate your attempt to use the Nios if you are not willing to spend the time necessary to learn it. You will not get any benefit of what soft processors on an FPGA can give you for the reasons you cite. 

 

If the 8051 can give you what you need then the Nios and FPGA's is probably not for you. 

 

Good Luck! 

 

Rick
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

 

--- Quote Start ---  

 

HAL is just a set of code that has drivers, file system, interrupt handler functions. It can be used in an OS but it does not need it to run. I am not sure if you can re-write the interrupt handler, if the NIOS II interrupt handler is too slow. Some else may know that answer.  

 

--- Quote End ---  

 

spooky.... i dont need drivers or file system. so why do i need the hal ? get rid of it. if i can read and write memory thats all i need. i dont need 'printf' and all that other stuff. 

 

 

--- Quote Start ---  

 

If you want to read/write to any device or port you can use IOWR/IORD macros in "io.h" header. 

 

--- Quote End ---  

 

i noticed those as well but that makes the program look very strange. 

instead of doing this : 

a = a + 1 

 

you'd have to do 

a = ioread ( adress_of_a) 

a = a+1 

iorwite adress_of_a ,a ) 

 

that is just plain stupid. 

 

 

--- Quote Start ---  

 

Your lack of knowledge on how the tool works is building your frustration.  

 

--- Quote Start ---  

 

 

fully correct. these tools are completely different than what i am used to ( Keil , Raisonnance , IAR , Intel) The problem is i am pressed for time. I've got 5 engineers breathing down my neck. If i have a person next to me that know the tools and i can explain what i want to do it would take 1 hour to set it up and write the skeleton code. I will never in my life deal with that stuff again. I'm not interested in becoming a tool guru . I just need an environment so i can concentrate on the job i need the cpu to do. I'm not interested in knowing how to set up the environment. That should be done by the people making the tool.  

 

It's like learning how to drive a car. I buy a car from intel or atmel or motorola or arm. A Vendor like Keil and IAR gives me the key and lends me a person to teach me how to drive. you also get a phone number you can call if you have trouble figuring something out. 

 

Altera gives you a box of assorted parts. ( some of them you don't even need ) . A book on how a combustion engine works . a 10.000 page manual on how to assemble a car .... and if you have a problem : feel free to ask your neighbour ... we don't know and can't be bothered. 

That's what it feels like. 

 

 

 

--- Quote Start ---  

 

C is the most portable language in the world. Your code will compile for NIOS II, it just may not the way you want it to. Evey CPU is different  

--- Quote End ---  

 

no n the first statement. yes on the second. 

if i write this 

 

int a _at_ 0x1000 

int b _at_ 0x1001 

a = b +1; 

 

and send this through the Keil compiler for an 8051 the code it will perform as intended 

If i send the same code through the compiler for an ARM it will do exactyl the same thing. 

 

take the contents of memory location 0x1001, add '1' to it and drop the result in 0x1000 

 

If i send it to the compiler from IAR it will also compile without a hitch.  

 

if i send it through GCC the compiler barfs ands says :surry bub but i dont know what _at_ means....  

 

that's what i mean.
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

 

--- Quote Start ---  

OK. Maybe I can help.  

 

-snip-  

 

in assmbly my main program would look like this : 

begin : sjmp begin; 

 

nothing more real world than that. 

 

Anyway. before we go off on tangents here is what the system mechanism has to do : 

This will also explain why i can not use things like DMA. 

 

I have a main memory ( SRAM ) that will hold program , stack ,heap ,scratchpad, whatever. i dont care what how the compiler stuffs the program in there it can do whatevere it wants. 

 

here is a simplified description : 

 

I have 2 dual port rams ( DPRAM1 and DPRAM2 ). i also have two interrupt sources and 2 io ports. 

An external system loads data into dual port RAM 1 at very specific locations. ( hence i need to be able to define absolute addresses in the NIOs program so the program can read this data. ) 

 

when the data is loaded this external system tickles interrupt 1. the nios roars to life and starts crunching the data in DPRAM 1. The results are written back to very specific locations of DPRAM 1 ( so that the external hardware can retrieve them). When the NIOS is done it sets io port 1 to '1' signalling the outside world 'i am done , data has been posted , i'm going back to sleep. wake me when you need me ' 

 

While the nios was crunching the data in DPRAM using interrupt handler 1 the external hardware was not sitting still either. It has loaded data in DPRAM2. DMA would block bus access and stall the nios ! that would be unacceptable . hence i use dual port ram. problem goes away. maybe my perception of DMA is wrong i don't know. the important bit is the program needs to keep crunching away while i am modifying memory locations that are not in use by that piece of code.) 

 

When the external block sees that the nIOs has set PIO1 it understands that the nios is done. the external hardware now tickles interrupt 2. the nios jumps to attention and interrupt handler 2 jumps to life. crunching data in DPRAM2 with an completely different algorithm. in the mena time the external hardware offloads DPRAM1 and stuffs new data in there. 

 

In the real application there will be tons of DPRAM's and tons of interrupts. 

each interrupt i a different algorithm. each dpram has a diffrent memory layout. 

 

to minimize all the shuffling typically associated with a program: 

 

- i hardcode all variables at specific adresses. that way the outside world know what to put where. 

- only one interrupt at a time is running. an external hardware scheduler takes care of that (a simple one-hot state machine ) 

- the processes on the nios do not communicate with each other. 

 

i dont even need a printf. There is a dedicated DPRAM to give me messages. the nios just dumps data there and sets an io flag. the external hardware takes care of reading the bytes and sending them , including handshake, to the uart. the nios does not need to spend time on that. 

 

I can not divulge what the system is for or why it needs to work this way. It suffices to say that it does work. ( i have it running on an 8051. i just lack clockspeed to do 32 bit arithmetic. something i was hoping to solve with this NIOS thing. since i have the FPGA anyway : dream solution. make the system in SOPC builder. map 8 DPRAMs ( each 256 bytes ) 8 interrupts and 8 pios. write half a page of code. attach exisiting algorithm code. compile and run... tops a few days ... its been weeks..... 

 

 

--- Quote Start ---  

 

All Altera and most vendor IP peripherals have their own drivers as well.  

 

--- Quote End ---  

 

 

i know and that is all very beautiful if you are a software developer and will use these modules. I don't. all i need is a number cruncher. i prepare data , it crunches, i load other data meanwhile when its done i offload and it begins with next block. 

 

i like to call this 'software assisted hardware' 

 

 

--- Quote Start ---  

 

The debugger in the IDE knows how to read your elf file (elf is the binary format output on the debugger and flash and SREc and all the other stuff. 

 

--- Quote Start ---  

 

 

my system doesnt have flash. the program on the nios is loaded dynamically. it can even change a few times a minute. One moment its running this set of algorithms , the next minute it is running a completley different set of algortihms. 

 

The easiest way to do this for me is : disconnect the SRAM from the nios : load the program image in the SRAM , reconnect and release the reset pin from the nios. 

 

This loading happens through a USB port from the PC. The nios is used as a hardware accelerator. PC drops correct program in the nios memory. PC dumps data in DPRAM , tickles nios. pc drops more data in diffrent dpram. and collects when nios is done. 2 seconds later a diffrent program gets loaded.  

most programs are small. 1 or 2 kilobyte of code. 

 

 

--- Quote Start ---  

 

Nios is little endian. You would store 0xddccbbaa into the first word. 

 

--- Quote End ---  

 

 

thank you. that is what i needed to know. can you believe this has taken 2 weeks to find out ? 

 

 

 

--- Quote Start ---  

 

Since you are a beginner I highly recommend you walk before running. Focus on learning the tools. 

 

--- Quote Start ---  

 

beingnner with nios and the toolchain yes. ive been programming this kind of systems for 20 years. using various toolchains and cpu architectures. most of the time switching meant 1 or 2 days of work. this nios has teken me 2 weeks and i still cant synthesize the core in SOPC builder ( some funny error in 7.2 about 2 clocks that worked fine in 7.1 ) 

 

I will use jtag debugger for myself yes. but the final system needs to run without. This thing is going in the field an JTAG will be disabled. can't have anyone snooping around in there while it's running ... 

 

 

--- Quote Start ---  

 

Again, you do not need to place variables at specific locations with the Nios.  

 

--- Quote End ---  

 

 

not in the main memory. there i don't care. but i need to be able to lock them down in the dpram's. 

 

 

--- Quote Start ---  

 

In this case you need 2 seperate RAM's. One for the Nios code, heap and stack and the other for your custom implementation. Define the Nios RAM for use with the linker in the <project>_syslib properties dialog box. Note that onchip memory is available to you if you only have a single off chip SRAM/SDRAM/etc. 

 

--- Quote End ---  

 

 

there we go that is what i am attempting. I figured this out in the linker settings. 

 

 

--- Quote Start ---  

 

Use the output of objectdump. You can turn it on by going to the Windows menu bar in the ide and selecting the "preferences" menu option. In the dialog box that comes up, click on Nios on the left hand side. On the right side there will be a checkbox for "objdumP" turn it on. The objdump file will reside in the same place as your elf file (typically here: <project>/Debug/<project>.elf.objdump). 

 

This text file has a full link map, symbol map and the 'C' code interspersed with the assembler output. 

 

--- Quote End ---  

 

 

YES ! wooohooo. that is what i needed thank you thank you thank you ! now i can see what that compiler produces. 

 

got an ADLs modem at home ? thats me .... and the same mechanism sits in the modem there... throw data in a bucket, have cpu crunch it. in the mean time unload the previous bucket and fill the next. when cpu is done tell him what bucket to crunch next. 

took half a day to configure an ARM 7 .... one more day to write some verilog and slap it in an ASIC. works like a charm. easy to work with and you can tweak the algorithms.  

(which would not be possible with a hard implementation. ) I am essentially using the NIOS to emulate hardware. i know i could write it directly in verilog but the algorithms need to be user modifyable. hence :code in c : compile , upload : run. 

user is not allowed to touch FPGA contents nor get the guts of the system ( there is other stuff in the FPGA that needs to remain hidden... )
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

 

--- Quote Start ---  

in assmbly my main program would look like this : 

begin : sjmp begin; 

 

nothing more real world than that. 

 

Anyway. before we go off on tangents here is what the system mechanism has to do : 

This will also explain why i can not use things like DMA. 

 

I have a main memory ( SRAM ) that will hold program , stack ,heap ,scratchpad, whatever. i dont care what how the compiler stuffs the program in there it can do whatevere it wants. 

 

here is a simplified description : 

 

I have 2 dual port rams ( DPRAM1 and DPRAM2 ). i also have two interrupt sources and 2 io ports. 

An external system loads data into dual port RAM 1 at very specific locations. ( hence i need to be able to define absolute addresses in the NIOs program so the program can read this data. ) 

 

when the data is loaded this external system tickles interrupt 1. the nios roars to life and starts crunching the data in DPRAM 1. The results are written back to very specific locations of DPRAM 1 ( so that the external hardware can retrieve them). When the NIOS is done it sets io port 1 to '1' signalling the outside world 'i am done , data has been posted , i'm going back to sleep. wake me when you need me ' 

 

While the nios was crunching the data in DPRAM using interrupt handler 1 the external hardware was not sitting still either. It has loaded data in DPRAM2. DMA would block bus access and stall the nios ! that would be unacceptable . hence i use dual port ram. problem goes away. maybe my perception of DMA is wrong i don't know. the important bit is the program needs to keep crunching away while i am modifying memory locations that are not in use by that piece of code.) 

 

When the external block sees that the nIOs has set PIO1 it understands that the nios is done. the external hardware now tickles interrupt 2. the nios jumps to attention and interrupt handler 2 jumps to life. crunching data in DPRAM2 with an completely different algorithm. in the mena time the external hardware offloads DPRAM1 and stuffs new data in there. 

 

In the real application there will be tons of DPRAM's and tons of interrupts. 

each interrupt i a different algorithm. each dpram has a diffrent memory layout. 

 

to minimize all the shuffling typically associated with a program: 

 

- i hardcode all variables at specific adresses. that way the outside world know what to put where. 

- only one interrupt at a time is running. an external hardware scheduler takes care of that (a simple one-hot state machine ) 

- the processes on the nios do not communicate with each other. 

 

i dont even need a printf. There is a dedicated DPRAM to give me messages. the nios just dumps data there and sets an io flag. the external hardware takes care of reading the bytes and sending them , including handshake, to the uart. the nios does not need to spend time on that. 

 

I can not divulge what the system is for or why it needs to work this way. It suffices to say that it does work. ( i have it running on an 8051. i just lack clockspeed to do 32 bit arithmetic. something i was hoping to solve with this NIOS thing. since i have the FPGA anyway : dream solution. make the system in SOPC builder. map 8 DPRAMs ( each 256 bytes ) 8 interrupts and 8 pios. write half a page of code. attach exisiting algorithm code. compile and run... tops a few days ... its been weeks..... 

 

 

 

i know and that is all very beautiful if you are a software developer and will use these modules. I don't. all i need is a number cruncher. i prepare data , it crunches, i load other data meanwhile when its done i offload and it begins with next block. 

 

i like to call this 'software assisted hardware' 

 

my system doesnt have flash. the program on the nios is loaded dynamically. it can even change a few times a minute. One moment its running this set of algorithms , the next minute it is running a completley different set of algortihms. 

 

The easiest way to do this for me is : disconnect the SRAM from the nios : load the program image in the SRAM , reconnect and release the reset pin from the nios. 

 

This loading happens through a USB port from the PC. The nios is used as a hardware accelerator. PC drops correct program in the nios memory. PC dumps data in DPRAM , tickles nios. pc drops more data in diffrent dpram. and collects when nios is done. 2 seconds later a diffrent program gets loaded.  

most programs are small. 1 or 2 kilobyte of code. 

 

 

 

thank you. that is what i needed to know. can you believe this has taken 2 weeks to find out ? 

 

beingnner with nios and the toolchain yes. ive been programming this kind of systems for 20 years. using various toolchains and cpu architectures. most of the time switching meant 1 or 2 days of work. this nios has teken me 2 weeks and i still cant synthesize the core in SOPC builder ( some funny error in 7.2 about 2 clocks that worked fine in 7.1 ) 

 

I will use jtag debugger for myself yes. but the final system needs to run without. This thing is going in the field an JTAG will be disabled. can't have anyone snooping around in there while it's running ... 

 

 

 

not in the main memory. there i don't care. but i need to be able to lock them down in the dpram's. 

 

 

 

there we go that is what i am attempting. I figured this out in the linker settings. 

 

 

 

YES ! wooohooo. that is what i needed thank you thank you thank you ! now i can see what that compiler produces. 

 

got an ADLs modem at home ? thats me .... and the same mechanism sits in the modem there... throw data in a bucket, have cpu crunch it. in the mean time unload the previous bucket and fill the next. when cpu is done tell him what bucket to crunch next. 

took half a day to configure an ARM 7 .... one more day to write some verilog and slap it in an ASIC. works like a charm. easy to work with and you can tweak the algorithms.  

(which would not be possible with a hard implementation. ) I am essentially using the NIOS to emulate hardware. i know i could write it directly in verilog but the algorithms need to be user modifyable. hence :code in c : compile , upload : run. 

user is not allowed to touch FPGA contents nor get the guts of the system ( there is other stuff in the FPGA that needs to remain hidden... ) 

--- Quote End ---  

 

 

OK. Cool stuff. FPGA's are perfect for what you are doing. 

 

Some ideas to help you deal with interrupt latency: 

 

1. You can eliminate the HAL interrupt vector. BUt I am not going to tell you how because I really don't want to cause you more frustration. It involves re-writing the crt0.s file and I consider that an advanced programming topic alone, let alone dealing with the Nios system. It will take a long while to do. Part of the complexity also involves GCC and linker scripts which can be frustrating as well. Basically you have to undo everything put in to handle embedded processors on an FPGA to create your "custom" implementation. 

 

Regardless a _big_ part of the interrupt latency is unavoidable because of the housekeeping needed as required by the Nios ABI (application binary interface - this is documented in the processor reference manual) which you would have to include. If you select interrupt 0 for your interrupt then you will get the fastest vector (THe HAL handler queries the Interrupt status bits one at a time starting with bit 0 which correlates to Interrupt 0).  

 

2. Use the interrupt vector accelerator. This is defined as the Interrupt Vector custom instruction found on the last tab in the Nios Wizard (double click the Nios in SOPC Builder). Just add it in and rebuid your system. The HAL interrupt vector SW will use it if it exists in teh system (just like adding HW multiply and divide and other CPU features will be used by GCC). It will make a big differece in interrupt latency. 

 

3. Use TCM memories to eliminate processor additional latency. TCM's guarentee the fastest processor execution (no wait states reading from memory). See the tutorial here (http://www.altera.com/literature/tt/tt_nios2_tightly_coupled_memory_tutorial.pdf). This can be used in addition to other suggestions here. 

 

4. Use multiple Nios processors. Use one for each DPRAM function you have. See the tutorial found here (http://www.altera.com/literature/tt/tt_nios2_multiprocessor_tutorial.pdf) if you are brave enough to try it. Personally I would consider this the best solution based on what you ahve said so far. 

 

Thanks, 

 

Rick
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

I think you will benefit greatly by adding 2 appnotes to your reading list. The first is recently released and marked with a red "New" flag, titled "AN 459: Guidelines for Developing a Nios II HAL Device Driver", listed in the "Software Development" section of the Nios II Literature page. It provides an example for HAL Memory Mapped I/O. (Nice 2001 - A Space Odyssey reference by the way. I hadn't heard that one yet :cool:  

 

See also for a skeleton which shows installation of a timer interrupt handler in fast on-chip memory an appnote titled "Using Nios II Tightly-Coupled Memory Tutorial", listed in the "Hardware and System Development" section. (This is the same one Rick mentions in point number 3 below). Both documents come with example software files to download as well. Grab the "Design file" and "bit_bang_uart.c file" links below each of the docs. Both are available on the Nios II Literature page, at: 

 

http://www.altera.com/literature/lit-nio2.jsp 

 

You will soon learn about the true beauty of the soft-cores in FPGA solution, where you could decide to throw down 60 Nios processors into one FPGA (granted, a larger sized variety of FPGA), each one dedicated to handling a single interrupt, all running truly in parallel in hardware.  

 

I think you will like the performance boost afforded by our exception handling custom instruction as well (also mentioned by Rick). This essentially extends the Nios II architecture instruction set with any command you would like to perform entirely in hardware. You can also write your own custom instructions, but we wrote the one to speed up the exception handling funnel for you.  

 

Additionally, be sure to always include the System ID component in your hardware design. This will save you hours of frustration chasing a problem if you accidentally load a syslib which does not match the currently loaded SOPC Builder design, by catching it and warning you during the attempt to download. 

 

Best of luck, and welcome to the world of soft-core microprocessors!
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

spooky .... 

 

int x =0; 

int main(void) 

x = x+1; 

 

 

Needs 6482 bytes of code with optimize set to 3 ( smallest footprint ) 

Any leads on how to tune the compiler more ? 

 

I had a long discussion today with some 'experts'.  

 

The outcome is : NIOS in the trashcan. 

This thing is completely un-usable as a processor core. Maybe if you want to start 'accelerating' functions and use all the advanced stuff. but as a generic core ? useless. 

 

Right now i stuffed an 8051 IP core in the FPGA. 1400 Le's. It's ticking away happily at 48 MHz ( its a single clock core. only MUL and DIV take 4 ticks and JMP takes 2 ticks ) i can blast it with interrupts at over 1 MHz.. and its still sleeping 40 % of its time... try doing that with a nios at 48 MHz... 

 

Somebody needs to wake up at altera and fix this processor (and the toolchain for that matter) ...  

 

SOPC builder 7.2 has a serious bug ! 

 

if you instantiate an avalon master and click 'generate', the master port is not brought to the outside world. you can not connect to it ! I have a bunch of things that connect to an avalon master port... whoops .... there goes the design. ( DPRAM sits in SOPC builder. the second port comes out through an avalon master port. )
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

 

--- Quote Start ---  

spooky .... 

 

int x =0; 

int main(void) 

x = x+1; 

--- Quote End ---  

 

 

I got 156 bytes following the hello_world_small example. 

 

 

--- Quote Start ---  

SOPC builder 7.2 has a serious bug ! 

 

if you instantiate an avalon master and click 'generate', the master port is not brought to the outside world. you can not connect to it ! I have a bunch of things that connect to an avalon master port... whoops .... there goes the design. ( DPRAM sits in SOPC builder. the second port comes out through an avalon master port. ) 

--- Quote End ---  

 

 

Are you exporting the signals that you want to see at the top-level of your SoPC Builder design? 

===== 

Many people find SoPC Builder and Nios II highly useful. Wart and "foible" free: No. Useful: Yes. 

 

You might be correct that it won't suit your needs for this particular application, but to write it off completely is being short-sighted, at best. 

 

From what I know (very little) of your application, I'd advise you to: 

 

1. Follow the hello_world_small example for code size reduction. 

- Alternately, you could look at the hello_alt_main or hello_led examples, which circumvent the HAL layer entirely, though I wouldn't advise doing it until you really know your way around a Nios II based system. 

2. Utilize the Interrupt Vector custom instruction. 

3. Look at re-designing your hardware to better suit the way in which Nios II/Avalon function. 

 

Good luck!
0 Kudos
Altera_Forum
Honored Contributor II
654 Views

thanks 

 

1) that seems to work better. 

2) done that. its still too slow.... 

3) can't change an ASIC ... i am using the FPGA to emulate the ASIC. the ASIC design is done the way it's done. I have no control over it ( for very specific reasons ... )
0 Kudos
Reply