Can't do a single byte read in Nios?

K

Kenneth Land

Guest
Hello,

I'm having a problem reading a single one byte register on a Nios/Cyclone
board. I've seen this on the devkit board as well. Every time I read a
single memory location, the Nios is automatically generating reads for the
next 3 locations as well.

This causes bad things to happen when you are reading a location that is
within 3 bytes of a location that does not want to be read.

There doesn't appear to be a setting in the SOPC User Logic GUI. Is there a
..ptf file entry I can edit to stop this behavior?

The UL has 5 address bits, 8 databits, (RD#,WR#,CS#) and is an Avalon Memory
Slave.

Thanks,
Ken
 
"Kenneth Land" <kland1@neuralog1.com1> wrote in message
news:106p5chij03th48@news.supernews.com...
Hello,

I'm having a problem reading a single one byte register on a Nios/Cyclone
board. I've seen this on the devkit board as well. Every time I read a
single memory location, the Nios is automatically generating reads for the
next 3 locations as well.

This causes bad things to happen when you are reading a location that is
within 3 bytes of a location that does not want to be read.

There doesn't appear to be a setting in the SOPC User Logic GUI. Is there
a
.ptf file entry I can edit to stop this behavior?

The UL has 5 address bits, 8 databits, (RD#,WR#,CS#) and is an Avalon
Memory
Slave.
That's the way the Nios works - it *always* reads 32-bit word, and then
throws away the data it doesn't want. Theoretically, a bus master can use
the byte enable signals to tell a slave device which bytes it is interested
in, but in practice that doesn't happen.

I would suggest that you either use the full 32-bit databus (just ignore
unused bits, and they will be pretty much optomised out), or make sure that
you don't have side effects on reads (it's not normally a good idea to have
such side effects anyway, although it's traditional for things like uart
receive registers), or space your critical registers within the address
space so that each such critical register takes 4 bytes of address space.
 
"David Brown" <david@no.westcontrol.spam.com> wrote in message
news:c4j5s7$rql$1@news.netpower.no...
"Kenneth Land" <kland1@neuralog1.com1> wrote in message
news:106p5chij03th48@news.supernews.com...
Hello,

I'm having a problem reading a single one byte register on a
Nios/Cyclone
board. I've seen this on the devkit board as well. Every time I read a
single memory location, the Nios is automatically generating reads for
the
next 3 locations as well.

This causes bad things to happen when you are reading a location that is
within 3 bytes of a location that does not want to be read.

There doesn't appear to be a setting in the SOPC User Logic GUI. Is
there
a
.ptf file entry I can edit to stop this behavior?

The UL has 5 address bits, 8 databits, (RD#,WR#,CS#) and is an Avalon
Memory
Slave.


That's the way the Nios works - it *always* reads 32-bit word, and then
throws away the data it doesn't want. Theoretically, a bus master can use
the byte enable signals to tell a slave device which bytes it is
interested
in, but in practice that doesn't happen.

I would suggest that you either use the full 32-bit databus (just ignore
unused bits, and they will be pretty much optomised out), or make sure
that
you don't have side effects on reads (it's not normally a good idea to
have
such side effects anyway, although it's traditional for things like uart
receive registers), or space your critical registers within the address
space so that each such critical register takes 4 bytes of address space.



Hi David,

Yeah, it would be fine except my register device has a register that is a
fifo. So if I read any register in the same quad alignment it inadvertantly
pops a value out of the fifo.

Here's something I don't know about it yet. Where does the other data bytes
read go? Does it put all four read results into different bytes of a
register?
For example:

byte_val = *byte_register_ptr;

It actually reads not only the byte I'm interested in but all four bytes
around the location pointed to by the ptr. What does the Nios do with the
other three bytes that it read? Bit bucket?

Thanks,
Ken
 
"Kenneth Land" <kland1@neuralog1.com1> wrote in message
news:106qpaadr24qoa4@news.supernews.com...
"David Brown" <david@no.westcontrol.spam.com> wrote in message
news:c4j5s7$rql$1@news.netpower.no...

"Kenneth Land" <kland1@neuralog1.com1> wrote in message
news:106p5chij03th48@news.supernews.com...
Hello,

I'm having a problem reading a single one byte register on a
Nios/Cyclone
board. I've seen this on the devkit board as well. Every time I read
a
single memory location, the Nios is automatically generating reads for
the
next 3 locations as well.

This causes bad things to happen when you are reading a location that
is
within 3 bytes of a location that does not want to be read.

There doesn't appear to be a setting in the SOPC User Logic GUI. Is
there
a
.ptf file entry I can edit to stop this behavior?

The UL has 5 address bits, 8 databits, (RD#,WR#,CS#) and is an Avalon
Memory
Slave.


That's the way the Nios works - it *always* reads 32-bit word, and then
throws away the data it doesn't want. Theoretically, a bus master can
use
the byte enable signals to tell a slave device which bytes it is
interested
in, but in practice that doesn't happen.

I would suggest that you either use the full 32-bit databus (just ignore
unused bits, and they will be pretty much optomised out), or make sure
that
you don't have side effects on reads (it's not normally a good idea to
have
such side effects anyway, although it's traditional for things like uart
receive registers), or space your critical registers within the address
space so that each such critical register takes 4 bytes of address
space.



Hi David,

Yeah, it would be fine except my register device has a register that is a
fifo. So if I read any register in the same quad alignment it
inadvertantly
pops a value out of the fifo.

Here's something I don't know about it yet. Where does the other data
bytes
read go? Does it put all four read results into different bytes of a
register?
For example:

byte_val = *byte_register_ptr;

It actually reads not only the byte I'm interested in but all four bytes
around the location pointed to by the ptr. What does the Nios do with the
other three bytes that it read? Bit bucket?

Thanks,
Ken
You should have a look at the Nios programmers' reference manual (page 22 on
my copy, but it might vary according to revision), which explains how the
nios reads from memory and peripherals. It always reads an aligned 32-bit
word, and then uses the EXT8D or EXT16D instruction to get the exact byte or
half-word it wants (overwriting the data read with the extracted byte or
half-word).

