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.

VHDL Generic multi-port memory

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
I'm trying to build a generic multi port memory (register based - not RAM).

I wrote the following package:
Code:
package definitions is
constant memory_depth : positive := 256 ;
constant memory_width : positive := 8 ;
constant number_of_ports : positive := 4 ;
type array_of_address is array ( 0 to number_of_ports ) of unsigned ( log_2_decimal ( memory_depth ) downto 0 ) ;
type memory is array ( 0 to memory_depth ) of unsigned ( memory_width - 1 downto 0 ) ;
end package definitions ;

I use the package in my entity as follows:
Code:
I_WRITE : in unsigned ( number_of_ports - 1 downto 0 ) ;	
I_ADDRESS : in array_of_address ;
I_DATA: 	in memory ;

This is the write process:
Code:
process ( I_CLOCK , I_RESET ) is
begin
   if I_RESET = '1' then  
      memory_matrix <= ( others => ( others => '0' ) ) ;
   elsif rising_edge ( I_CLOCK ) then 				
      for index in 0 to number_of_ports  
      loop
         if I_WRITE ( index ) = '1' then 
	memory_matrix <= I_DATA ( to_integer ( I_ADDRESS ( i ) ) ) ;  	
         end if ;
      end loop ;
   end if;	
end process ;

Modelsim fails with the following error:
Cannot resolve indexed name as type work.definitions.memory.

What did I do wrong?
 

I_DATA(N) returns an unsigned. memory_matrix appears to be an array of a std_logic array type (std_logic_vector, usigned or signed) - which is probably your memory type (Its common practice to name types with a prefix or a suffix like _t or _type).

I think you meant to write:

memory_matrix(to_integer ( I_ADDRESS ( i ) )) <= I_DATA ( to_integer ( I_ADDRESS ( i ) ) ) ;

Its quite difficult to see the whole picture with this code snippet

NOTE: talking about types - Im going to make an assumption as I can only see part of the code - why is I_WRITE an unsigned type. In your short code snippet you use it as a write enable, so why isnt it a std_logic_vector?
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
You understood my code and all of your assumptions are correct.
I_WRITE is indeed an unsigned vector. Every bit of it serves as a write enable to the corresponding data input and address input port.

I think that this indeed was the problem.
Code:
memory_matrix <= I_DATA ( to_integer ( I_ADDRESS ( i ) ) ) ;

I changed it to:
Code:
memory_matrix(to_integer ( I_ADDRESS ( i ) )) <= I_DATA ( to_integer ( I_ADDRESS ( i ) ) ) ;
compiles without errors now...

Regarding your question:
so why isnt it a std_logic_vector?
What's wrong with defining I_WRITE as unsigned?
I avoid using std_logic_vector in all of my new designs. Shouldn't I ?
 

What's wrong with defining I_WRITE as unsigned?
I avoid using std_logic_vector in all of my new designs. Shouldn't I ?

Well, theres nothing wrong with making I_WRITE an unsigned. Its like saying you shouldnt use a std_logic_vector for numbers.
VHDL has strong typing, hence why we have std_logic_vector, signed and unsigned which are all basically the same thing. But the whole point is you're meant to use an appropriate type for an appropriate task.

The problem with std_logic_vectors for numbers is that it could be a signed number or unsigned. You need a specific library to handle it as either and you cant easily use both at the same time (you can, but add lots more code to an already verbose language!). A Std_logic_vector is just meant to be a generic bus. Hence it is ideal to group things like write enables or other things together. Making it an unsigned implies it has some numerical value, which it really doesnt.

At the end of the day, it will work just as well with either. Using the wrong type will have no affect on the final design. It only affects the impression placed upon the next engineer.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I'm convinced.
Thanks for your help.
 

Can I ask your intended usage of this multi-port memory?

One of my students has just written a generic multi-port memory in Verilog for FPGAs. It synthesizes efficiently to Altera RAM blocks, and should also work well for other FPGAs. We are releasing it under an open source license.

We also have a research paper that describes the design, to appear at the FPGA2014 conference next week. It combines and generalizes two past approaches for generating efficient multi-port memories into a single framework.

In general, a RAM-based multiport memory uses (# read ports) x (# write ports) x NBlocks, where NBlocks is the number of blocks needed if it was a regular single or dual-port RAM.

Please let me know if you want access to the library. (Sorry I can't include a URL right now, but we are still getting the package together to put online somewhere.)
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I intend to use DFFs not RAM...
Sure,
Please include the URL.
 

One of my students has just written a generic multi-port memory in Verilog for FPGAs. It synthesizes efficiently to Altera RAM blocks, and should also work well for other FPGAs. We are releasing it under an open source license.

We also have a research paper that describes the design, to appear at the FPGA2014 conference next week. It combines and generalizes two past approaches for generating efficient multi-port memories into a single framework.

can you please explain how this differs from altera'a altsyncram for altera devices? How is it better than ram inference?

The main problem i have with "generic" multi port rams is they do not necessarily give access to all the base device features. And they usually are no better than inferred rams.
 

can you please explain how this differs from altera'a altsyncram for altera devices? How is it better than ram inference?

The main problem i have with "generic" multi port rams is they do not necessarily give access to all the base device features. And they usually are no better than inferred rams.

Altera (or Xilinx) can't create a 4-write, 3-read memory.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top