Forum Discussion

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

Dual Port RAM acces in VHDL

Hi,

i read a lot of similar threads on this topic here but i could not find a solution to my (maybe suuper simple;) ) questions.

I also would like to know if this approach is a good way to implement shared memory to pass 20 .. 30 parameters .

The basic idea is to create a shared memory location for Nios to dump parameters and VHDL modules to read these parameters.

So i created a dual port RAM in Qsys, connecting to the first slave only the data master from Nios and exporting the second slave.

i connected a VHDL module to the second slave. The whole system looks like this:

https://www.alteraforum.com/forum/attachment.php?attachmentid=8978

In Qsys the dpram was instantiated with:

datawidth 32 bit,

total memory size 32768 bytes, (which results in a 13 bit wide address bus)

single clock operation.

The Address region lasts from 0x0400_0000 to 0x0400_7FFF.

I checked if i could read and write from Nios to the memory and this works fine with:


IOWR(SHARED_MEM_BASE,0,0xF);
int a = IORD(SHARED_MEM_BASE,0);
printf("%i",a);  // results in 15

For the VHDL module i thought it is sufficient to connect the address where i want to read from and read the data from this address.

But i struggle to map the addresses.

The base_address is h"4000000" for the first memory slave but how can i now access this region through the second slave?

I would need 25 bit to reach this address but Qsys only gives me 13.

I have the feeling this is a really stupid question, but right now i am really stuck.

i read the Avalon Specification but i could not find a solution there.

Thanks to all for reading!!

Cheers

Tim

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MemoryMaster is
port (
    clk                : in    std_logic;
    reset_n            : in    std_logic;
    --av_m_chipselect  : in    std_logic;
    av_m_write     : out    std_logic;
    av_m_read    : out    std_logic;
    av_m_address     : out    std_logic_vector(12 downto 0);
    av_m_writedata   : out    std_logic_vector(31 downto 0);
    av_m_readdata    : in   std_logic_vector(31 downto 0);
    q : out std_logic
);
end MemoryMaster;
-- base address shared memory 0x4000 000 
architecture behave of MemoryMaster is
begin
avalon_if : process (reset_n, clk)  
begin
    if ( reset_n = '0' ) then
        av_m_address <= (others => '0');
        av_m_write <= '0';
        av_m_read <= '0';
        av_m_writedata <= (others => '0');
        
    elsif clk'event and clk ='1' then
        --av_m_address <= (others => '0');
        --av_m_address(26) <= '1';
        av_m_address <=b"0_0100_0000_0000";
        
        if (av_m_readdata = x"F") then 
        q <= '1';
        else 
        q <= '0';
        --if ( av_m_read_n = '0'  and av_m_address = b"0" ) then      
            --av_m_readdata <= reg_temp;
        --elsif ( av_m_write = '0' and av_m_address = b"1" ) then  
            
        end if;
    end if;
end process avalon_if;
end behave;

21 Replies

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

    I now solved this issue.

    The problem was the addresses were assigned to late and the data from memory was assigned to the wrong port.

    By introducing a state to "burn a clock cycle" between the setup_addr states and the read states makes the design work.

    Now all the values are read correctly and the output port show the correct signals.

    I thought it is possible to read data one clock cycle after applying the address, but obviously that is not correct.

    is it possible to avoid this extra state by using somekind of wait statement? What is the best way to do this?

    Cheers

    Tim

    (now my weekend will be much nicer ;))