Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Avalon-MM-Slave address alignment

Hi All

I have aquestion regarding the address alignment of a an-MM slave.

My MM-Save has an avs_readdata and avs_writedata port each 512 bit wide.

Now I'm trying to write the custom pripheral driver for the NIOSII.

There I have to asign the correct address for read and write data but which comes first?

IOWR(base,0,data)
IORD(base,513)

or vice versa?

Thank you for your answer!

Ben

10 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Since the Nios can only do 32bit Avalon master cycles, you really don't want a 512bit wide slave.

    You'll only get a bus width adapter that will assert the revelant byte enables for the address.

    It is probably much better to write a 32bit slave.

    I'm not sure what your problem with IORD() and IOWR() is - they are just wrappers that generate ldio and stio instructions.

    As such their definitions aren't entirely useful.

    Most device driver writers use C structures to map device registers, it is much less error prone than using integer offsets.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi dsl

    You're right, I now changed my Avalon MM slave Custom peripheral to us it with burst transfer.

    However, I don't know how the _regs.h file needs to look.

    For example, how to I write my 32bit width data over the IOWR() makro on the right position of my 512bit wide slave avr_writedata?

    Do I need to set the bytenable or address bits? But how?

    Thank you for your help
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    IIRC the Nios won't generate burst transfers either (except maybe for cache line transfers).

    So qsys will probably have added a burst adapter!

    Personally I'd just define the correct values and ignore the Altera definitions - they just confuse things.

    qsys will show a base address for your slave of (say) 0x123000, fix this rather than letting qsys assign the addresses.

    In your header file:

    #define MY_SLAVE_BASE 0x123000
    struct {
        volatile unsigned int    reg_0;
        ....
    } my_device registers;
    extern struct my_device *my_device;

    In your source, and assuming you aren't using the MMU:

    struct my_device *my_device = (void *)(0x80000000 | MY_SLAVE_BASE);

    Then you can access my_device->reg_0 the same as any other variable.

    The fabric will convert the low address bits into byte enables for you.

    But note that the nios always does 32bit reads, char/short writes will assert the expected byte enables.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If I declare my struct like you stated above and I try to write to reg_0 with

    <CODE> my_device->reg_0 = 1;<\CODE>

    my NIOS stops working.

    However, if I check the address in debug mode of my_device it's the right one.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi dsl

    I was following the thread with great interest since I'm struggeling with something very similar. Thanks for the enlightenment!

    --- Quote Start ---

    So qsys will probably have added a burst adapter!

    --- Quote End ---

    If this is the case, how can I force it to make the burstcount as big as the number of symbols to be read, in order to

    prevent having the burst divided into a bunch of smaller ones?

    I'm trying to transfer a 512 Bit package using your mentioned cache-method.

    Thanks, Markus.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It is a long time since I've looked at the options.

    ISTR there being one to request the cache do bursts.

    But it won't generate bursts longer than a cache line.

    An alternate approach is to dual port an M9K block as tightly coupled data memory.

    That will give the nios the same access times as a data cache hit.

    You need to make sure the m9K block is set for OLD_DATA (which implies single clock mode).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    thanks for your answer!

    --- Quote Start ---

    But it won't generate bursts longer than a cache line.

    .

    --- Quote End ---

    The cache line is defined as 32, but the Nios refuses to make bursts longer than 8. I'd be perfectly fine with a 32-wide burst. This applies to both read and write bursts. :(
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Both avs_readdata and avs_writedata are 32 Bit wide, so in order to have my 512 Bit package delivered, a burst of 16 is needed (whereas a burst of 8 is only half the rent). Please correct me if I'm wrong..

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Isn't a burst of 8 transfering 32 bytes?

    --- Quote End ---

    now I see your point, sorry! Your're right of course. But I need to transfer 64Byte.