Forum Discussion

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

NIOS II HW/SW Interface

Hi all,

I'm new on working with Nios. I want to build a spezial Hardware (with the dsp Builder) on the FPGA and connect this Hardware to the NIOS Software. I want to do this with a Avalon Slave on the Hardware side.

So i'm looking on a simple Exampe wich contains a simple Hardware with a Avalon Slave and a Nios prozessor with a simple software code wich writes and reads from the avalon slave.

I would be very happy if anybody can send mi a small example like this, or just explaim me qhat i have to do.

Thanks alot

lg florian

7 Replies

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

    Hello

    Thanks, but i know this paper (Nios II Hardware Development Tutorial ) allready. This paper shows fine how to build a SOC with standard components.

    But my problem is, that i have a own component topach_AvalonSlave wich a

    AvalonReadSlave Base Adr:0xyyyyyyyy and AvalonWriteSlvae Base Adr: 0xzzzzzzzz

    And my question is how can i write an value like int i=2 on the AvalonWriteSlave and how can i read the value from the AvalonReadSlave?

    Can i use the macros like

    IOWR_ALTERA_AVALON_PIO_DATA(????;i);

    Thanks for your help

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

    --- Quote Start ---

    originally posted by fplank@Jun 5 2006, 02:55 AM

    hello

    thanks, but i know this paper (nios ii hardware development tutorial ) allready. this paper shows fine how to build a soc with standard components.

    but my problem is, that i have a own component topach_avalonslave wich a

    avalonreadslave base adr:0xyyyyyyyy and avalonwriteslvae base adr: 0xzzzzzzzz

    and my question is how can i write an value like int i=2 on the avalonwriteslave and how can i read the value from the avalonreadslave?

    can i use the macros like

    iowr_altera_avalon_pio_data(????;i);

    thanks for your help

    lg florian

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=15908)

    --- quote end ---

    --- Quote End ---

    Hi lg florian,

    It sounds like what you want to do are memory mapped IOs. You can declare a pointer to the address locations directly (or use the system.h declarations of the component&#39;s base address with an offset).

    Then you only have to write a value to a pointer location or read back a value from a pointer location in your program.

    It may look something like this (this is a very simple way of doing this, I&#39;m sure there are much better ways):

    // defines LED_BASE to have address value # define LED_BASE 0xyyyyyyyy

    volatile unsigned int *led_port = ((volatile unsigned int *) (LED_BASE));

    // declares pointer to LED_BASE address location

    .

    .

    void main()

    .

    .

    *led_port = 0x5555aaaa; // writes value to LEd_BASE address

    .

    .

    I hope this helps.

    Regards,

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

    Hallo

    I&#39;m able to write on my Avalon Slave Interface already.

    Ich write with

    IOWR(0x0000808,0,i)

    i on my Avalon Slave Interface.This works correct.

    My Avalon Slave has a secon Adr. How can i write on the second Adr.

    Thanks for your help

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

    --- Quote Start ---

    originally posted by atjung+jun 8 2006, 05:32 am--><div class='quotetop'>quote (atjung @ jun 8 2006, 05:32 am)</div>

    --- quote start ---

    <!--quotebegin-fplank@Jun 5 2006, 02:55 AM

    hello

    thanks, but i know this paper (nios ii hardware development tutorial ) allready. this paper shows fine how to build a soc with standard components.

    but my problem is, that i have a own component topach_avalonslave wich a

    avalonreadslave base adr:0xyyyyyyyy and avalonwriteslvae base adr: 0xzzzzzzzz

    and my question is how can i write an value like int i=2 on the avalonwriteslave and how can i read the value from the avalonreadslave?

    can i use the macros like

    iowr_altera_avalon_pio_data(????;i);

    thanks for your help

    lg florian

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=15908)

    --- quote end ---

    --- Quote End ---

    Hi lg florian,

    It sounds like what you want to do are memory mapped IOs. You can declare a pointer to the address locations directly (or use the system.h declarations of the component&#39;s base address with an offset).

    Then you only have to write a value to a pointer location or read back a value from a pointer location in your program.

    It may look something like this (this is a very simple way of doing this, I&#39;m sure there are much better ways):

    // defines LED_BASE to have address value # define LED_BASE 0xyyyyyyyy

    volatile unsigned int *led_port = ((volatile unsigned int *) (LED_BASE));

    // declares pointer to LED_BASE address location

    .

    .

    void main()

    .

    .

    *led_port = 0x5555aaaa; // writes value to LEd_BASE address

    .

    .

    I hope this helps.

    Regards,

    -ATJ

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=16016)</div>

    [/b]

    --- Quote End ---

    !!! DON&#39;T DO THAT - IT WILL NOT WORK IF YOU HAVE EANBLED THE DATA CACHE OF YOUR CPU. !!!

    Allways use the macros from the IOWR() and IORD() family to access anything besides real memory.

    look at %nios_install_dir%/components/altera_nios2/HAL/inc/io.h how to use them...

    regards

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

    I may be able to clarify a few things here. First I will indicate that the previous post from fplank is correct. Using a pointer to reference your IO peripheral will not bypass the data cache (if you have one) on the NIOS processor. Unless .... you set the highest bit in the address (pointer). The reason for this is that NIOS uses the highest bit to indicate whether to access data from the cache or not. That is why NIOS only has 2GB of address space instead of 4GB. Setting the highest bit to 1 will bypass the data cache.

    However, the preferred method for accessing IO components is to use the IOWR and IORD macros provided by altera. These macros call the NIOS assembly instructions stwio and ldwio.

    Now, back to the question of accessing YOUR custom user logic. It appears that you have created a component with two avalon slave ports. Make sure that both of these ports are setup correctly in the Component Wizard. When you add your component to the SOPC system, make sure they are both connected to the avalon bus and that there are no conflicts, errors, or warnings.

    Now the current method you are using to write to your component is probably not what you want to do. When you build your system library project in the NIOS IDE it will generate a file system.h. This file contains a ton of macros that are available for you to use in your code. Among these will be the base addresses of the slave ports of your component. They will appear as something like:

    <NAME_OF_YOUR_COMPONENT>_<NAME_OF_PORT>_BASE

    You should use the macros in your code when accessing any component rather than hard-coded values. That way if anything in your SOPC system changes, you don&#39;t have to change your C-code.

    so you would write to your component using C calls like:

    IOWR(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, <OFFSET>, <DATA>);

    IORD(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, <OFFSET>);

    Hope this helps. If you have further questions, feel free to post.

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

    Hallo

    Thanks for your answers. But i have some more questions.

    I use this

    IOWR(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, <OFFSET>, <DATA>);

    IORD(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, <OFFSET>);

    makros.

    But i have some questions about the OFFSET. How can i know which offset i have to use.

    I have 4 address Read Slave and 4addr Write Slave Bus

    IOWR(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, 0, a);

    IOWR(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, 1, http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/cool.gif ;

    IOWR(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, 2, c);

    IOWR(<BASE_ADDRESS_GIVEN_IN_SYSTEM.H>, 3, d);

    Is it correct that i write a,b,c and d to the 4 adresse ligns? Can i read things like datatreadyforread....