Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12621 Discussions

How to use the avalon bus correctly?

Altera_Forum
Honored Contributor II
1,838 Views

I am using Quartus 4.1 with SOPC-builder and the Cyclone Development Board von Altera. My nios-system contains the nios2 processor, some memory and some other peripherals. 

 

I created my own user logic which I want to connect to the avalon bus and access from software. I read the complete avalon bus specification but I was not able to find any real example there. Can somebody give me a simple example how to connect some user logic to the avalon bus correctly? And how to access it in software then? 

 

As a simple example we can take the following vhdl-code: 

library IEEE; use IEEE.std_logic_1164.all; ENTITY example IS PORT (     SIGNAL clk: IN STD_LOGIC;     SIGNAL input1: IN STD_LOGIC;        SIGNAL input2: IN STD_LOGIC;     SIGNAL output: OUT STD_LOGIC ); END example; ARCHITECTURE behavior OF example IS BEGIN  PROCESS(clk)  BEGIN    IF clk&#39;EVENT AND clk=&#39;1&#39; THEN      output <= input1 AND input2;    END IF;  END PROCESS; END behavior; 

 

How do I have change this vhdl-code in order to connect this user logic to the the avalon bus? Because I want to write to and read from the hardware module at least the signals chipselect, write (or write_n), writedata, read (or read_n), readdata and address must be there. Am I wright?
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
550 Views

Take a look at the Lancelot VGA reference design at www.fpga.nl. Download the design and you have a starting point.

0 Kudos
Altera_Forum
Honored Contributor II
550 Views

Thank you for your answer, but the Lancelot VGA reference design is rather complicated for me. 

 

Where can I find a simple example of avalon bus usage like for the vhdl-code from above?
0 Kudos
Altera_Forum
Honored Contributor II
550 Views

Hi Owerty 

 

Look at this code: 

 

library IEEE; use IEEE.std_logic_1164.all; ENTITY example IS PORT (     clk      : IN STD_LOGIC;     nreset      : IN STD_LOGIC;     -- Nios interface     Nios_Cs  : IN STD_LOGIC;     Nios_Rd  : IN STD_LOGIC;     Nios_Wr  : IN STD_LOGIC;     Nios_Addr    : IN STD_LOGIC_VECTOR(2 DOWNTO 0);    -- just an example     Nios_Din    : IN STD_LOGIC_VECTOR(31 DOWNTO 0);     Nios_Dout   : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);    -- The output from your entity     output: OUT STD_LOGIC ); END example; ARCHITECTURE behavior OF example IS -- Define some constnts to help woth addressing when the design gets bigger CONSTANT INPUT_1_ADDR    :    STD_LOGIC_VECTOR(2 DOWNTO 0) := "000"; CONSTANT INPUT_2_ADDR    :    STD_LOGIC_VECTOR(2 DOWNTO 0) := "001"; -- I also find this constant helpful CONSTANT ZEROS      :    STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => &#39;0&#39;); -- Some registers to hold internal values SIGNAL  Input1      :    STD_LOGIC; SIGNAL  Input2      :    STD_LOGIC; BEGIN PROCESS(clk,nreset) BEGIN     IF (nreset = &#39;0&#39;) THEN  Input1 <= &#39;0&#39;;  Input2 <= &#39;0&#39;;     ELSIF (rising_edge(clk)) THEN  IF (Nios_Cs = &#39;1&#39; AND Nios_Wr = &#39;1&#39;) THEN      CASE Nios_Addr IS    WHEN "000" =>        Input1 <= Nios_Din(0);        Input2 <= Input2;    WHEN "001" =>        Input1 <= Input1;        Input2 <= Nios_Din(1);    WHEN OTHERS =>        Input1 <= Input1;        Input2 <= Input2;      END CASE;  ELSE      Input1 <= Input1;      Input2 <= Input2;  END IF;     END IF; END PROCESS; Nios_Dout <= ZEROS(31 DOWNTO 1) & Input1 WHEN Nios_Cs = &#39;1&#39; AND Nios_Rd = &#39;1&#39; AND Nios_Addr = INPUT_1_ADDR ELSE    ZEROS(31 DOWNTO 1) & Input2 WHEN Nios_Cs = &#39;1&#39; AND Nios_Rd = &#39;1&#39; AND Nios_Addr = INPUT_2_ADDR ELSE    (OTHERS => &#39;0&#39;);     output <= Input1 AND Input2     END behavior;  

 

