Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Dealing with RAM in VHDL

Status
Not open for further replies.

saifaljanahi

Newbie level 6
Joined
Jul 30, 2020
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Location
Najaf
Activity points
72
Hello all,
I'm new here and beginner to FPGA world.

I'm having a data from another project (it's Fibonacci seqence) and i want to store these data in a RAM memory using vhdl (only simulation) but my instructor didn't give me enough information how to do it and also he's never explained how to dealing with ram and rom.

So I'm confused how to generate addresses for the (Fibonacci seqence for example) and how to read and write to this memory.

Any help is highly appreciated.
 

Hi,

We don't know
* what knowledge you currently have
* what you have learned
* what documents you did read
* what videos you watched
Nor do we know what you expect from us.

Give use informations, give us details.

Klaus
 

Read the memory documentation of the FPGA device you are using, they all have timing diagrams and even code examples of how to infer their RAM/ROMs in VHDL/Verilog.

Or generate a memory IP core and look at the testbench produced by the tools and see how the vendor interfaces to the RAM. You can also run a simulation to see how it works.

If you don't understand how the Fibonacci sequence works then look at the wiki page.
 

Hi,

We don't know
* what knowledge you currently have
* what you have learned
* what documents you did read
* what videos you watched
Nor do we know what you expect from us.

Give use informations, give us details.

Klaus

Hello,
* I have knowledge in general digital design but not so advanced.
* Till now I have learned how to design decoders, muxes, storage elements, counters, FSM.
* I'm reading a textbook called "Circuit Design and Simulation in Vhdl".
* till now I've watched videos only about testbench (sequential one).

any other details you need ill happy to give, thanks.
 

Read the memory documentation of the FPGA device you are using, they all have timing diagrams and even code examples of how to infer their RAM/ROMs in VHDL/Verilog.

Or generate a memory IP core and look at the testbench produced by the tools and see how the vendor interfaces to the RAM. You can also run a simulation to see how it works.

If you don't understand how the Fibonacci sequence works then look at the wiki page.
Thanks for your reply.

My instructor gives me a hint to use a counter to generate the RAM addresses though this ram is dual-port so it will need write_addresses and read_addresses, I'm finished from the Fibonacci part and now confused how to generate ram addresses.

I looked into the document of the specific FPGA board that we must deal with, I haven't found anything related to RAM, the document is talking about SDRAM and I don't know what SDRAM is,

I think my instructor want me to deal not with the FPGA RAM, I think it's just a RAM (pure simulation), thanks again.
 
Last edited:

Here's a dual port, single clock RAM template.

Code:
-- Quartus Prime VHDL Template
-- Simple Dual-Port RAM with different read/write addresses but
-- single read/write clock

library ieee;
use ieee.std_logic_1164.all;

entity simple_dual_port_ram_single_clock is

    generic
    (
        DATA_WIDTH : natural := 8;
        ADDR_WIDTH : natural := 6
    );

    port
    (
        clk        : in std_logic;
        raddr    : in natural range 0 to 2**ADDR_WIDTH - 1;
        waddr    : in natural range 0 to 2**ADDR_WIDTH - 1;
        data    : in std_logic_vector((DATA_WIDTH-1) downto 0);
        we        : in std_logic := '1';
        q        : out std_logic_vector((DATA_WIDTH -1) downto 0)
    );

end simple_dual_port_ram_single_clock;

architecture rtl of simple_dual_port_ram_single_clock is

    -- Build a 2-D array type for the RAM
    subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
    type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;

    -- Declare the RAM signal.  
    signal ram : memory_t;

begin

    process(clk)
    begin
    if(rising_edge(clk)) then
        if(we = '1') then
            ram(waddr) <= data;
        end if;

        -- On a read during a write to the same address, the read will
        -- return the OLD data at the address
        q <= ram(raddr);
    end if;
    end process;

end rtl;
 


Here's a dual port, single clock RAM template.

