FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP

Avalon MM Interface

Altera_Forum
Honored Contributor II
2,259 Views

Hi, 

 

I'm using a Nios2 processor as an avalon memory mapped master. The Nios2 is connected to a avalon mm slave, which is the controller for a sram. Now I can read and write from Nios2 to the sram. 

 

Additionally I have another hardware which has to read (readonly) from the same sram. Which interface do I have to use? 

 

I can exclude reading/writing at the same time from Nios2 and the other hardware. 

 

Best Regards 

 

Mark
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
924 Views

is the additional hardware your own ip ? 

normaly you just add a connection between your additional hardwares master port to the slave port of your sram, thats it. 

the avalon switch fabric would take care about the arbitration which master (nios or the additional master) gains access to the slave and holds the master until the other master releases the slave. so your additional master must obey the wait condition. normaly the avalon switch fabric can hold 1 write transaction and releases the master (thats what i had monitored via signal tap)
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

The additional hardware is my own IP (not realised yet).  

I think I need to create an avalon mm master. At the top level of SOPC I need a (unidirectional) adressbus (to the IP), a data bus (to the top-level). 

and a clock (data valid with rising edge). 

 

The goal is to give the data of the sram at the adressbus adress to the databus. 

 

How can I reach this? Sorry, I don't have any experience with the component editor. 

 

Thank you. 

 

Mark
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

I edited a new component with a Avalon MM Master interface (adress[31..0],waitrequest, data[31..0], read_from_bus, arbiterlock, byteenable signals).  

 

I set all byteenable-bits to 1111 in order to read a 32 bit word, then set the adress of the sram and the read_from_bus signal. After the next clock cycle the waitrequest signal went high but never returns low, which should indicate, that readdata is valid. 

 

What went wrong? 

 

Here some code: 

 

-- CorrDataReader.vhd -- This file was auto-generated as a prototype implementation of a module -- created in component editor. It ties off all outputs to ground and -- ignores all inputs. It needs to be edited to make it do something -- useful. -- -- This file will not be automatically regenerated. You should check it in -- to your version control system if you want to keep it. library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity CorrDataReader is port ( address : out std_logic_vector(31 downto 0); -- avalon_master.address waitrequest : in std_logic := '0'; -- .waitrequest data_mm : in std_logic_vector(31 downto 0) := (others => '0'); -- .readdata read_from_bus : out std_logic; -- .read byteenable : out std_logic_vector(3 downto 0); -- .byteenable arbiterlock : out std_logic; -- .arbiterlock clk : in std_logic := '0'; -- clock.clk data_out : out std_logic_vector(31 downto 0); -- conduit_end.export datavalid : out std_logic; -- .export onlyglass_clock : in std_logic := '0'; -- .export onlyglass_vsync : in std_logic := '0'; -- .export arbiterlock_in : in std_logic := '0' -- .export ); end entity CorrDataReader; architecture rtl of CorrDataReader is type State_t is (READMEM, IDLE); signal state : State_t := IDLE; begin byteenable <= "1111"; datavalid <= '0'; arbiterlock <= arbiterlock_in; process(clk, onlyglass_vsync) begin if onlyglass_vsync = '1' then state <= IDLE; read_from_bus <= '0'; elsif rising_edge(clk) then if onlyglass_clock = '1' then -- triggers read address <= x"0c000000"; -- sram adress read_from_bus <= '1'; state <= READMEM; end if; if state = READMEM and waitrequest = '0' then --data available on readdata_in data_out<=data_mm; read_from_bus <= '0'; state <= IDLE; end if; end if; end process; -- TODO: Auto-generated HDL template -- ADDRESSUPDATE: PROCESS(onlyglass_clock) ---BEGIN --IF onlyglass_vsync = '1' THEN -- RESET: signale initialisieren --nextaddress <= x"0c000000"; -- Startadresse SRAM -- ELSIF onlyglass_clock'event AND onlyglass_clock='0' THEN -- nextaddress<=nextaddress+0; -- immer 32 Bit = 4 Byte auslesen -- END IF; -- j -- address <= std_logic_vector(nextaddress); -- muss unsigned sein --END PROCESS; end architecture rtl; -- of CorrDataReader
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

Is your address indeed in the SRAM space? You must be careful about one thing: as you read 32-bit values, you must divide by 4 the address that you can see in SOPC builder.

0 Kudos
Altera_Forum
Honored Contributor II
924 Views

That's correct. 

32-Bit access must be at 32bit address boundaries 0x0 0x4 0x8 0xc ...
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

The address that I can see in SOPC builder is 0x0c000000. 

 

Access with Nios runs: 

 

/* Fill memory with a known pattern. */ for (int offset = 0; offset < 4096; offset+=4) { IOWR_32DIRECT(memory_base, offset, offset+1); } for (int offset = 0; offset < 4096; offset+=4) { pattern=IORD_32DIRECT(memory_base, offset); }  

 

Which address do I have to set in the VHDL-code above? 0x0c0000000 / 4 = 0x03000000 ????
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

 

--- Quote Start ---  

entity CorrDataReader is 

port ( 

address : out std_logic_vector(31 downto 0); -- avalon_master.address 

 

--- Quote End ---  

 

 

so your address is a 32 bit signal and it must be the full address 0x0c000000. 

address alignment here means the next address you can access is 0x0c000004 

even if your master will only access 32 bit and the two lower adr bits will always be 0. 

accessing the 4 bytes within the 32 bit is und byteenable control
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

This is what I do in the vhdl-code above. Reading from 0x0c000000 (SRAM Range: 0x0c000000-0x0c7fffff = 8MB) doesn't run. The waitrequest signal stays high.

0 Kudos
Altera_Forum
Honored Contributor II
924 Views

sorry i am not a VHDL guy, only verilog HDL. 

 

but did you look at the master templates ? 

normaly you setup the addressline, the byteenables, and then assert ther read signal and wait until waitrequest is release (=0). 

did you monitor via signaltap the slave you want to read from ?
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

I add the SRAM-controller (the slave) to signal-Tap too. Let's see, what happens. I'll report here.

0 Kudos
Altera_Forum
Honored Contributor II
924 Views

I got confused between masters and slave... Indeed in your case you must use addresses 0x0c000000 / 0x0c000004 etc... 

If you put some Signaltap probes on the SRAM interface, do you see any access attempt?
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

thats why i use the signal name suggestion from one of those altera documents. 

avm_userif1_read (thats an output) 

avs_userif2_read (thats an input) 

where avs is avalon valid slave 

and avm is avalon valid master 

the most positive effect is, that the sopc component editor automaticaly does the correct connection between your ip interface signal and the corresponding avalon signal. well 99% it works.
0 Kudos
Altera_Forum
Honored Contributor II
924 Views

OK. Now it's working. It was a problem with the reset of the ip (it was reseted after toggling the reading). 

 

Thank you all for your help. 

 

Mark
0 Kudos
Reply