- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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'EVENT AND clk='1' 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?
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Take a look at the Lancelot VGA reference design at www.fpga.nl. Download the design and you have a starting point.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 => '0');
-- Some registers to hold internal values
SIGNAL Input1 : STD_LOGIC;
SIGNAL Input2 : STD_LOGIC;
BEGIN
PROCESS(clk,nreset)
BEGIN
IF (nreset = '0') THEN
Input1 <= '0';
Input2 <= '0';
ELSIF (rising_edge(clk)) THEN
IF (Nios_Cs = '1' AND Nios_Wr = '1') 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 = '1' AND Nios_Rd = '1' AND Nios_Addr = INPUT_1_ADDR ELSE
ZEROS(31 DOWNTO 1) & Input2 WHEN Nios_Cs = '1' AND Nios_Rd = '1' AND Nios_Addr = INPUT_2_ADDR ELSE
(OTHERS => '0');
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'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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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's a not-avalon signal, right? Why are the expressions like input1 <= input1 needed? For me they don'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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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'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't make any sense.[/b] --- Quote End --- Let'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'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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
<div class='quotetop'>QUOTE </div>
--- Quote Start --- Let'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'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?
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page