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.

How to Create large Memory in VHDL

Status
Not open for further replies.

nikhilsigma

Full Member level 2
Full Member level 2
Joined
Jun 19, 2010
Messages
142
Helped
17
Reputation
34
Reaction score
16
Trophy points
1,298
Location
Delhi, India
Activity points
2,584
Hi,
In my project i need to model an SSD Controller but for that to do something i think that i should also implement the Flash memory on FPGA. so how can i create a memory of 512 bytes(a page)....

for example :
  • Total Flash memory is divided into blocks
  • and each block have 16 pages
  • and each page have 512 bytes of memory

i can easily create flipflops and registers but don't know how should i create such a large memory... :???:
so please tell me how to create such a large memory on FPGA from VHDL CODE !!
 

What device are you using? Not all FPGAs have Flash available. Your question is really more specific to the device than to VHDL.
 

i am modeling flash so it will be registers only....

i found the following.... to make a memory as described above(no. blocks = 64)
it's a 3D array....


Code VHDL - [expand]
1
2
3
type pbyte is array (0 to 511) of std_logic_vector (7 downto 0);  --pbyte is no of bytes in a page, each byte having 8 bits....
type mem_page is array (0 to 1023) of pbyte;                      -- total memory data type
signal page : mem_page :=(others=>(others =>(others => '0')));    -- TOTAL MEMORY !!



xilinx is showing that this is synthesizable....but still fingers crossed... :wink:

BUT now the problem is how to access the particular element of array.....??

please help...
 

Hi,
In my project i need to model an SSD Controller but for that to do something i think that i should also implement the Flash memory on FPGA. so how can i create a memory of 512 bytes(a page)....
I would just drop in a tiny processor (picoblaze on Xilinx) to handle the complexity this is likely to require. Now wait, this does not look like a real design problem. Is this your homework?:lol:
 
Last edited by a moderator:

I would just drop in a tiny processor (picoblaze on Xilinx) to handle the complexity this is likely to require. Now wait, this does not look like a real design problem. Is this your homework?:lol:

no mini project.....it's just a part of project.....
and even if this would have been my homework then also can't i have any doubts in that...??
 

Hey guys its showing warnings while sysnthesizing the code.....

WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.


lines 80 and 97 are mentioned in the code in comments....longest lines.....


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    18:44:36 09/15/2012 
-- Design Name: 
-- Module Name:    memory - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity memory is
    Port ( rw,clk : in  STD_LOGIC;
           add : in  STD_LOGIC_VECTOR (9 downto 0);
           data : inout  STD_LOGIC_VECTOR (63 downto 0);
           busy1 : out  STD_LOGIC:='0');
--            aaa : inout integer );
end memory;
 
 
 
architecture Behavioral of memory is
type pbyte is array (0 to 511) of std_logic_vector (7 downto 0);  --pbyte is no of bytes in a page
type mem_page is array (0 to 1023) of pbyte;                      -- total memory type
signal page : mem_page :=(others=>(others =>(others => '0')));    -- TOTAL MEMORY !!
-- Temporary buffer
signal cu_add : std_logic_vector (9 downto 0);
signal cu_rw : std_logic;
signal count,add_int: integer :=0;
signal rep,busy : std_logic :='0';
begin
 
    add_int<= CONV_INTEGER(cu_add); --converting adderess to integer..
    busy1<=busy;
    
    assign : process(clk)
    begin
        if(rising_edge(clk))
        then
            if(busy='0')
            then
                cu_add<=add;
                cu_rw<=rw;
            end if;
        end if;
    end process assign;
            
    
    
    main : process(clk)
    begin
        if(rising_edge(clk))
        then
                        
            if(rep='1')
            then
                if(count<64)
                then
                    if(cu_rw='1')   -- Reading DATA
                    then
                        data <= page(add_int)(count) & page(add_int)(count+1) & page(add_int)(count+2) & page(add_int)(count+3) & page(add_int)(count+4) & page(add_int)(count+5) & page(add_int)(count+6) & page(add_int)(count+7);
