Arrays in VHDL

A

Ann

Guest
I am trying to covert the following Verilog code to VHDL. I am having
issues with converting the arrays to VHDL. Could you please comment on
how this should be done
module FIFO16x8(DataOut, DataIn, FF, AF, HF, AE, EF, Push, Pop, Dump,
Clk);
parameter WIDTH = 8;
parameter DEPTH = 16;
parameter LOG2DEPTH = 4;

input [(WIDTH-1):0] DataIn;
output [(WIDTH-1):0] DataOut;
output FF, AF, HF, AE, EF;
input Push, Pop, Dump, Clk;

wire WE, RE;

reg [(LOG2DEPTH-1):0] Contents, ReadPointer, WritePointer;
reg [(WIDTH-1):0] queue[(DEPTH-1):0];

assign FF = (Contents == (DEPTH-1))? 1 : 0;
assign AF = (Contents > (DEPTH-3))? 1 : 0;
assign HF = (Contents > (DEPTH/2))? 1 : 0;
assign AE = (Contents < 3)? 1 : 0;
assign EF = (Contents == 0)? 1 : 0;

assign WE = Push && ~FF;
assign RE = Pop && ~EF;

assign DataOut = queue[ReadPointer];

always @ (posedge Clk)
begin
if (Dump == 1)
Contents <= 0;
else
if ((WE == 1) && (RE == 0))
Contents <= Contents + 1;
else
if ((WE == 0) && (RE == 1))
Contents <= Contents - 1;
else
Contents <= Contents;
end

always @ (posedge Clk)
begin
if (Dump == 1)
begin
ReadPointer <= 0;
WritePointer <= 0;
end
else
begin
if (RE == 1)
begin
ReadPointer <= ReadPointer + 1;
end
if (WE == 1)
begin
queue[WritePointer] <= DataIn;
WritePointer <= WritePointer + 1;
end
end
end

endmodule


I have declared an array in VHDL as follows
TYPE queue IS ARRAY (7 DOWNTO 0, 15 DOWNTO 0)
OF std_logic_vector(7 downto 0);

I am not sure about how to convert the Verilog statements belwo to
VHDL. Verilog code is referenced above.
assign DataOut = queue[ReadPointer];
and
queue[WritePointer] <= DataIn;

thanks
Anuja
 
Try this. Please check this thoroughly before using it...

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer :
std_logic_vector(LOG2DEPTH-1 downto 0);
type fifo_type is array(DEPTH-1 downto 0) of std_logic_vector(WIDTH-1
downto 0);
signal queue : fifo_type;
signal WE, RE : std_logic;
signal full_flag, almost_full, half_flag, almost_empty, empty_flag :
std_logic;
begin

