Jump to content
  • 0

RAM write and read


Koss41

Question

hello,

Could you pls help me/I have a problem with RAM dual port.My purpose is the write some data in this RAM on the certain addresses/like on the 1 and 16 address I want to put some data.and on the rest of the address will be zero data.I write code like

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

entity dp_ram_rbw_scl is
  generic (
    DATA_WIDTH : integer := 8;
    ADDR_WIDTH : integer := 6
    );
  port (
-- common clock
    clk    : in  std_logic;
    -- Port A
    we_a   : in  std_logic;
    addr_a : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
    data_a : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    q_a    : out std_logic_vector(DATA_WIDTH-1 downto 0);

    -- Port B
    we_b   : in  std_logic;
    addr_b : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
    data_b : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    q_b    : out std_logic_vector(DATA_WIDTH-1 downto 0)
    );
end dp_ram_rbw_scl;

architecture rtl of dp_ram_rbw_scl is
  -- Shared memory
  type mem_type is array ((2**ADDR_WIDTH)-1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
  shared variable mem : mem_type;
begin

-- Port A
  process(clk)
  begin
    if(clk'event and clk = '1') then
      q_a <= mem(conv_integer(addr_a));
      if(we_a = '1') then
        mem(conv_integer(addr_a)) := data_a;
      end if;
    end if;
  end process;

-- Port B
  process(clk)
  begin
    if(clk'event and clk = '1') then
      q_b <= mem(conv_integer(addr_b));
      if(we_b = '1') then
        mem(conv_integer(addr_b)) := data_b;
      end if;
    end if;
  end process;

end rtl;

and test bench for this 

library ieee;
    use ieee.std_logic_1164.all;
	 use ieee.numeric_std.all;
	 use ieee.std_logic_unsigned.all;
entity ram_tb is
end ram_tb;
architecture behaviour of ram_tb is 
component dp_ram_rbw_scl
generic (
      DATA_WIDTH : natural := 8;
      ADDR_WIDTH : natural := 6
     );
     port (
      clk : in std_logic;
		addr_a : in std_logic_vector(ADDR_WIDTH-1 downto 0);
      addr_b : in std_logic_vector(ADDR_WIDTH-1 downto 0);
      data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);
      data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);
      we_a : in std_logic ;
      we_b : in std_logic ;
      q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);
      q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)
     );
