new to vhdl

V

Vandana

Guest
Hello All,
Im learning vhdl since the past 2 days and I have attempted to make a
4x4 RAM module. When I simulate the code, there are certain aspects of
the simulation that I dont understand and I could do with some help.

My questions are the following:

1. Currently, in my code once i set the we(write_enable) or the
re(read_enable) on I dont turn it off. the reason being, if i set them
to 0 after the read/write operation, I dont see the desired data. So
the we/re remains on even after the operation is complete. how to
avoid this?

2. In cycles 45 -55 ns, I get undefined value in dout, after 55 ns, I
again see the desired value. what is the reason for this?

3. This is the second testbench/vhdl code, so I have idea about the
quality. Is it a very poor testbench?

I have attached the code below.
Thank you for your time.
Vandana.

Code is attached:
ram.vhdl
------------------------------------------
entity ram is
port (
clk : in std_logic;
rst : in std_logic;
re : in std_logic;
we : in std_logic;
write_addr : in std_logic_vector(1 downto 0);
read_addr : in std_logic_vector(1 downto 0);
din : in std_logic_vector(3 downto 0);
dout : out std_logic_vector(3 downto 0)
);
end entity ram;

architecture behav of ram is
type ram_type is array (3 downto 0) of std_logic_vector(3 downto 0);
signal ram_block : ram_type;

begin -- behav
read_ram : process(clk,rst,re)
begin
if(clk'event and clk='1') then
if (re = '1') then
dout <= ram_block(to_integer(unsigned(read_addr)));
else
dout <= (others=> '0');
end if;
end if;
end process read_ram;

write_ram: process(clk, rst,we)
begin
if(clk'event and clk='1') then
if ( we = '1') then
ram_block(to_integer(unsigned(write_addr))) <= din;
end if;
end if;
end process write_ram;

end behav;

--------------------------------
ram_tb.vhdl
-----------------------------

ENTITY ram_tb IS
END ram_tb;

ARCHITECTURE behavior OF ram_tb IS

-- Component Declaration for the Unit Under Test (UUT)
COMPONENT ram
PORT(
clk : IN std_logic;
rst : IN std_logic;
re : IN std_logic;
we : IN std_logic;
write_addr : IN std_logic_vector(1 downto 0);
read_addr : IN std_logic_vector(1 downto 0);
din : IN std_logic_vector(3 downto 0);
dout : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;

--Inputs
SIGNAL clk : std_logic := '0';
SIGNAL rst : std_logic := '1';
SIGNAL re : std_logic := '0';
SIGNAL we : std_logic := '0';
SIGNAL write_addr : std_logic_vector(1 downto 0) :=
(others=>'0');
SIGNAL read_addr : std_logic_vector(1 downto 0) := (others=>'0');
SIGNAL din : std_logic_vector(3 downto 0) := (others=>'0');

--Outputs
SIGNAL dout : std_logic_vector(3 downto 0);

BEGIN

-- Instantiate the Unit Under Test (UUT)
dut: ram PORT MAP(
clk => clk,
rst => rst,
re => re,
we => we,
write_addr => write_addr,
read_addr => read_addr,
din => din,
dout => dout
);

clk_gen: process
begin
wait for 5 ns;
clk <= not clk;
end process clk_gen;

rst_gen: process
begin
wait for 30 ns;
rst <= '0';
end process rst_gen;

write_ram: process(clk,rst, we)
begin
if (clk'event and clk ='1') then
if (rst = '1') then
we <= '0';
else
we <= '1';
write_addr <= "10";
din <= "0011";
end if;
end if;
end process write_ram;

read_ram: process(clk,rst,re)
begin
if (clk'event and clk = '1') then
if (rst = '1') then
re <= '0';
else
re <= '1';
read_addr <= "10";
end if;
end if;
end process read_ram;

END;
 
Vandana wrote:

1. Currently, in my code once i set the we(write_enable) or the
re(read_enable) on I dont turn it off. the reason being, if i set them
to 0 after the read/write operation, I dont see the desired data. So
the we/re remains on even after the operation is complete. how to
avoid this?
Write to the ram before you read it.

2. In cycles 45 -55 ns, I get undefined value in dout, after 55 ns, I
again see the desired value. what is the reason for this?
You are reading before the write is finished.

3. This is the second testbench/vhdl code, so I have idea about the
quality. Is it a very poor testbench?
It compiled and ran. Not bad for two days of work.

To avoid errors like this I prefer a sequential test process.
See my testbench example here.
http://mysite.verizon.net/miketreseler/

-- Mike Treseler
 
I think Mike pointed out all the problems, I thought Id now just get a
little picky with the code :)

You are using clock'event and clk = 1, for your rising edge triggers.
VHDL93 adds two functions "rising_edge(clk)" and "falling_edge(clk)"
that function exactly the same but I think make the code a little more
readable.

write_ram: process(clk,rst, we)
begin
if (clk'event and clk ='1') then
You only need to put "clk" in the sensitivity list here, because
output only change on clock events. In a large design, this may slow a
simulation down as it is triggering processes unnessarily.

rst_gen: process
begin
wait for 30 ns;
rst <= '0';
end process rst_gen;
In this process, rst is being assigned to '0' every 30ns. This will
probably not cause a problem, but it does make "rst'transaction" go
high for that single delta. Personally, I would put "wait;" after "rst
<= '0';" to halt the process;
 
On Jun 27, 4:12 am, Tricky <Trickyh...@gmail.com> wrote:
rst_gen: process
 begin
      wait for 30 ns;
     rst <= '0';
 end process rst_gen;

In this process, rst is being assigned to '0' every 30ns. This will
probably not cause a problem, but it does make "rst'transaction" go
high for that single delta. Personally, I would put "wait;" after "rst
Or simply...

rst <= '1', '0' after 30 ns;

KJ
 
On Jun 27, 7:52 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Jun 27, 4:12 am, Tricky <Trickyh...@gmail.com> wrote:



rst_gen: process
begin
wait for 30 ns;
rst <= '0';
end process rst_gen;

In this process, rst is being assigned to '0' every 30ns. This will
probably not cause a problem, but it does make "rst'transaction" go
high for that single delta. Personally, I would put "wait;" after "rst

Or simply...

rst <= '1', '0' after 30 ns;

KJ

@Mike. I initialized the ram array, then I was able to get rid of the
undefined values. The waveforms look better, but I doubt if
the array initialization is synthesizable.
Thanks for pointing out to your code snippets, they will be of help.

@Tricky, @KJ: I actually intended to use the wait to halt the process
not to make rst go high after every 30 ns. Thanks for pointing it
out.

Thanks,
Vandana
 

Welcome to EDABoard.com

Sponsor

Back
Top