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++

A big bug?

Altera_Forum
Honored Contributor II
1,258 Views

Hi, 

Here is a simple program:# include <stdio.h># include <io.h># include "sys/alt_stdio.h"# include "alt_types.h"# include "system.h" 

 

alt_u8 SND[1100]; 

 

int main() 

int i; 

int prt1; 

alt_u8 *p8; 

alt_u32 *p32; 

for(i=0;i<100;i++)SND=0; 

snd[47]=9; 

snd[46]=8; 

p8=snd+48; 

p32=(alt_u32 *)p8; 

*p32=0x11223344; 

prt1=(int)p32; 

i=prt1 & 0x3; 

 

uartprintf("\n\n\n\nsnd48 | 4=(%d:%d),%x,%x,%x,%x,%x,%x,\n",prt1,i,snd[46],snd[47],snd[48],snd[49],snd[50],snd[51]); 

 

for(i=0;i<100;i++)snd=0; 

SND[47]=9; 

SND[46]=8; 

p8=SND+50; 

p32=(alt_u32 *)p8; 

*p32=0x11223344; 

prt1=(int)p32; 

i=prt1 & 0x3; 

 

UartPrintf("\n\n\n\nSND50 | 4=(%d:%d),%x,%x,%x,%x,%x,%x,\n",prt1,i,SND[46],SND[47],SND[48],SND[49],SND[50],SND[51]); 

return 0; 

and the printed results are as following: 

___________________________________________ 

SND48 | 4=(67146460:0),8,9,44,33,22,11, 

 

SND50 | 4=(67146462:2),8,9,44,33,22,11, 

___________________________________________ 

while it should be as following: 

___________________________________________ 

SND48 | 4=(67146460:0),8,9,44,33,22,11, 

 

SND50 | 4=(67146462:2),8,9,00,00,44,33, 

___________________________________________ 

Is there any person encountered this case? It seems that *P32 only can be used in the case of ((int)p32) % 4 =0, otherwise it will get an error result.
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
482 Views

No, there is no reason why misaligned memory cycles should do anything sensible.

0 Kudos
Altera_Forum
Honored Contributor II
482 Views

The problem is about understanding the requirements of the processor architecture. NIOS II reference handbook tells: 

 

--- Quote Start ---  

A data address is considered misaligned if the byte address is not a multiple of the width of the load or store instruction data width (four bytes for word, two bytes for half-word). Byte load and store instructions are always aligned so never take a misaligned address exception. 

--- Quote End ---  

 

 

The same is valid for most modern processors. x86 is an exception somehow.
0 Kudos
Altera_Forum
Honored Contributor II
482 Views

Supporting misaligned transfers isn't as easy as it might seem. 

At first sight it might be thought adequate to perform 2 bus cycles with appropriate byte enabled and shifted data. This in itself is a moderate amount of logic - especially if you don't want to slow down the processor. 

 

The real issues arise when you get a memory error on the second cycle (eg a mmu 'page not present', or a TLB miss). This really requires a mid-instruction fault! For atomic 'compare and swap' type instructions it is all horrid and really not worth thinking about.
0 Kudos
Altera_Forum
Honored Contributor II
482 Views

Hi, 

Thank you all of the persons replaied.. 

As you mentioned that Nios does not support mismatch.Now I try to align SND[1100] to word in my actual project:# pragma align 4 

alt_u8 SND[1100]; 

There was no warning during building and the address was 67389634 ( % 4=2) not my expected. Is there any way to solve this problem.
0 Kudos
Altera_Forum
Honored Contributor II
482 Views

I don't understand what you are trying to achieve. SND has been already word aligned in your original code. A# pragma align can be used to enforce word align of structs (I think it's the default), but it can't change the placement of individual array elements. In an array of byte, the distance between succeeding elements will be always 1.

0 Kudos
Altera_Forum
Honored Contributor II
482 Views

Since SND[] is a byte array, it might have any alignment. You can force a larger alignment (with gcc) by writing: 

unsigned char SND __attribute__((aligned(32))); 

You can similarly reduce the alignment of structure members - gcc will generate code to read/write the separate bytes of the field.
0 Kudos
Altera_Forum
Honored Contributor II
482 Views

Hi, 

My project is very complex ,it is migrated from DOS in which there are many such case.When building the project some of the arrays were aligned to word and some of them were aligned to short,so I have to force all of them align to word since Nios not support mismatch.
0 Kudos
Altera_Forum
Honored Contributor II
482 Views

You'll also find that the bytes get written in the opposite order (to i386). 

If you are trying to make protocol packets that will matter. 

You'll also need to ensure that the 32bit items within the packets are actually aligned - if not you'll need to do byte assignments. 

 

If your code had used structures (not magic constants) for the layouts you can do things like; 

#define aligned(n) __attribute__(aligned(n)))# define verify_size(type, size) typedef char verify_##type typedef unsigned it u32_align16 aligned(2); struct foo { unsigned short a; u32_align_16 b; }; /* verify size */ verify_size(foo, 6); The compiler will then do two 16bit accesses for 'b'. 

 

If you need to byteswap data, add a combinatorial custom instruction to do it.
0 Kudos
Reply