FPGARelated.com
Forums

Can't do a single byte read in Nios?

Started by Kenneth Land April 1, 2004
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