+ Post New Thread
Results 1 to 8 of 8
  1. #1
    Advanced Member level 5
    Points: 13,109, Level: 27
    Achievements:
    7 years registered

    Join Date
    Aug 2011
    Posts
    2,605
    Helped
    304 / 304
    Points
    13,109
    Level
    27

    Inferred VHDL dual port RAM template

    Hello,

    Taken from this link:
    https://www.intel.com/content/www/us...k-syncram.html

    The following code is an Intel VHDL template for inference of "Single Clock Synchronous RAM".
    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.numeric_std.ALL;
    
    ENTITY ram IS
    	GENERIC
    	(
    		ADDRESS_WIDTH	: integer := 4;
    		DATA_WIDTH	: integer := 8
    	);
    	PORT
    	(
    		clock			: IN  std_logic;
    		data			: IN  std_logic_vector(DATA_WIDTH - 1 DOWNTO 0);
    		write_address			: IN  std_logic_vector(ADDRESS_WIDTH - 1 DOWNTO 0);
    		read_address			: IN  std_logic_vector(ADDRESS_WIDTH - 1 DOWNTO 0);
    		we			: IN  std_logic;
    		q			: OUT std_logic_vector(DATA_WIDTH - 1 DOWNTO 0)
    	);
    END ram;
    
    ARCHITECTURE rtl OF ram IS
    	TYPE RAM IS ARRAY(0 TO 2 ** ADDRESS_WIDTH - 1) OF std_logic_vector(DATA_WIDTH - 1 DOWNTO 0);
    
    	SIGNAL ram_block : RAM;
    BEGIN
    	PROCESS (clock)
    	BEGIN
    		IF (clock'event AND clock = '1') THEN
    			IF (we = '1') THEN
    			    ram_block(to_integer(unsigned(write_address))) <= data;
    			END IF;
    
    			q <= ram_block(to_integer(unsigned(read_address)));
    		END IF;
    	END PROCESS;
    END rtl;
    As far as I understand - it will have a "Read Before Write" behavior when the same address is accessed.
    Question:
    Can you think of a way to change the above to behave as "Write Before Read" ?

    •   AltAdvertisement

        
       

  2. #2
    Advanced Member level 5
    Points: 37,911, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,874
    Helped
    2019 / 2019
    Points
    37,911
    Level
    47

    Re: Inferred VHDL dual port RAM template

    For xilinx you can do this by making the ram storage a shared variable rather than signal. But this never used to work for write before read in altera. Your only choice was to instantiate an altsyncram yourself.

    This may have changed, but you'll have to investigate. Imo, if you have an address collision and you're relying on write before read behaviour, you probably have a design problem.


    1 members found this post helpful.

  3. #3
    Advanced Member level 5
    Points: 13,109, Level: 27
    Achievements:
    7 years registered

    Join Date
    Aug 2011
    Posts
    2,605
    Helped
    304 / 304
    Points
    13,109
    Level
    27

    Re: Inferred VHDL dual port RAM template

    But this never used to work for write before read in altera
    When was the last time you tried it ?

    They do have a template that makes use of a shared variable - but it's for a "True Dual-Port RAM with a Single Clock".
    https://www.intel.com/content/www/us...-ram-sclk.html
    From reading the code this should have "Read Before Write" behavior.

    Imo, if you have an address collision and you're relying on write before read behaviour, you probably have a design problem.
    This isn't necessarily true.
    For example - I worked on a third party code that implements an histogram equalization algorithm.
    It would function correctly as long as the RAM is set to work as "Read Before Write" and fail for "Write Before Read".
    Not the most portable design - but I wouldn't call it a bug.



    •   AltAdvertisement

        
       

  4. #4
    Full Member level 5
    Points: 2,369, Level: 11

    Join Date
    May 2014
    Posts
    279
    Helped
    28 / 28
    Points
    2,369
    Level
    11

    Re: Inferred VHDL dual port RAM template

    How important is portability vs vendor ip instantiation?

    Just a brain dump - Based on the code presented you'll always have to wait 1 cycle after we='1' before your see write value pushed out onto the read q signal. Why not assign a valid signal associated with your read that is either delayed 'we' or a delayed ack of address change. The latency of which is 1 clk for read on address change and 2 clks for read on write change.

    tldr - why not supply your own valid signal with read?

    Regards,
    Wes



  5. #5
    Advanced Member level 5
    Points: 13,109, Level: 27
    Achievements:
    7 years registered

    Join Date
    Aug 2011
    Posts
    2,605
    Helped
    304 / 304
    Points
    13,109
    Level
    27

    Re: Inferred VHDL dual port RAM template

    Hi,
    It'll be easier to understand what you're proposing if you post a code example.



  6. #6
    Full Member level 5
    Points: 2,369, Level: 11

    Join Date
    May 2014
    Posts
    279
    Helped
    28 / 28
    Points
    2,369
    Level
    11

    Re: Inferred VHDL dual port RAM template

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    process(clk) is
    begin
        if rising_edge(clk) then
            prev_read_addr <= read_addr;
        end if;
    end process;
     
    process(clk) is
    begin
        if rising_edge(clk) then
            if prev_read_addr /= read_addr then
                r_valid_slv(0) <= '1';
            elsif we='1' then
                r_valid_slv(0) <= '1';
            else
                r_valid_slv(0) <= '0';
            end if;
            r_valid_slv(2 downto 1) <= r_valid_slv(1 downto 0);
            r_valid_flag <= r_valid_slv(2);
        end if;
    end process;



    •   AltAdvertisement

        
       

  7. #7
    Newbie level 4
    Points: 44, Level: 1

    Join Date
    Sep 2019
    Location
    Germany
    Posts
    7
    Helped
    0 / 0
    Points
    44
    Level
    1

    Re: Inferred VHDL dual port RAM template

    You could add an if-else condition on the assignment to "q" such that if read and write address are equal and write enable is also '1', then "q" should be assigned "data", else it should be assigned the value at read address from "ram_block".



  8. #8
    Advanced Member level 5
    Points: 37,911, Level: 47
    Achievements:
    7 years registered

    Join Date
    Jun 2010
    Posts
    6,874
    Helped
    2019 / 2019
    Points
    37,911
    Level
    47

    Re: Inferred VHDL dual port RAM template

    Quote Originally Posted by wahab.khan View Post
    You could add an if-else condition on the assignment to "q" such that if read and write address are equal and write enable is also '1', then "q" should be assigned "data", else it should be assigned the value at read address from "ram_block".
    You have to be a little careful with the code, as if it goes too far from the template, inferrence may not work.



--[[ ]]--