Assuming you have control over the peripheral in question, it should not be
too difficult to re-arrange the memory map to take this into account.

mvh.,

David
 
"Kenneth Land" <kland1@neuralog1.com1> wrote in message news:<106p5chij03th48@news.supernews.com>...
Hello,

I'm having a problem reading a single one byte register on a Nios/Cyclone
board. I've seen this on the devkit board as well. Every time I read a
single memory location, the Nios is automatically generating reads for the
next 3 locations as well.

This causes bad things to happen when you are reading a location that is
within 3 bytes of a location that does not want to be read.

There doesn't appear to be a setting in the SOPC User Logic GUI. Is there a
.ptf file entry I can edit to stop this behavior?

The UL has 5 address bits, 8 databits, (RD#,WR#,CS#) and is an Avalon Memory
Slave.

Thanks,
Ken
Ken,

Others have explained what is going on, but there are some subtle
changes that can be made to your system to get the behavior you want.
When you add your peripheral, I am presuming you are using the
'interface to user logic' wizard. If so, be sure you're selecting
"Avalon Register Slave" (as opposed to memory slave).

In the case of a 32-bit master, this has the effect right-shifting the
address bus going to the slave by two bits (this does not occur if you
are going through a tri-state bus bridge.. you can do so on your own
by connecting address line A2 from Nios to A0 on your peripheral
manually). The Avalon reference manual describes this in more detail.

The reasoning behind this feature is to cover this very case -- where
register access to a peripheral of a 'strange' width may upset other
registers that happen to be inadvertently accessed. It also allows a
peripheral to have a register that is 1 bit wide, followed by one that
is 5 bits, or 30 bits, etc. With this, a master can then read *or
write* a peripheral register of any bit width (up to the master's
width) by presenting a word-aligned address (0, 4, 8...). On the slave
side, the corresponding registers are decoded as 0..1..2... (again,
the above example is based on a 32-bit wide master).

One last note: Turning this feature on turns *off* the dynamic bus
sizing feature of Avalon.

Hope this is of some help to your design.

Regards,

Jesse Kempa
Altera Corp.
jkempa at altera dot com
 
"Jesse Kempa" <kempaj@yahoo.com> wrote in message
news:95776079.0404021757.302101b5@posting.google.com...
"Kenneth Land" <kland1@neuralog1.com1> wrote in message
news:<106p5chij03th48@news.supernews.com>...
Hello,

I'm having a problem reading a single one byte register on a
Nios/Cyclone
board. I've seen this on the devkit board as well. Every time I read a
single memory location, the Nios is automatically generating reads for
the
next 3 locations as well.

This causes bad things to happen when you are reading a location that is
within 3 bytes of a location that does not want to be read.

There doesn't appear to be a setting in the SOPC User Logic GUI. Is
there a
.ptf file entry I can edit to stop this behavior?

The UL has 5 address bits, 8 databits, (RD#,WR#,CS#) and is an Avalon
Memory
Slave.

Thanks,
Ken

Ken,

Others have explained what is going on, but there are some subtle
changes that can be made to your system to get the behavior you want.
When you add your peripheral, I am presuming you are using the
'interface to user logic' wizard. If so, be sure you're selecting
"Avalon Register Slave" (as opposed to memory slave).

In the case of a 32-bit master, this has the effect right-shifting the
address bus going to the slave by two bits (this does not occur if you
are going through a tri-state bus bridge.. you can do so on your own
by connecting address line A2 from Nios to A0 on your peripheral
manually). The Avalon reference manual describes this in more detail.

The reasoning behind this feature is to cover this very case -- where
register access to a peripheral of a 'strange' width may upset other
registers that happen to be inadvertently accessed. It also allows a
peripheral to have a register that is 1 bit wide, followed by one that
is 5 bits, or 30 bits, etc. With this, a master can then read *or
write* a peripheral register of any bit width (up to the master's
width) by presenting a word-aligned address (0, 4, 8...). On the slave
side, the corresponding registers are decoded as 0..1..2... (again,
the above example is based on a 32-bit wide master).

One last note: Turning this feature on turns *off* the dynamic bus
sizing feature of Avalon.

Hope this is of some help to your design.

Regards,

Jesse Kempa
Altera Corp.
jkempa at altera dot com
Hi Jesse,

I thought I read somewhere that a Register Slave wouldn't work with the dma.
(maybe not?)

Anyway, thanks to you and David for your insight. With this understanding I
am happily dma'ing at full speed with no lost bytes.

Will the NiosII allow unaligned reads? (if its not a secret :) )

Ken
 

Welcome to EDABoard.com

Sponsor

Back
Top