jerryvikram
Newbie level 3
I wrote a RAM memory with Bidirectional Data... But when I wrote a small test bench i am not getting the proper Data out. Whats wrong here?
My code:
entity ram is
generic (
DATA_WIDTH :integer := 8;
ADDR_WIDTH :integer := 8
);
port (
clk :in std_logic; -- Clock Input
address :in std_logic_vector (ADDR_WIDTH-1 downto 0); -- address Input
data :inout std_logic_vector (DATA_WIDTH-1 downto 0); -- data bi-directional
cs :in std_logic; -- Chip Select
we :in std_logic; -- Write Enable/Read Enable
oe :in std_logic -- Output Enable
);
end entity;
architecture rtl of ram is
----------------Internal variables----------------
constant RAM_DEPTH :integer := 2**ADDR_WIDTH;
signal data_out :std_logic_vector (DATA_WIDTH-1 downto 0);
type RAM is array (integer range <>)of std_logic_vector (DATA_WIDTH-1 downto 0);
signal mem : RAM (0 to 255);
begin
----------------Code Starts Here------------------
-- Tri-State Buffer control
-- output : When we = 0, oe = 1, cs = 1
data <= data_out when (cs = '1' and oe = '1' and we = '0') else (others=>'Z');
-- Memory Write Block
-- Write Operation : When we = 1, cs = 1
MEM_WRITE:
process (clk) begin
if (rising_edge(clk)) then
if (cs = '1' and we = '1') then
mem(conv_integer(address)) <= data;
end if;
end if;
end process;
-- Memory Read Block
-- Read Operation : When we = 0, oe = 1, cs = 1
MEM_READ:
process (clk) begin
if (rising_edge(clk)) then
if (cs = '1' and we = '0' and oe = '1') then
data_out <= mem(conv_integer(address));
end if;
end if;
end process;
end architecture;
Test bench:
entity RAM_TB is
end RAM_TB;
architecture TB of RAM_TB is
component ram is
port (
clk :in std_logic; -- Clock Input
address :in std_logic_vector (7 downto 0); -- address Input
data :inout std_logic_vector (7 downto 0); -- data bi-directional
cs :in std_logic; -- Chip Select
we :in std_logic; -- Write Enable/Read Enable
oe :in std_logic -- Output Enable
);
end component;
signal T_Clock, T_Enable, T_WriteEn: std_logic;
signal T_Data,T_Tx_Data, T_Rx_Data: std_logic_vector(7 downto 0);
signal T_Address: std_logic_vector(7 downto 0);
signal T_OE: std_logic;
signal T_tag,T_Tx_Tag,T_Rx_Tag: std_logic_vector(12 downto 0);
begin
U_CKT: ram port map(T_Clock,
T_Address,
T_Data,
T_Enable,
T_WriteEn,
T_OE);
T_Data <= T_Tx_Data when T_WriteEn='1';
T_Rx_Data <= T_Data when T_WriteEn='0' and T_OE='1';
Clk_sig: process
begin
T_Clock<='1'; -- clock cycle 10 ns
wait for 5 ns;
T_Clock<='0';
wait for 5 ns;
end process;
process
variable err_cnt: integer := 0;
begin
T_Enable <= '0';
--T_WriteEn <= 'Z';
T_Address <= (T_Address'range => '0');
T_Tx_Data <= (T_Tx_Data'range => '0');
wait for 20 ns;
-- test write
T_Enable <= '1';
T_OE <= '0';
for i in 0 to 2 loop
T_Address <= T_Address + '1';
T_Tx_Data <= T_Tx_Data + '1';
T_WriteEn <= '1';
wait for 10ns;
end loop;
-- test read
T_Address <= "00000001";
T_WriteEn <= '0';
wait for 10 ns;
wait;
end process;
end TB;
--------------------------------------------------------------------------
configuration CFG_TB of RAM_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------
My code:
entity ram is
generic (
DATA_WIDTH :integer := 8;
ADDR_WIDTH :integer := 8
);
port (
clk :in std_logic; -- Clock Input
address :in std_logic_vector (ADDR_WIDTH-1 downto 0); -- address Input
data :inout std_logic_vector (DATA_WIDTH-1 downto 0); -- data bi-directional
cs :in std_logic; -- Chip Select
we :in std_logic; -- Write Enable/Read Enable
oe :in std_logic -- Output Enable
);
end entity;
architecture rtl of ram is
----------------Internal variables----------------
constant RAM_DEPTH :integer := 2**ADDR_WIDTH;
signal data_out :std_logic_vector (DATA_WIDTH-1 downto 0);
type RAM is array (integer range <>)of std_logic_vector (DATA_WIDTH-1 downto 0);
signal mem : RAM (0 to 255);
begin
----------------Code Starts Here------------------
-- Tri-State Buffer control
-- output : When we = 0, oe = 1, cs = 1
data <= data_out when (cs = '1' and oe = '1' and we = '0') else (others=>'Z');
-- Memory Write Block
-- Write Operation : When we = 1, cs = 1
MEM_WRITE:
process (clk) begin
if (rising_edge(clk)) then
if (cs = '1' and we = '1') then
mem(conv_integer(address)) <= data;
end if;
end if;
end process;
-- Memory Read Block
-- Read Operation : When we = 0, oe = 1, cs = 1
MEM_READ:
process (clk) begin
if (rising_edge(clk)) then
if (cs = '1' and we = '0' and oe = '1') then
data_out <= mem(conv_integer(address));
end if;
end if;
end process;
end architecture;
Test bench:
entity RAM_TB is
end RAM_TB;
architecture TB of RAM_TB is
component ram is
port (
clk :in std_logic; -- Clock Input
address :in std_logic_vector (7 downto 0); -- address Input
data :inout std_logic_vector (7 downto 0); -- data bi-directional
cs :in std_logic; -- Chip Select
we :in std_logic; -- Write Enable/Read Enable
oe :in std_logic -- Output Enable
);
end component;
signal T_Clock, T_Enable, T_WriteEn: std_logic;
signal T_Data,T_Tx_Data, T_Rx_Data: std_logic_vector(7 downto 0);
signal T_Address: std_logic_vector(7 downto 0);
signal T_OE: std_logic;
signal T_tag,T_Tx_Tag,T_Rx_Tag: std_logic_vector(12 downto 0);
begin
U_CKT: ram port map(T_Clock,
T_Address,
T_Data,
T_Enable,
T_WriteEn,
T_OE);
T_Data <= T_Tx_Data when T_WriteEn='1';
T_Rx_Data <= T_Data when T_WriteEn='0' and T_OE='1';
Clk_sig: process
begin
T_Clock<='1'; -- clock cycle 10 ns
wait for 5 ns;
T_Clock<='0';
wait for 5 ns;
end process;
process
variable err_cnt: integer := 0;
begin
T_Enable <= '0';
--T_WriteEn <= 'Z';
T_Address <= (T_Address'range => '0');
T_Tx_Data <= (T_Tx_Data'range => '0');
wait for 20 ns;
-- test write
T_Enable <= '1';
T_OE <= '0';
for i in 0 to 2 loop
T_Address <= T_Address + '1';
T_Tx_Data <= T_Tx_Data + '1';
T_WriteEn <= '1';
wait for 10ns;
end loop;
-- test read
T_Address <= "00000001";
T_WriteEn <= '0';
wait for 10 ns;
wait;
end process;
end TB;
--------------------------------------------------------------------------
configuration CFG_TB of RAM_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------