Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to write VHDL test bench for INOUT Port ?

Status
Not open for further replies.

jerryvikram

Newbie level 3
Joined
Oct 28, 2010
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,335
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;
--------------------------------------------------------------------------
 

The problem i see is that you don't have a loop for the clock and you generate only one period.

try this

Code:
Clk_sig: process
begin
	for Z in 1 to 800000   -- period count
	loop
		T_Clock<='1'; -- clock cycle 10 ns
		wait for 5 ns;
		T_Clock<='0';
		wait for 5 ns;
	end  loop;
	wait;
end process;


Alex
 

The problem i see is that you don't have a loop for the clock and you generate only one period.

This is the clock loop:

Code:
Clk_sig: process
begin
  T_Clock<='1'; -- clock cycle 10 ns
  wait for 5 ns;
  T_Clock<='0';
  wait for 5 ns;
end process;

the problem you are having is you need to drive 'Z' onto your data bus when you're not writing to it in the testbench.

change:
T_Data <= T_Tx_Data when T_WriteEn='1';

to this:
T_Data <= T_Tx_Data when T_WriteEn='1' else (others => 'Z');
 

You are right , I thought I saw a wait at the end of the process , my mistake, sorry.

Alex
 

This is the clock loop:

Code:
Clk_sig: process
begin
  T_Clock<='1'; -- clock cycle 10 ns
  wait for 5 ns;
  T_Clock<='0';
  wait for 5 ns;
end process;

the problem you are having is you need to drive 'Z' onto your data bus when you're not writing to it in the testbench.

change:
T_Data <= T_Tx_Data when T_WriteEn='1';

to this:
T_Data <= T_Tx_Data when T_WriteEn='1' else (others => 'Z');


Actually I removed this entire line and it worked fine. Thanks for the replies guys...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top