end component;
--Inputs
signal clk :  std_logic :='0';
signal addr_a :  std_logic_vector(6-1 downto 0);
signal addr_b :  std_logic_vector(6-1 downto 0);
signal data_a :  std_logic_vector((8-1) downto 0);
signal data_b :  std_logic_vector((8-1) downto 0);
signal we_a :  std_logic ;
signal we_b :  std_logic ;
--Outputs
signal q_a :  std_logic_vector((8 -1) downto 0);
signal q_b :  std_logic_vector((8 -1) downto 0);
constant CLK_period : time := 5 ns;
constant ADDR_WIDTH : integer := 6;
constant DATA_WIDTH :integer :=8;
  type mem_type is array ((2**ADDR_WIDTH)-1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
  shared variable mem : mem_type;
begin
uut: dp_ram_rbw_scl port map (
clk=>clk,
addr_a=>addr_a,
addr_b =>addr_b,
data_a =>data_a,
data_b =>data_b,
we_a=>we_a,
we_b=>we_b,
q_a=>q_a,
q_b=>q_b
);
-- clock process definition
clk_process : process
begin
clk<= '1';
wait for 1 ns;
clk <= '0';
wait for 1 ns;
end process; 
--for A port we :=0
stim_proc :process
begin 
we_a <= '0';
addr_a <="000010";
data_a <="00000010";
q_a <= data_a;
wait for 1 ns;

addr_a <="000100";
data_a <="00000100";
q_a <=data_a;
wait for 1 ns;
addr_a <="001000";
data_a <="00001000";
q_a <=data_a;
wait for 1 ns;
addr_a <="010000";
data_a <="00010000";
q_a <=data_a;
wait for 1 ns;
addr_a <="100000";
data_a <="00100000";
q_a <=data_a;
wait for 1 ns;

--for A port we :=1
we_a <='1';
data_a <= "00100000";
addr_a <="000001";
q_a <= data_a;
wait for 1 ns;
addr_a <="000010";
data_a <= "00100000";
q_a <= data_a;
wait for 1 ns;
addr_a <="000100";
data_a <= "00100000";
wait for 1 ns;
q_a <= data_a;
addr_a <="001000";
data_a <= "00100000";
wait for 1 ns;
q_a <= data_a;
addr_a <="010000";wait for 1 ns;
data_a <= "00100000";

addr_a <="100000";
data_a <= "00100000";
q_a <= data_a;
wait for 1 ns;



end process;

 stim_proc1 :process
begin 
--for B port we :=0
we_b <= '0';

addr_b <="000010";
data_b <="00000010";
q_b <= data_b;
wait for 1 ns;

addr_b <="000100";
data_b <="00000100";
q_b <=data_b;
wait for 1 ns;
addr_b <="001000";
data_b <="00001000";
q_b <=data_b;
wait for 1 ns;
addr_b <="010000";
data_b <="00010000";
q_b <=data_b;
wait for 1 ns;
addr_b <="100000";
data_b <="00100000";
q_b <=data_b;
wait for 1 ns;

--for B port we :=1
we_b <='1';
data_b <= "00100000";
addr_b <="000001";
q_b <= data_b;
wait for 1 ns;
addr_b <="000010";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="000100";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="001000";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="010000";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="100000";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;



end process;
end;

Could you pls give me some hints or examples

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

7 minutes ago, Koss41 said:

hello,

Could you pls help me/I have a problem with RAM dual port.My purpose is the write some data in this RAM on the certain addresses/like on the 1 and 16 address I want to put some data.and on the rest of the address will be zero data.I write code like


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

entity dp_ram_rbw_scl is
  generic (
    DATA_WIDTH : integer := 8;
    ADDR_WIDTH : integer := 6
    );
  port (
-- common clock
    clk    : in  std_logic;
    -- Port A
    we_a   : in  std_logic;
    addr_a : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
    data_a : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    q_a    : out std_logic_vector(DATA_WIDTH-1 downto 0);

    -- Port B
    we_b   : in  std_logic;
    addr_b : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
    data_b : in  std_logic_vector(DATA_WIDTH-1 downto 0);
    q_b    : out std_logic_vector(DATA_WIDTH-1 downto 0)
    );
end dp_ram_rbw_scl;

architecture rtl of dp_ram_rbw_scl is
  -- Shared memory
  type mem_type is array ((2**ADDR_WIDTH)-1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
  shared variable mem : mem_type;
begin

-- Port A
  process(clk)
  begin
    if(clk'event and clk = '1') then
      q_a <= mem(conv_integer(addr_a));
      if(we_a = '1') then
        mem(conv_integer(addr_a)) := data_a;
      end if;
    end if;
  end process;

-- Port B
  process(clk)
  begin
    if(clk'event and clk = '1') then
      q_b <= mem(conv_integer(addr_b));
      if(we_b = '1') then
        mem(conv_integer(addr_b)) := data_b;
      end if;
    end if;
  end process;

end rtl;

and test bench for this 


library ieee;
    use ieee.std_logic_1164.all;
	 use ieee.numeric_std.all;
	 use ieee.std_logic_unsigned.all;
entity ram_tb is
end ram_tb;
architecture behaviour of ram_tb is 
component dp_ram_rbw_scl
generic (
      DATA_WIDTH : natural := 8;
      ADDR_WIDTH : natural := 6
     );
     port (
      clk : in std_logic;
		addr_a : in std_logic_vector(ADDR_WIDTH-1 downto 0);
      addr_b : in std_logic_vector(ADDR_WIDTH-1 downto 0);
      data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);
      data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);
      we_a : in std_logic ;
      we_b : in std_logic ;
      q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);
      q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)
     );