This code generates a peripheral with two registers. You need to add it to your SOPC builder system and assign it with an address. You&#39;ll be able to access it from sw the same way you access any other address (with IOWR and IORD commands). 

 

Hope this helps. 

 

Nir
0 Kudos
Altera_Forum
Honored Contributor II
550 Views

Hi nir, thank you for your example. I added it to my system but I still have some questions about it. 

 

I mapped the "output" signal to type export because it&#39;s a not-avalon signal, right? 

 

Why are the expressions like input1 <= input1 needed? For me they don&#39;t make any sense. 

 

For accessing the peripheral I wrote the following code (EXAMPLE_INTERFACE_BASE is the address of our example peripheral): 

int t; IOWR(EXAMPLE_INTERFACE_BASE, 0 , 255); t = IORD(EXAMPLE_INTERFACE_BASE, 0); printf ("t = %d\n", t); 

I would expect t to be 1 but the result is always 0. Why? What am I doing wrong? 

 

And the last question: in this example we in principle can access eigth 32-bit input ports and eigth 32-bit output ports (because address is a 3-bit value), right? What if I want to have lets say two 3-bit input ports, one 1-bit input port, one 32-bit input port and one 1-bit output port? How do I have do declare them in the vhdl-code and access them from them SW?
0 Kudos
Altera_Forum
Honored Contributor II
550 Views

Hello Qwerty 

 

Here are the answers to your questions: 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

I mapped the "output" signal to type export because it&#39;s a not-avalon signal, right?[/b] 

--- Quote End ---  

 

This is right. 

 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

Why are the expressions like input1 <= input1 needed? For me they don&#39;t make any sense.[/b] 

--- Quote End ---  

 

Let&#39;s say we removed the two lines syaing Input1 <= Input1. The compiler seeing that will not know what to do when the address seen is not "000". What it will do is generate a latch to keep the data in Input1 the same as it was. This is done without you knowing about it and is not desirable (latches in FPGAs are bad things). So, these lines actually make sure that the compiler knows what to do with each of the registers in each of the cases it may encounter. This prevents these transparent latches from being instantiated. 

 

Regarding the problem you are seeing in software: It&#39;s possible that you defined the polarity of the Nios control signals (or one of them) wrong when you added the peripheral to the SOPC builder ? 

 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

And the last question: in this example we in principle can access eigth 32-bit input ports and eigth 32-bit output ports (because address is a 3-bit value), right? What if I want to have lets say two 3-bit input ports, one 1-bit input port, one 32-bit input port and one 1-bit output port? How do I have do declare them in the vhdl-code and access them from them SW?[/b] 

--- Quote End ---  

 

I defined the peripheral to use a 3 bit address bus, meaning the address space is 8 addresses. Each address can have its own data width (from 1 to 32 bits). If ou add one more bit to the address space you can have 16 different addresses. These addresses are registers addresses. Each register can be either Read only, write only or read-write. I hope this ansewrs your question. 

 

Nir
0 Kudos
Altera_Forum
Honored Contributor II
550 Views

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

Let&#39;s say we removed the two lines syaing Input1 <= Input1. The compiler seeing that will not know what to do when the address seen is not "000". What it will do is generate a latch to keep the data in Input1 the same as it was. This is done without you knowing about it and is not desirable (latches in FPGAs are bad things). So, these lines actually make sure that the compiler knows what to do with each of the registers in each of the cases it may encounter. This prevents these transparent latches from being instantiated.[/b] 

--- Quote End ---  

 

Ok now I see. 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

Regarding the problem you are seeing in software: It&#39;s possible that you defined the polarity of the Nios control signals (or one of them) wrong when you added the peripheral to the SOPC builder ?[/b] 

--- Quote End ---  

 

This is possible, I will check the settings tommorow. 

 

Another question: is it possible that my peripheral needs some time to provide the result, so I have to wait a liitle bit before reading from it? How can I determine that my peripheral is ready for reading from it?
0 Kudos
Reply