Forum Discussion

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

Implementing registers in memory

Hi,i need to implement 3 registers on memory.A 16bit and an 8 bit register.And i need access only 8th and 9th bit of 16bit register and 4,5,6,7bit of 8 bit register.How can i do this.should i use IORD, IOWR or IORD/IOWR_XXDIRECT or use arrays like in normal c programming to do this.Can anyone help me in this please?

5 Replies

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

    Is this a PIO, an external device register or standard memory?

    A general way of operation could be this:

    int temp = IORD(REGISTER_BASE_ADDRESS, register_offset);

    /* change required bits in temp variable */

    IOWR(REGISTER_BASE_ADDRESS, register_offset, temp);

    If your register is a PIO, you could take advantage of the individual bit setting/clearing feature, and avoid the RD/WR sequence.

    If you want to use normal C pointers or arrays make sure to use uncached addresses if the register is volatile, i.e. supposed to change independently from your code flow.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for your help.

    Im using the onchip memory itself.The onchip memory start address is0x00000000 and end address is0x00004e1f.

    So if i need to assign some memory for a 16 bit register,what value should i give for offset?

    Does the offset means that from the base address ,with increments of 4bits, till the offset address the memory will be allocated for a register?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If I remember correctly IORD/IOWR use the native bus width, so the offset is usually increment one for each 32bit word. You can choose 8/16/32 accesses using IORD_8DIRECT and similar. Take a look at page 9-4 of Nios II SW Developer Hadbook.

    Anyway, for onchip memory it could be convenient to use simple C pointers instead of IORD/IOWR macros.

    volatile alt_u16 * preg;

    preg = (alt_u16*) MEMORY_ADDRESS;

    preg |= 0x80000000; // map as uncached

    Then you can use *preg as a normal variable to access the register
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Also remember that your Avalon slave device needs to be defined as a 32bit one (even if it discards most of the written bits, and returns 0 for reads).

    Otherwise the SOPC builder will add a 'bus width adapter' in order to convert the 32bit cycles generated by the Nios into four 8bit ones. The writes will have the appropriate byte enables set, the reads always set all the byte enables.