Code:
-- Quartus Prime VHDL Template
-- Simple Dual-Port RAM with different read/write addresses but
-- single read/write clock

library ieee;
use ieee.std_logic_1164.all;

entity simple_dual_port_ram_single_clock is

    generic
    (
        DATA_WIDTH : natural := 8;
        ADDR_WIDTH : natural := 6
    );

    port
    (
        clk        : in std_logic;
        raddr    : in natural range 0 to 2**ADDR_WIDTH - 1;
        waddr    : in natural range 0 to 2**ADDR_WIDTH - 1;
        data    : in std_logic_vector((DATA_WIDTH-1) downto 0);
        we        : in std_logic := '1';
        q        : out std_logic_vector((DATA_WIDTH -1) downto 0)
    );

end simple_dual_port_ram_single_clock;

architecture rtl of simple_dual_port_ram_single_clock is

    -- Build a 2-D array type for the RAM
    subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
    type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;

    -- Declare the RAM signal.
    signal ram : memory_t;

begin

    process(clk)
    begin
    if(rising_edge(clk)) then
        if(we = '1') then
            ram(waddr) <= data;
        end if;

        -- On a read during a write to the same address, the read will
        -- return the OLD data at the address
        q <= ram(raddr);
    end if;
    end process;

end rtl;

it's so ok till now, but one more thing.

I'm confused about how to make addresses to the Fibonacci outputs, my instructor said by using counter but no further info about that gives me.
and also he said I must use FSM to control the memory.

If you are using a Xilinx FPGA, I would recommend to use the Synthesis Guide.

See the topic RAM HDL Coding Guidelines in there. Templates for various RAM types can be found there.

Other FPGA vendors should also have such a document.
I don't think documentation gonna help me, I'm using pure simulation which is no specific fpga board to handle this code here, thanks.
 

Your question isn't specifically related to RAM, more to implementation of the overall code.The Fibonacci sequence itself can be generated by just two registers and an adder.

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
signal F0, F1: integer;
begin
process (reset, clock)
begin
  if reset = '1' then
    F0 <= 0;
    F1 <= 1;
  elsif rising_edge(clock) then
    F0 <= F1;
    F1 <= F0 + F1;
  end if;
end process;


I understand that your exercise problem involves storing the sequence to a RAM. You could read the Fn-1 und Fn-2 from the RAM which might use a FSM, but that's not actually necessary.
 

Your question isn't specifically related to RAM, more to implementation of the overall code.The Fibonacci sequence itself can be generated by just two registers and an adder.

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
signal F0, F1: integer;
begin
process (reset, clock)
begin
  if reset = '1' then
    F0 <= 0;
    F1 <= 1;
  elsif rising_edge(clock) then
    F0 <= F1;
    F1 <= F0 + F1;
  end if;
end process;


I understand that your exercise problem involves storing the sequence to a RAM. You could read the Fn-1 und Fn-2 from the RAM which might use a FSM, but that's not actually necessary.

I'm getting so close, I've finished the Fibonacci part two days ago and I've understand how RAM memory works yesterday, but now I'm struggling to complete this project, which is after generating the Fibonacci seqence I must store these seqences one by one to a RAM and control the read and write of this RAM by FSM.
The hardest part and that I so confused about is how to generate addresses for the Fibonacci seqence and how to store them in such manner as using FSM.

Thanks for your reply, really helpful.
 

write down the data flow..something like

1. address =0, write 0, address++
2. address =1, write 1, address++
now we can start a loop to do the reset of the sequence
3. address = 2, read address-2, read address-1, add the two numbers, write sum to address=2, address++
4. repeat step 3 with address=3,4,5....

Write an FSM that follows that flow. You will probably want to break the steps down further as I've got a lot of steps (clock cycles) compressed together.
 

write down the data flow..something like

