Flip Flop based memory instead of RAM

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
Visit site
Activity points
18,302
I wrote this code for generic multiport memory.

Code:
entity memory is
generic 
(       	
  CELL_WIDTH : positive := 8 ;
  NUMBER_OF_CELLS : positive := 4 ;
  NUMBER_OF_WRITE_PORTS : positive := 1 ; 															
  NUMBER_OF_READ_PORTS : positive := 1 		
) ;													
port														
( 		
  CLOCK : in std_logic ;          								
  WRITE_REQUEST_VECTOR : in std_logic_vector ( NUMBER_OF_WRITE_PORTS - 1 downto 0 ) ;										
  READ_REQUEST_VECTOR : in std_logic_vector ( NUMBER_OF_READ_PORTS - 1 downto 0 ) ; 										
  WRITE_ADDRESS_ARRAY : in type_array_unsigned ( 0 to NUMBER_OF_WRITE_PORTS - 1 ) ( log_2_decimal ( NUMBER_OF_CELLS ) - 1 downto 0 ) ;				
  READ_ADDRESS_ARRAY : in	type_array_unsigned ( 0 to NUMBER_OF_READ_PORTS - 1 ) ( log_2_decimal ( NUMBER_OF_CELLS ) - 1 downto 0 ) ;	
  INPUT_DATA_ARRAY : in type_array_slv ( 0 to NUMBER_OF_WRITE_PORTS - 1 ) ( CELL_WIDTH - 1 downto 0 ) ;									
  OUTPUT_DATA_ARRAY : out type_array_slv ( 0 to NUMBER_OF_READ_PORTS - 1 ) ( CELL_WIDTH - 1 downto 0 ) 							
) ;             

end entity memory ;


architecture synthesizable_memory of memory is

type type_array_data_memory is array ( 0 to NUMBER_OF_CELLS - 1 ) of std_logic_vector ( CELL_WIDTH - 1 downto 0 ) ; 	
signal memory_matrix : type_array_data_memory ;																		
begin

  writing : process ( CLOCK ) is
  begin
    if rising_edge ( CLOCK ) then 
      for index in INPUT_DATA_ARRAY ' range
      loop
        if WRITE_REQUEST_VECTOR ( index ) = '1' and PORT_IN_SLV_ENABLE ( index ) = '1' then 
          memory_matrix ( to_integer ( WRITE_ADDRESS_ARRAY ( index ) ) ) <= INPUT_DATA_ARRAY ( index ) ;  	
        end if ;
      end loop ;	
    end if;	
  end process writing ;			
  
  reading : process ( CLOCK ) is
  begin
    if rising_edge ( CLOCK ) then 
      for index in OUTPUT_DATA_ARRAY ' range
      loop
        if READ_REQUEST_VECTOR ( index ) = '1' then
          OUTPUT_DATA_ARRAY ( index ) <=  memory_matrix ( to_integer ( ( READ_ADDRESS_ARRAY ( index ) ) ) ) ;	
        end if ;
      end loop ;	
    end if;	
  end process reading ;

end architecture synthesizable_memory ;

When the "NUMBER_OF_WRITE_PORTS" , "NUMBER_OF_READ_PORTS" generics are instantiated to a value higher then 1, a multiport flip-flop based memory is successfully generated.

However, when the "NUMBER_OF_WRITE_PORTS" , "NUMBER_OF_READ_PORTS" generics are instantiated to 1 - I expect the synthesis tool to see that the complex multi port memory degenerates to simple block RAM.

But this doesn't happen. The RTL viewer shows that flip-flops (and not RAM) remain the bulding block of the memory matrix.

Why does this happen?
 

I doubt that the question can be generally answered. It refers to the hardware features of the used device family and the specific memory inference rules of your synthesis tool. Also synthesis settings can suppress RAM inference below a certain memory size.

Altera Quartus would e.g. require to register the read address. The actual memory read process can be either combinational (unregistered RAM outputs) or clocked (registered outputs).
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
venturing too far from the synthesis templates can cause non-generation of expected device.

Much safer just to use generates around a known good bit of code.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…