--                  else      -- Writing DATA
--                      page(add_int)<=data;
                    end if;
                    count<=count+8;
                    if(count=64)
                    then
                        rep<='0';
                        count<=0;
                        busy<='0';
                    end if;
                end if;
            else
                busy <= '1';
                rep<='1';
                if(cu_rw='1')   -- Reading DATA
                then
                    data <= page(add_int)(0) & page(add_int)(1) & page(add_int)(2) & page(add_int)(3) & page(add_int)(4) & page(add_int)(5) & page(add_int)(6) & page(add_int)(7);
--              else      -- Writing DATA
--                  page(add_int)<=data;
                end if;
            end if;
            
        end if;
    end process;
        
 
end Behavioral;



Exact Console output is :

Code:
Reading design: memory.prj

=========================================================================
*                          HDL Compilation                              *
=========================================================================
Compiling vhdl file "C:/Xilinx92i/Programs/Mem/memory.vhd" in Library work.
Architecture behavioral of Entity memory is up to date.

=========================================================================
*                     Design Hierarchy Analysis                         *
=========================================================================
Analyzing hierarchy for entity <memory> in library <work> (architecture <behavioral>).


=========================================================================
*                            HDL Analysis                               *
=========================================================================
Analyzing Entity <memory> in library <work> (Architecture <behavioral>).
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 80: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.
WARNING:Xst:790 - "C:/Xilinx92i/Programs/Mem/memory.vhd" line 97: Index value(s) does not match array range, simulation mismatch.

No error is shown in syntax....BUT only warnings in synthesis......!! :cry:
Please tell me what is wrong....???
 

Some confusion results from the fact that you are saying you want to model a flash but are writing synthesizable hardware. A flash model doesn't need to be synthesizable. You can review the flash models e.g. available from Micron.

I doubt that your code will synthesize to real FPGA hardware, at least with nonzero memory content. As is, it can't be mapped to block RAM, and most likely doesn't fit available block RAM capacity.

Unfortunately I don't recognize at first sight how the said range mismatch is created.
 

Mmmh, isn't data 64-bit vector? If so, the offending lines only stuff an 8-bit vector into that 64-bit vector.

As in:

Code:
data <= page(add_int)(count) & page(add_int)(count+1) & page(add_int)(count+2) & page(add_int)(count+3) & page(add_int)(count+4) & page(add_int)(count+5) & page(add_int)(count+6) & page(add_int)(count+7);

If I understand things correctly, then the left side is 64 bits, and the operand on the right side it only 8 bits. Won't that give you some warnings in vhdl country?

Then again, I probably don't understand things correctly, because a similar line does NOT give warnings. The only diff being that the non-warning-generating line has fixed indices.

So I come back to what I thought, but then thought naaaah too simple... You probably overrun the bit range in some silly way.

Pedantic stuff: even if (count < 64), you can still generate illegal indices in your code, depending on starting conditions. Your current code only works fine for a starting count where count mod 8 = 0. So maybe do some printing of "count" during simulation and see if it has any funny value.

Other than that, coming from verilog country and just learning vhdl by example, so feel free to ignore any potential silly remarks. :p
 
Last edited:

isn't data 64-bit vector? If so, the offending lines only stuff an 8-bit vector into that 64-bit vector.
No, 8 bytes are concatenated to 64 bit, that's correct so far. I wonder however, why the memory hasn't been defined with 64-Bit words?

The compiler may have problems to recognize the index range, I'm not sure about. Without enabling writes to the memory or giving it a default nonzero content, the design is pretty useless.
 

No, 8 bytes are concatenated to 64 bit, that's correct so far. I wonder however, why the memory hasn't been defined with 64-Bit words?

The compiler may have problems to recognize the index range, I'm not sure about. Without enabling writes to the memory or giving it a default nonzero content, the design is pretty useless.

first of all thanks alot for replying....i want to make some things clear....

I am still in a process of making the whole code, although write can be done by uncommenting those write commands...
also the data bus is of 8bytes thus i need to send 8 bytes in one clk cycle(so i was trying to concatenate) and thus whole page of 512bytes will be transfered in 64 cycles...
also i have to read or write the complete page.....
and i am just modeling the FLASH MEMORY, in simple words i want to create a memory or a 3D array with following specifications...
-Total 1024 pages
-each page having 512 Bytes
-each byte having 8 bits