full_flag <= '1' when (Contents =
std_logic_vector(to_unsigned((DEPTH-1), Contents'Length))) else '0';
almost_full <= '1' when (Contents =
std_logic_vector(to_unsigned((DEPTH-3), Contents'Length))) else '0';
half_flag <= '1' when (Contents = std_logic_vector(to_unsigned((DEPTH/
2), Contents'Length))) else '0';
almost_empty <= '1' when (Contents < std_logic_vector(to_unsigned(3,
Contents'Length))) else '0';
empty_flag <= '1' when (Contents = std_logic_vector(to_unsigned(0,
Contents'Length))) else '0';

FF <= full_flag;
AF <= almost_full;
HF <= half_flag;
AE <= almost_empty;
EF <= empty_flag;
WE <= Push and (not full_flag);
RE <= Pop and (not empty_flag);

DataOut <= queue(to_integer(unsigned(ReadPointer)));

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= std_logic_vector(unsigned(Contents) + 1);
elsif ((WE='0') and (RE='1')) then
Contents <= std_logic_vector(unsigned(Contents) - 1);
end if;
end if;
end process;

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
WritePointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= std_logic_vector(unsigned(ReadPointer) + 1);
elsif (WE='1') then
queue(to_integer(unsigned(WritePointer))) <= DataIn;
WritePointer <= std_logic_vector(unsigned(WritePointer) + 1);
end if;
end if;
end process;

end architecture rtl;

Regards,
JK
 
Try this.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer : unsigned(LOG2DEPTH-1
downto 0);
type fifo_type is array(DEPTH-1 downto 0) of unsigned(WIDTH-1 downto
0);
signal queue : fifo_type;
signal WE, RE : std_ulogic;
signal full_flag, almost_full, half_flag, almost_empty, empty_flag :
std_ulogic;
begin

full_flag <= '1' when (Contents = (DEPTH-1)) else '0';
almost_full <= '1' when (Contents = (DEPTH-3)) else '0';
half_flag <= '1' when (Contents = (DEPTH/2)) else '0';
almost_empty <= '1' when (Contents < 3) else '0';
empty_flag <= '1' when (Contents = 0) else '0';

FF <= full_flag;
AF <= almost_full;
HF <= half_flag;
AE <= almost_empty;
EF <= empty_flag;
WE <= Push and (not full_flag);
RE <= Pop and (not empty_flag);

DataOut <= std_logic_vector(queue(to_integer(ReadPointer)));

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= Contents + 1;
elsif ((WE='0') and (RE='1')) then
Contents <= Contents - 1;
end if;
end if;
end process;

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
WritePointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= ReadPointer + 1;
elsif (WE='1') then
queue(to_integer(WritePointer)) <= unsigned(DataIn);
WritePointer <= WritePointer + 1;
end if;
end if;
end process;

end architecture rtl;

Regards,
JK
 
On Dec 18, 4:35 am, JK <krishna.januman...@gmail.com> wrote:
Try this.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer : unsigned(LOG2DEPTH-1
downto 0);
type fifo_type is array(DEPTH-1 downto 0) of unsigned(WIDTH-1 downto
0);
signal queue : fifo_type;
signal WE, RE : std_ulogic;
signal full_flag, almost_full, half_flag, almost_empty, empty_flag :
std_ulogic;
begin

full_flag <= '1' when (Contents = (DEPTH-1)) else '0';
almost_full <= '1' when (Contents = (DEPTH-3)) else '0';
half_flag <= '1' when (Contents = (DEPTH/2)) else '0';
almost_empty <= '1' when (Contents < 3) else '0';
empty_flag <= '1' when (Contents = 0) else '0';

FF <= full_flag;
AF <= almost_full;
HF <= half_flag;
AE <= almost_empty;
EF <= empty_flag;
WE <= Push and (not full_flag);
RE <= Pop and (not empty_flag);

DataOut <= std_logic_vector(queue(to_integer(ReadPointer)));

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= Contents + 1;
elsif ((WE='0') and (RE='1')) then
Contents <= Contents - 1;
end if;
end if;
end process;

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
WritePointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= ReadPointer + 1;
elsif (WE='1') then
queue(to_integer(WritePointer)) <= unsigned(DataIn);
WritePointer <= WritePointer + 1;
end if;
end if;
end process;

end architecture rtl;

Regards,
JK
Note there are errors in operation when simultaneous reads and writes
are attempted, and in the behavior of the HF and AF flags in this vhdl
description.

Why use unsigned for the data type in queue? There is no numerical
connotation to the data, only the pointers.

Andy
 
On Dec 19, 9:46 am, Andy <jonesa...@comcast.net> wrote:
On Dec 18, 4:35 am, JK <krishna.januman...@gmail.com> wrote:





Try this.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer : unsigned(LOG2DEPTH-1
downto 0);
type fifo_type is array(DEPTH-1 downto 0) of unsigned(WIDTH-1 downto
0);
signal queue : fifo_type;
signal WE, RE : std_ulogic;
signal full_flag, almost_full, half_flag, almost_empty, empty_flag :
std_ulogic;
begin

full_flag <= '1' when (Contents = (DEPTH-1)) else '0';
almost_full <= '1' when (Contents = (DEPTH-3)) else '0';
half_flag <= '1' when (Contents = (DEPTH/2)) else '0';
almost_empty <= '1' when (Contents < 3) else '0';
empty_flag <= '1' when (Contents = 0) else '0';

FF <= full_flag;
AF <= almost_full;
HF <= half_flag;
AE <= almost_empty;
EF <= empty_flag;
WE <= Push and (not full_flag);
RE <= Pop and (not empty_flag);

DataOut <= std_logic_vector(queue(to_integer(ReadPointer)));

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= Contents + 1;
elsif ((WE='0') and (RE='1')) then
Contents <= Contents - 1;
end if;
end if;
end process;

process(clk)
begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
WritePointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= ReadPointer + 1;
elsif (WE='1') then
queue(to_integer(WritePointer)) <= unsigned(DataIn);
WritePointer <= WritePointer + 1;
end if;
end if;
end process;

end architecture rtl;

Regards,
JK

Note there are errors in operation when simultaneous reads and writes
are attempted, and in the behavior of the HF and AF flags in this vhdl
description.

Why use unsigned for the data type in queue? There is no numerical
connotation to the data, only the pointers.

Andy- Hide quoted text -

- Show quoted text -
I am getting some errors as Andy said. When i simulate the design, I
am loosing the very first byte at Write Pointer = 0001. When Read
Pointer = 0001, instead of reading DataIn which we provided when Write
Pointer = 0001, it starts reading the dataIn when writepointer = 0010.
I am not sure why this is happening. I have paseted the test bench
below. Please help

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY tb_FIFO16x8 IS

END tb_FIFO16x8;

ARCHITECTURE tb OF tb_FIFO16x8 IS

-- temporary signals
SIGNAL clk_temp : std_logic := '0' ;
SIGNAL
Push_temp,Pop_temp,Dump_temp,FF_temp,AF_temp,HF_temp,AE_temp,EF_temp:std_logic;
SIGNAL DataIn_temp,DataOut_temp : std_logic_vector(7 DOWNTO 0);

-- component declaration
COMPONENT FIFO16x8 is
GENERIC (
WIDTH : integer := 8;
DEPTH : integer := 16;
LOG2DEPTH : integer := 4
);
PORT(
clk : IN std_logic ;
Push,Pop,Dump : IN std_logic ;
DataIn : IN std_logic_vector((WIDTH-1) DOWNTO
0);
FF, AF, HF, AE, EF : OUT std_logic;
DataOut : OUT std_logic_vector((WIDTH-1) DOWNTO
0)
);
END COMPONENT;

BEGIN
UUT : FIFO16x8
PORT MAP(
clk => clk_temp,
Push => Push_temp,
Pop => Pop_temp,
Dump => Dump_temp,
DataIn => DataIn_temp,
FF => FF_temp,
AF => AF_temp,
HF => HF_temp,
AE => AE_temp,
EF => EF_temp

);

-- apply inputs to monitor output
clk_temp <= (NOT clk_temp) AFTER 5 ns;

Push_temp <= '0' AFTER 0 ns,'1' AFTER 15 ns,'0' AFTER
160 ns;

Pop_temp <= '0' AFTER 5 ns,'1' AFTER 160 ns;

Dump_temp <= '1' AFTER 0 ns, '0' AFTER 10 ns, '1'
AFTER 300 ns;

DataIn_temp <= "10101111" AFTER 0 ns,"11111111" AFTER
10 ns,
"11110000" AFTER 20 ns,"10101010" AFTER
30 ns,
"00001100" AFTER 40 ns,"11001100" AFTER
50 ns,
"00000001" AFTER 60 ns,"00000010" AFTER
70 ns,
"00000011" AFTER 80 ns,"00000100" AFTER
90 ns,
"00000101" AFTER 100 ns,"10110111"
AFTER 110 ns,
"00001100" AFTER 120 ns,"11001100"
AFTER 130 ns,
"00000001" AFTER 140 ns,"00000010"
AFTER 150 ns,
"00000011" AFTER 160 ns,"00000100"
AFTER 170 ns;
END tb; -- test bench ends
 
On Dec 19, 7:46 pm, Andy <jonesa...@comcast.net> wrote:
Note there are errors in operation when simultaneous reads and writes
are attempted,
I seperated read & write processes for simulatneous operations.
I cannot utilize fifo fully(while writing, location: 15 and while
reading, location: 0).

and in the behavior of the HF and AF flags in this vhdl
description.
I didnt understood this point to fix. Could you please explain?

Why use unsigned for the data type in queue? There is no numerical
connotation to the data, only the pointers.
Yes, correct. Tha data in fifo can be signed/unsigned.
I modified the data type of queue to std_logic_vector.

Andy- Hide quoted text -

- Show quoted text -
Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer : unsigned(LOG2DEPTH-1
downto 0);
type fifo_type is array(0 to DEPTH-1) of std_logic_vector(WIDTH-1
downto 0);
signal queue : fifo_type;
signal WE, RE : std_ulogic;
signal fifo_full, almost_full, half_full, almost_empty, empty_fifo :
std_ulogic;
begin

fifo_full <= '1' when (Contents = (DEPTH-1)) else '0';
almost_full <= '1' when (Contents = (DEPTH-3)) else '0';
half_full <= '1' when (Contents = (DEPTH/2)) else '0';
almost_empty <= '1' when (Contents < 3) else '0';
empty_fifo <= '1' when (Contents = 0) else '0';

FF <= fifo_full;
AF <= almost_full;
HF <= half_full;
AE <= almost_empty;
EF <= empty_fifo;

WE <= Push and (not fifo_full);
RE <= Pop and (not empty_fifo);

process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= Contents + 1;
elsif ((WE='0') and (RE='1')) then
Contents <= Contents - 1;
end if;
end if;
end process;

-- Read Process
process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= ReadPointer + 1;
end if;
end if;
end process;
DataOut <= queue(to_integer(ReadPointer));

-- Write Process
process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
WritePointer <= (others => '0');
elsif (WE='1') then
queue(to_integer(WritePointer)) <= DataIn;
WritePointer <= WritePointer + 1;
end if;
end if;
end process;

end architecture rtl;

simple testbench:

Clk <= not Clk;

process begin
Dump <= '1'; wait for 100 ns;
Dump <= '0';

--write
Push <= '1'; Pop <= '0';
DataIn <= X"10"; wait for 10 ns;
DataIn <= X"20"; wait for 10 ns;
DataIn <= X"30"; wait for 10 ns;
DataIn <= X"40"; wait for 10 ns;
DataIn <= X"50"; wait for 10 ns;
DataIn <= X"60"; wait for 10 ns;
DataIn <= X"70"; wait for 10 ns;
DataIn <= X"80"; wait for 10 ns;
DataIn <= X"90"; wait for 10 ns;
DataIn <= X"A0"; wait for 10 ns;
DataIn <= X"B0"; wait for 10 ns;
DataIn <= X"C0"; wait for 10 ns;
DataIn <= X"D0"; wait for 10 ns;
DataIn <= X"E0"; wait for 10 ns;
DataIn <= X"F0"; wait for 10 ns;
DataIn <= X"FF"; wait for 10 ns;

--read
Pop <= '1'; Push <= '0';
wait for 160 ns;

--simultaneous read/write
Push <= '1'; Pop <= '1';
DataIn <= X"DD"; wait for 10 ns;

wait;
end process;

Regards,
JK
 
On Dec 20, 1:56 am, JK <krishna.januman...@gmail.com> wrote:
On Dec 19, 7:46 pm, Andy <jonesa...@comcast.net> wrote:



Note there are errors in operation when simultaneous reads and writes
are attempted,

I seperated read & write processes for simulatneous operations.
I cannot utilize fifo fully(while writing, location: 15 and while
reading, location: 0).

and in the behavior of the HF and AF flags in this vhdl
description.

I didnt understood this point to fix. Could you please explain?

Why use unsigned for the data type in queue? There is no numerical
connotation to the data, only the pointers.

Yes, correct. Tha data in fifo can be signed/unsigned.
I modified the data type of queue to std_logic_vector.



Andy- Hide quoted text -

- Show quoted text -

Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer : unsigned(LOG2DEPTH-1
downto 0);
type fifo_type is array(0 to DEPTH-1) of std_logic_vector(WIDTH-1
downto 0);
signal queue : fifo_type;
signal WE, RE : std_ulogic;
signal fifo_full, almost_full, half_full, almost_empty, empty_fifo :
std_ulogic;
begin

fifo_full <= '1' when (Contents = (DEPTH-1)) else '0';
almost_full <= '1' when (Contents = (DEPTH-3)) else '0';
half_full <= '1' when (Contents = (DEPTH/2)) else '0';
almost_empty <= '1' when (Contents < 3) else '0';
empty_fifo <= '1' when (Contents = 0) else '0';

FF <= fifo_full;
AF <= almost_full;
HF <= half_full;
AE <= almost_empty;
EF <= empty_fifo;

WE <= Push and (not fifo_full);
RE <= Pop and (not empty_fifo);

process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= Contents + 1;
elsif ((WE='0') and (RE='1')) then
Contents <= Contents - 1;
end if;
end if;
end process;

-- Read Process
process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= ReadPointer + 1;
end if;
end if;
end process;
DataOut <= queue(to_integer(ReadPointer));

-- Write Process
process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
WritePointer <= (others => '0');
elsif (WE='1') then
queue(to_integer(WritePointer)) <= DataIn;
WritePointer <= WritePointer + 1;
end if;
end if;
end process;

end architecture rtl;

simple testbench:

Clk <= not Clk;

process begin
Dump <= '1'; wait for 100 ns;
Dump <= '0';

--write
Push <= '1'; Pop <= '0';
DataIn <= X"10"; wait for 10 ns;
DataIn <= X"20"; wait for 10 ns;
DataIn <= X"30"; wait for 10 ns;
DataIn <= X"40"; wait for 10 ns;
DataIn <= X"50"; wait for 10 ns;
DataIn <= X"60"; wait for 10 ns;
DataIn <= X"70"; wait for 10 ns;
DataIn <= X"80"; wait for 10 ns;
DataIn <= X"90"; wait for 10 ns;
DataIn <= X"A0"; wait for 10 ns;
DataIn <= X"B0"; wait for 10 ns;
DataIn <= X"C0"; wait for 10 ns;
DataIn <= X"D0"; wait for 10 ns;
DataIn <= X"E0"; wait for 10 ns;
DataIn <= X"F0"; wait for 10 ns;
DataIn <= X"FF"; wait for 10 ns;

--read
Pop <= '1'; Push <= '0';
wait for 160 ns;

--simultaneous read/write
Push <= '1'; Pop <= '1';
DataIn <= X"DD"; wait for 10 ns;

wait;
end process;

Regards,
JK
Thanks a bunch guys. I appreciate your help. I would be stuck at this
point forever if you guys did not help.
 
On Dec 20, 1:56 am, JK <krishna.januman...@gmail.com> wrote:
On Dec 19, 7:46 pm, Andy <jonesa...@comcast.net> wrote:



Note there are errors in operation when simultaneous reads and writes
are attempted,

I seperated read & write processes for simulatneous operations.
I cannot utilize fifo fully(while writing, location: 15 and while
reading, location: 0).

and in the behavior of the HF and AF flags in this vhdl
description.

I didnt understood this point to fix. Could you please explain?

Why use unsigned for the data type in queue? There is no numerical
connotation to the data, only the pointers.

Yes, correct. Tha data in fifo can be signed/unsigned.
I modified the data type of queue to std_logic_vector.



Andy- Hide quoted text -

- Show quoted text -

Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FIFO16x8 is
generic (
WIDTH: integer := 8;
DEPTH: integer := 16;
LOG2DEPTH: integer := 4
);
port (
DataIn : in std_logic_vector(WIDTH-1 downto 0);
Push, Pop, Dump, Clk : in std_logic;
DataOut: out std_logic_vector(WIDTH-1 downto 0);
FF, AF, HF, AE, EF: out std_logic
);
end entity FIFO16x8;

architecture rtl of FIFO16x8 is
signal Contents, ReadPointer, WritePointer : unsigned(LOG2DEPTH-1
downto 0);
type fifo_type is array(0 to DEPTH-1) of std_logic_vector(WIDTH-1
downto 0);
signal queue : fifo_type;
signal WE, RE : std_ulogic;
signal fifo_full, almost_full, half_full, almost_empty, empty_fifo :
std_ulogic;
begin

fifo_full <= '1' when (Contents = (DEPTH-1)) else '0';
almost_full <= '1' when (Contents = (DEPTH-3)) else '0';
half_full <= '1' when (Contents = (DEPTH/2)) else '0';
almost_empty <= '1' when (Contents < 3) else '0';
empty_fifo <= '1' when (Contents = 0) else '0';

FF <= fifo_full;
AF <= almost_full;
HF <= half_full;
AE <= almost_empty;
EF <= empty_fifo;

WE <= Push and (not fifo_full);
RE <= Pop and (not empty_fifo);

process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
Contents <= (others => '0');
elsif ((WE='1') and (RE='0')) then
Contents <= Contents + 1;
elsif ((WE='0') and (RE='1')) then
Contents <= Contents - 1;
end if;
end if;
end process;

-- Read Process
process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
ReadPointer <= (others => '0');
elsif (RE='1') then
ReadPointer <= ReadPointer + 1;
end if;
end if;
end process;
DataOut <= queue(to_integer(ReadPointer));

-- Write Process
process(clk) begin
if rising_edge(clk) then
if (Dump='1') then
WritePointer <= (others => '0');
elsif (WE='1') then
queue(to_integer(WritePointer)) <= DataIn;
WritePointer <= WritePointer + 1;
end if;
end if;
end process;

end architecture rtl;

simple testbench:

Clk <= not Clk;

process begin
Dump <= '1'; wait for 100 ns;
Dump <= '0';

--write
Push <= '1'; Pop <= '0';
DataIn <= X"10"; wait for 10 ns;
DataIn <= X"20"; wait for 10 ns;
DataIn <= X"30"; wait for 10 ns;
DataIn <= X"40"; wait for 10 ns;
DataIn <= X"50"; wait for 10 ns;
DataIn <= X"60"; wait for 10 ns;
DataIn <= X"70"; wait for 10 ns;
DataIn <= X"80"; wait for 10 ns;
DataIn <= X"90"; wait for 10 ns;
DataIn <= X"A0"; wait for 10 ns;
DataIn <= X"B0"; wait for 10 ns;
DataIn <= X"C0"; wait for 10 ns;
DataIn <= X"D0"; wait for 10 ns;
DataIn <= X"E0"; wait for 10 ns;
DataIn <= X"F0"; wait for 10 ns;
DataIn <= X"FF"; wait for 10 ns;

--read
Pop <= '1'; Push <= '0';
wait for 160 ns;

--simultaneous read/write
Push <= '1'; Pop <= '1';
DataIn <= X"DD"; wait for 10 ns;

wait;
end process;

Regards,
JK
Are there errors in opertation of the Verilog code as well when we try
to simultaneously read and write? Or are the "if then else statements"
in the 2nd always block run simultaneously bcoz of the use of Non-
Blocking statements so that we can read and write at the same time.
 
On Dec 21, 1:15 am, Ann <thakkar.an...@gmail.com> wrote:
Are there errors in opertation of the Verilog code as well when we try
to simultaneously read and write? Or are the "if then else statements"
in the 2nd always block run simultaneously bcoz of the use of Non-
Blocking statements so that we can read and write at the same time.- Hide quoted text -

- Show quoted text -
I guess Verilog code doesnt have errors in simultaneous read & write
operations.

Not becaause of non-blocking statements, but because of 2 if
statements under else condition in second always block. If dump is
high, else part will be ignored. And if dump is not high, both RE and
WE will be checked.

Where as in VHDL code (1st one), I represented this with one if-elsif
condition. This will create a priority encoder kind of thing. If all
Dump, RE and WE are high, Dump is first priority and rest of elsif
statement ignored. And if Dump is not high, both WE & RE are high;
then RE will be considered, rest of elsif statement ignored.

Regards,
JK
 
Ann wrote:

There are simulation problems in the design when we write seperate
processes for read and write
Here's a related example:
http://home.comcast.net/~mike_treseler/sync_fifo.vhd
It may not do what you want, but it does work.

-- Mike Treseler
 
On Dec 20, 8:14 pm, JK <krishna.januman...@gmail.com> wrote:
On Dec 21, 1:15 am, Ann <thakkar.an...@gmail.com> wrote:



Are there errors in opertation of the Verilog code as well when we try
to simultaneously read and write? Or are the "if then else statements"
in the 2nd always block run simultaneously bcoz of the use of Non-
Blocking statements so that we can read and write at the same time.- Hide quoted text -

- Show quoted text -

I guess Verilog code doesnt have errors in simultaneous read & write
operations.

Not becaause of non-blocking statements, but because of 2 if
statements under else condition in second always block. If dump is
high, else part will be ignored. And if dump is not high, both RE and
WE will be checked.

Where as in VHDL code (1st one), I represented this with one if-elsif
condition. This will create a priority encoder kind of thing. If all
Dump, RE and WE are high, Dump is first priority and rest of elsif
statement ignored. And if Dump is not high, both WE & RE are high;
then RE will be considered, rest of elsif statement ignored.

Regards,
JK
There are simulation problems in the design when we write seperate
processes for read and write
 
On Dec 20 2007, 12:56 am, JK <krishna.januman...@gmail.com> wrote:
On Dec 19, 7:46 pm, Andy <jonesa...@comcast.net> wrote:
and in the behavior of the HF and AF flags in this vhdl
description.

I didnt understood this point to fix. Could you please explain?
Sorry; been out of touch for the holidays...

The HF and AF flags are only asserted when the contents equal the
threshold, not when they exceed it.

Instead of an "=" comparison, they should have either a ">" or a ">="
comparison against the thresholds.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top