Forum Discussion

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

Questions regarding interfacing of & accessing custom hardware blocks

Hello,

Firstly, before you read the rest - i'm pretty "green" with FPGAs, but i do know how to set up a Nios II soft-core processor system with IP blocks using the SOPC builder, and instantiating it in Quartus II using the top-level hdl files (vhdl). And it works fine with the C code i have written to execute on it.

Now I want to implement a certain, often executed, part of the C code as a hardware block ("IP block" i guess), to work as a pheripheral with the Nios II.

From what i have gathered i obviously need the VHDL code for the hardware block that i want to create, but i'm in doubt regarding three things (mainly):

- Does this VHDL code need to take anything special into account regarding the Avalon switch fabric? i.e. new port/signal names, etc.?

I have read http://www.altera.com/literature/hb/qts/qts_qii5v4_01.pdf but i'm not sure if this means i shouldn't think of the Avalon Switch fabric in any way in my HDL.

- How do I communicate between my C code executing on the Nios II and the hardware accelerator? By using addresses? Could someone show me an example on how this should be done?

Does a tutorial on this exist, covering just a really simple example, like a multiplier as a hardware accelerator, and how this is "interfaced" both regarding calls from a C code and in SOPC builder?

Basically what i want to do is what C2H can do for me, but i'd like to learn by doing it manually. I don't care if i can't do it as well as C2H.

Thanks for any help.

12 Replies

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

    I have the same problem no matter what i do.

    Did you succeed on reading and writing to your component?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hi again,

    Ok, this really ought to be easy... i guess this is just a case of RTFM, and do it properly.. and then it would occured to me that there is no "magic" tricks regarding the Avalon - there's a address bus - just what i was looking for. Forget my previous post.

    Now the VHDL code looks like this process regarding the Avalon interface:

    process (clk)
    begin
     if clk'event and clk = '1' then
      if reset_n = '0' then
       readdata <= (others => '0');
       else
       if chipselect = '1' then -- our HW is selected
        if read = '1' then   -- if the HW wants to write to Nios (avalon should read from HW)
          if address ="011100" then -- 0x1C (28)
           readdata <= branch_cost; -- output this new branch cost.
          else
           readdata <= "11111111111111111111111111111111"; -- return when nothing has happened.
          end if;
        end if;  
        elsif write = '1' then -- if write is asserted (avalon should write to the HW)
         case address is  
          when "000000" => -- 0x00
          sys_rec <= writedata;
          when "000100" => -- 0x04 (4)
          sys_ref <= writedata;
          when "001000" => -- 0x08 (8)
          par1rec <= writedata;
          when "001100" => -- 0x0C (12)
          par1ref <= writedata;
          when "010000" => -- 0x10 (16)
          par2rec <= writedata;
          when "010100" => -- 0x14 (20)
          par2ref <= writedata;
          when "011000" => --0x18 (24)
          x <= writedata;
          when others =>
          null;
         end case;    
       end if;
      end if;
     end if;
    end process;
    

    Regardless of what i'm doing, and even adding a case statement for readdata to read some of the values that are written to the variable/signals...

    But this does not work - no matter what i do (regardless of using IORD/IOWR and IORD_32DIRECT/IOWR_32DIRECT

    The code i use is:

    # include "system.h"# include <io.h>
    .
    .
    .# define WR_test(offset,data) IOWR_32DIRECT(BCC_TEST_BASE,offset,data)# define RD_test(offset) IORD_32DIRECT(BCC_TEST_BASE,offset)# define sysref 4
     
    int main(void) {
     
    WR_test(sysref,1);
    WR_test(par1ref,3);
    printf("sysrech=%x", RD_test(sysref));
    printf("sysrecd=%d", RD_test(sysref));
    return 0;
    }
    

    I have tried defining sysref as 4 and 0x04, but by the same results

    No matter what i have done, it always prints that:

    sysrech=0 and sysrecd=0

    My entity of the VHDL is just:

    entity bcc_test
     port (
      signal clk, 
        reset_n,
        read,
        write,
        chipselect : in std_logic;
      signal readdata : out std_logic_vector(31 downto 0);
      signal writedata : in std_logic_vector(31 downto 0);
      signal address : in std_logic_vector(5 downto 0)
     );
    end bcc_test;
    

    Any hints? From importing the component in SOPC builder, there were absolutely no errors, and the write and read waveforms also looked as expected.

    Thanks for any hints regarding why it always throws a zero back... :)

    --- Quote End ---

    did find the answer?