so if you can suggest a better way to create this kind of memory or 3D array....then i would be very thankful to you....but it should be synthesizable...
 

You are still talking about models - models are usually for simulation only. Why are you putting it on an FPGA?
 

This is not a real project, but a contrived homework, obviously. The whole point of homework is to do the work yourself, not ask an engineer to do it for you. Ask for pointers, or specific issues you get into with syntax or whatever... Otherwise you or your parents are paying a lot of money for nothing.

I am not trying to start a fight. I just think that you are depriving yourself from an excellent opportunity to learn something and feel good about it. I apologize for upsetting you in any way.
 
No, 8 bytes are concatenated to 64 bit, that's correct so far. I wonder however, why the memory hasn't been defined with 64-Bit words?

A-gah! I did see the concatenation, only I read it as 8 parts of 1 bit each being concatenated. Turns out it was 8-bits for each part. *BLIND* Thanks for the clarification.
 

This is not a real project, but a contrived homework, obviously. The whole point of homework is to do the work yourself, not ask an engineer to do it for you. Ask for pointers, or specific issues you get into with syntax or whatever... Otherwise you or your parents are paying a lot of money for nothing.
If you read more than the original post, you'll notice that nikhilsigma already did some work himself. In so far your comment doesn't fit the present thread well, but in fact many others.
 
No insult intended. I guess I am just missing the point. If nikhilsigma is really trying to wire up to a flash, we are talking about a very specific FPGA indeed and not generic VHDL that is applicable to various devices. So we are talking about a handful of Spartan3AN parts, or something like that. Or perhaps he is trying to fake a flash using a RAM? Or is there an external flash? Is there a specific flash part that needs to be simulated for timing or whatever? Then how is having an array of RAM in VHDL helpful?

I am new here, and apologize for any wrongdoing in advance. It's just that when people ask a question with an implied partial solution, for instance, "I need to do xxx using yyy", my first question is "Why yyy when it totally does not fit? Why not zzz?". The answer is either "This is a homework and my teacher told me to use VHDL" or "My boss who knows nothing about software likes Ruby on Rails".

Either way, we all lose - the student gets a job and says "I implemented a fake flash array in VHDL on an FPGA", passes the interview and gets laughed at at the water cooler. The poor developer who stays up all night debugging Ruby on Rails and gets laughed at at the water cooler. The customer who gets a crashing microwave or awful web pages... Me - I get to waste my time writing idiotic messages like this one...
 

Your questions are well founded, but I can't answer it. I also fear that the original poster doesn't exactly understand the differences between hardware modelling and hardware synthesis. If simulation of flash in FPGA hardware is actually intended, the design needs to reflect the restrcitions of internal block RAM and also the limited resources, which isn't apparently the case yet.
 
Last edited:

Dear stacksmith, First of all i want to thank you for being so optimistic... and I respect that alot. As i have mentioned earlier that this is a part of my project so YES you can say it as a homework. BUT i want to say that i am trying my best to learn things and do them my self, and also it is NOT like that i have posted my COMPLETE problem here for anyone else to solve for me....I was just asking you guys how to make a 3D array or an VECTOR of VECTOR, thats it !! as i was not able to find out how to do that. and i gave some other details like pages, blocks, flash etc, just to make it easy for others to relate and answer, it would be good if they can suggest me some improvement....I never wanted someone to complete my code..

and if still you people think that i have done something wrong, then i am really sorry for that...

still it would be great if anyone can tell me that why that concatination is not working(giving warning) ??
 

nikhilsigma said:
I was just asking you guys how to make a 3D array or an VECTOR of VECTOR, thats it !!
Wut? Are we still talking about this?

Okay, forget VHDL and fpga hardware and all that crap for the moment.

We want to make a 5-dimensional memory where each memory node is a 16-bit word. How do we do that? For the sake of simplicity all the dimensions are sized a power of 2.

5 dimensions: i, j, k, l, m.

sizes:
i =2 (1 bit)
j =4 (2 bit)
k =8 (3 bit)
l =4 (2 bit)
m = 2 (1 bit)

So total space of the magical 5-dimensional memory is 2*4*8*4*2 = 512 entries (9 bits address)