1. address =0, write 0, address++
2. address =1, write 1, address++
now we can start a loop to do the reset of the sequence
3. address = 2, read address-2, read address-1, add the two numbers, write sum to address=2, address++
4. repeat step 3 with address=3,4,5....

Write an FSM that follows that flow. You will probably want to break the steps down further as I've got a lot of steps (clock cycles) compressed together.

Thanks, my instructor said I should use a counter to generate the Fibonacci sequence output addresses to the RAM.
 

Consider address as the counter value.
I'm stuck again unfortunately, I can't understand how to assign the counter of the Fibonacci sequences (0 for 0,1 ..... 7 for 13..etc) as an address to the memory, can you explain that to me, because now I want to assign the counter as address then loading theses addresses by the Fibonacci sequences, thank in advance for any help.
 

Using the Fibonacci sequence as the address? I suspect that isn't what you are supposed to do. It doesn't make a lot of sense as the address would be way to large in a short number of clock cycles. By the time you've reached the 48th number in the sequence you would end up with an address that is over 2^32 (4Gig).

From you description in your first post you say you are supposed to store the sequence in a RAM. If you make the RAM 64-bits wide you can store quite a few more values. If you store them in sequential locations in the RAM then a counter is what you use, which is what I describe in my previous post with the address++ (increment address, in both C and Verilog).

Also you don't "assign" the counter (or the Fibonacci sequence) to the the address of the RAM. That statement you made makes me think you don't quite grasp that VHDL is not actually the same as your usual programming languages like C++, ADA, etc. Think of VHDL has a way to describe how to hook up chips on a board without drawing the schematic or individual logic gates. So connecting the counter address to the RAM is instantiating a RAM block into your code (or writing a behavior description of the RAM using a template, linked by others) and using port mapping to connect a counter signal to the RAM address port.

Maybe you should look at examples of code that shows how to use RAM e.g. https://vhdlguide.readthedocs.io/en/latest/vhdl/dex.html#random-access-memory-ram which I found after a couple of search attempts (most search results showed how to infer RAM in VHDL with no example of using the RAM, this page has testbenches to run the RAM in a simulation).
 

The Fibonacci sequence takes on a shape like a tree's root system, with levels and columns (which are skewed columns).

When you generate a new row of numbers, you store the value of each number in one array. And you store its row number in another array. And its position on the row in another array.

There are tricks you can use to save memory if you have to. Example, omit left and right values of each row because they are always 1.
 

Using the Fibonacci sequence as the address? I suspect that isn't what you are supposed to do. It doesn't make a lot of sense as the address would be way to large in a short number of clock cycles. By the time you've reached the 48th number in the sequence you would end up with an address that is over 2^32 (4Gig).

From you description in your first post you say you are supposed to store the sequence in a RAM. If you make the RAM 64-bits wide you can store quite a few more values. If you store them in sequential locations in the RAM then a counter is what you use, which is what I describe in my previous post with the address++ (increment address, in both C and Verilog).

Also you don't "assign" the counter (or the Fibonacci sequence) to the the address of the RAM. That statement you made makes me think you don't quite grasp that VHDL is not actually the same as your usual programming languages like C++, ADA, etc. Think of VHDL has a way to describe how to hook up chips on a board without drawing the schematic or individual logic gates. So connecting the counter address to the RAM is instantiating a RAM block into your code (or writing a behavior description of the RAM using a template, linked by others) and using port mapping to connect a counter signal to the RAM address port.

Maybe you should look at examples of code that shows how to use RAM e.g. https://vhdlguide.readthedocs.io/en/latest/vhdl/dex.html#random-access-memory-ram which I found after a couple of search attempts (most search results showed how to infer RAM in VHDL with no example of using the RAM, this page has testbenches to run the RAM in a simulation).

Your reply is so helpful, really thanks.
PS: my attempt was to assign the counter of the sequences as addresses not the sequence as an address, just one more thing.
can you write to me Snippet code that stores counter of the sequence to the addresses and store the sequences into the DATA_IN in the RAM.
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top