Search code examples
vhdl

Read and Write 2d array in BRAM VHDL


I want to sort an array of length 16 having 8 bit numbers. I have used bubblesort for it and it's working fine. Now I want to read the input array from BRAM and write the sorted output to BRAM. I have used Single Port RAM for testbench and here is how it looks.

library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity testbench is   
end testbench;

architecture Behavioral of testbench is

--temporary signal declarations.
signal ena : std_logic := '0';
signal wea : std_logic_VECTOR(0 downto 0):="0";
signal addra,dina,douta : std_logic_VECTOR(7 downto 0) := (others => '0');
signal clk : std_logic := '0';

begin
--Instantiating BRAM.
BRAM : entity work.BRAM_test 
port map(
clka => clk,  --clock for writing data to RAM.
ena => ena,   --Enable signal.
wea => wea,   --Write enable signal for Port A.
addra => addra, --8 bit address for the RAM.
dina => dina,   --8 bit data input to the RAM.
douta => douta);  --8 bit data output from the RAM. 

--Simulation process.
process(clk)
begin
addra <= X"00";  --reset the address value for reading from memory location "0"


end process;    

--Clock generation - Generates 500 MHz clock with 50% duty cycle.
process
begin
clk <= '1';
wait for 1 ns;  --"ON" time.
clk <= '0';
wait for 1 ns;  --"OFF" time.
end process;    

end Behavioral;

I am unable to do that. Please help me.


Solution

  • you can do something like the attached code below. it's a process going through the states to read the BRAM content, to sort the data (you can add the logic for the sorting) and to write the results back.

    gen_reset: process
    begin
        reset<='1';
        wait for 50 ns;
        reset<='0';
        wait;
    end process gen_reset;
    
    gen_bram_access: process(clk, reset)
        type state_t is (read_bram, sort, write_bram, end_state);
        type buf_t is array(255 downto 0) of std_logic_vector(7 downto 0);
        variable buf: buf_t;
        variable state: state_t;
    
    begin
        if reset='1' then
            addra<=X"00";
            buf:=(others=>(others => '0'));
            ena<='1';
            wea<="0";
            state:=read_bram;
        elsif rising_Edge(clk) then
            -- defaults
            ena<='1';
            wea<="0"; 
    
            case state is
        -- readout
            when read_bram =>
                if addra<X"FF" then --expected that X"FF" is last address
                    buf(to_integer(unsigned(addra))):=dina;
                    state:=read_bram;
                    addra<=std_logic_vector(unsigned(addra) + 1);
                else
                    addra<=X"00";
                    state:=sort;
                end if;
    
        -- sort with whatever algo
            when sort =>
                -- add algo here! when finished, write results!
                state:=write_bram;
    
        -- write sorted to bram 
            when write_bram =>  
                if addra<X"FF" then --expected that X"FF" is last address
                    douta<=buf(to_integer(unsigned(addra)));
                    wea<="1";
                    state:=write_bram;
                    addra<=std_logic_vector(unsigned(addra) + 1);
                else
                    addra<=X"00";
                    state:=end_state;
                end if;         
            when others => -- (end_state)   
                state:=end_state;
            end case;
        end if;
    end process gen_bram_access;