end component;
--Inputs
signal clk :  std_logic :='0';
signal addr_a :  std_logic_vector(6-1 downto 0);
signal addr_b :  std_logic_vector(6-1 downto 0);
signal data_a :  std_logic_vector((8-1) downto 0);
signal data_b :  std_logic_vector((8-1) downto 0);
signal we_a :  std_logic ;
signal we_b :  std_logic ;
--Outputs
signal q_a :  std_logic_vector((8 -1) downto 0);
signal q_b :  std_logic_vector((8 -1) downto 0);
constant CLK_period : time := 5 ns;
constant ADDR_WIDTH : integer := 6;
constant DATA_WIDTH :integer :=8;
  type mem_type is array ((2**ADDR_WIDTH)-1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
  shared variable mem : mem_type;
begin
uut: dp_ram_rbw_scl port map (
clk=>clk,
addr_a=>addr_a,
addr_b =>addr_b,
data_a =>data_a,
data_b =>data_b,
we_a=>we_a,
we_b=>we_b,
q_a=>q_a,
q_b=>q_b
);
-- clock process definition
clk_process : process
begin
clk<= '1';
wait for 1 ns;
clk <= '0';
wait for 1 ns;
end process; 
--for A port we :=0
stim_proc :process
begin 
we_a <= '0';
addr_a <="000010";
data_a <="00000010";
q_a <= data_a;
wait for 1 ns;

addr_a <="000100";
data_a <="00000100";
q_a <=data_a;
wait for 1 ns;
addr_a <="001000";
data_a <="00001000";
q_a <=data_a;
wait for 1 ns;
addr_a <="010000";
data_a <="00010000";
q_a <=data_a;
wait for 1 ns;
addr_a <="100000";
data_a <="00100000";
q_a <=data_a;
wait for 1 ns;

--for A port we :=1
we_a <='1';
data_a <= "00100000";
addr_a <="000001";
q_a <= data_a;
wait for 1 ns;
addr_a <="000010";
data_a <= "00100000";
q_a <= data_a;
wait for 1 ns;
addr_a <="000100";
data_a <= "00100000";
wait for 1 ns;
q_a <= data_a;
addr_a <="001000";
data_a <= "00100000";
wait for 1 ns;
q_a <= data_a;
addr_a <="010000";wait for 1 ns;
data_a <= "00100000";

addr_a <="100000";
data_a <= "00100000";
q_a <= data_a;
wait for 1 ns;



end process;

 stim_proc1 :process
begin 
--for B port we :=0
we_b <= '0';

addr_b <="000010";
data_b <="00000010";
q_b <= data_b;
wait for 1 ns;

addr_b <="000100";
data_b <="00000100";
q_b <=data_b;
wait for 1 ns;
addr_b <="001000";
data_b <="00001000";
q_b <=data_b;
wait for 1 ns;
addr_b <="010000";
data_b <="00010000";
q_b <=data_b;
wait for 1 ns;
addr_b <="100000";
data_b <="00100000";
q_b <=data_b;
wait for 1 ns;

--for B port we :=1
we_b <='1';
data_b <= "00100000";
addr_b <="000001";
q_b <= data_b;
wait for 1 ns;
addr_b <="000010";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="000100";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="001000";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="010000";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;
addr_b <="100000";
data_b <= "00100000";
q_b <= data_b;
wait for 1 ns;



end process;
end;

Could you pls give me some hints or examples

Im simulate this code in ModelSim.and I see very strange diagrams.I dont understand why signal q_b change like this

Screen Shot 2016-07-13 at 11.46.55.png

Link to comment
Share on other sites

Your diagram is misleading, in that I rarely examine processes zoomed in that far.  You offer only one negative clock transition.  However, everything is changing on this negative transition.  Therefore, I suggest you take a closer look at how you are handling the clock.  Transitions on negative edges are usually a bad thing.

As a comparison, here's an example of a working VHDL memory.  Notice how the clocks are handled by "if rising_edge(clk_i)" rather than "if (clk'event and clk = '1)".

Dan

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...