Now make a boring normal array of 512 entries. As address you just concatenate your "subaddress" for lack of a better word.

address = mllkkkji

or if vhdl makes you happy at this point you do

address = m & l & k & j & i; --- address being a 9-bit address.

Then you use that address for your regular boring RAM consisting of 512 words of 16-bits.

You can do this sort of thing in C/java/asm/vhdl/matlab/abstract math/whatever. Essentially it comes down to flattening an N-dimensional space by rolling it out in a lower dimensional space, and then just creatively address this lower dimensional space. And in computer land that usually means just concatenating addresses, assuming you cleverly chose power-of-two sizes. So where's the problem?

- - - Updated - - -

And before you predictably write "OMG but I already do the concatenatey thingy like you say, because previous posts have the word concatenate in them!!!". No you don't. You concatenate data entries, not addresses. ;-)
 
Last edited:

Thats sparse memory model seems a bit of overkill for a memory of 512k. And I recon as you fill it up, it will actually run slower than just a large array as it has to search through a long linked list to find your memory. Plus every time you add a value, it has to seach the whole list, and remove the previous value if it finds it. This design may have useful on computers with little ram, but nowadays its common to have at least 2GB ram which is more than ample for a 512k array.

but if you're interested, here is another sparse memory model:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
type ddr_model_t is protected
  impure function read( addr : unsigned(25 downto 0) ) return std_logic_vector;
  procedure write(      addr : unsigned(25 downto 0); 
                        data : std_logic_vector(31 downto 0)
                 );
  
end protected ddr_model_t;
 
 
 
type ddr_model_t is protected body
    
  type bank_t;
  type row_t;
  
  type row_ptr_t is access row_t;
  type bank_ptr_t is access bank_t;
  
  type row_t  is array(0 to 1023) of std_logic_vector(31 downto 0);
  type bank_t is array(0 to 8191) of row_ptr_t;
  
  ---------------------------------------------------------------------
  --Total mem is 8 banks x 8192 rows x 1024 columns x 32 bits/word
  --
  -- = 256 Mbyte
  ---------------------------------------------------------------------
  type mem_t is array(0 to 7) of bank_ptr_t;
  
  variable mem              : mem_t;
  
  impure function read(addr : unsigned(25 downto 0) )  return std_logic_vector is
    variable bank           : integer;
    variable row            : integer;
    variable column         : integer;
    
    variable ret            : std_logic_vector(31 downto 0);
  begin
    
    bank     := to_integer( addr(25 downto 23) );
    row      := to_integer( addr(22 downto 10) );
    column   := to_integer( addr( 9 downto  0) );
    
    ---------------------------------------------------------
    --Bank has not been written to, therefore not created
    ---------------------------------------------------------
    if mem(bank) = null then
      ret := (others => 'X');
      
    ---------------------------------------------------------
    --Row has not been written to, therefore not created
    ---------------------------------------------------------
    elsif mem(bank)(row) = null then
      ret := (others => 'X');
      
    ------------------------------------------
    --Return what has been written already
    ------------------------------------------
    else 
      ret :=  mem(bank)(row)(column);
    end if;
      
    return ret;   
  end function read;
 
 
  procedure write(      addr : unsigned(25 downto 0); 
                        data : std_logic_vector(31 downto 0)
                 ) is
    variable bank           : integer;
    variable row            : integer;
    variable column         : integer;
  begin
    
    bank     := to_integer( addr(25 downto 23) );
    row      := to_integer( addr(22 downto 10) );
    column   := to_integer( addr( 9 downto  0) );
    
    --------------------------------------------------
    --Create the bank if it doesnt already exist
    --------------------------------------------------
    if mem(bank)   = null then
      mem(bank)   := new bank_t;
    end if;
    
    ---------------------------------------------
    --Create the row if it doesnt already exist
    ---------------------------------------------
    if mem(bank)(row) = null then
      mem(bank)(row)     := new row_t;
    
      mem(bank)(row).all := (row_t'range => (others => 'X'));
    end if;
    
    mem(bank)(row)(column) := data;
  end procedure write;
  
end protected body ddr_model_t;

 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top