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.
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?
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.
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.
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.)
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.