Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Continuous Queue in VHDL?

Reply
Thread Tools

Continuous Queue in VHDL?

 
 
dcwang3 dcwang3 is offline
Junior Member
Join Date: Nov 2009
Posts: 8
 
      11-13-2009
Hey guys:

I'm trying to work on a code in VHDL that basically has a queue. I want the queue to retrieve data continuously. So basically once the queue is full, it will start to write over the old data (in the last spots). I would like to have pointers to tell me where the first and the last entry, and if there is a wrapback, to be able to keep those pointers synced and correct.

I guess I am having a hard time trying to figure out how to keep track of the pointers.

Can another give me some pointers or advice?

Thanks
 
Reply With Quote
 
 
 
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      11-13-2009
Take a look at this post: Must be what your looking for.

velocityreviews.com/forums/t703373-representing-the-buffer-with-logic-gates-flipflops.html
(copy the address to the browser) or look below your post in this group
 
Reply With Quote
 
 
 
 
dcwang3 dcwang3 is offline
Junior Member
Join Date: Nov 2009
Posts: 8
 
      11-17-2009
I looked at it and I am getting some ideas. I have written code. I am trying to make a generic code, so that I have generic variables at the top and can change the width and size of my QUEUE.

for instance:

Code:
ENTITY FIFO IS
	GENERIC(	SIZE:	INTEGER:= 16;
				WIDE:	INTEGER:= 4
		   );
	PORT( 
	           CLK,RESET,WRITE_EN,READ_EN:	IN STD_LOGIC;
                   DATA_IN: 	IN  STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
		   DATA_OUT:  OUT   STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
     		   QUEUE_EMPTY,QUEUE_FULL:   OUT  STD_LOGIC
	    );
END FIFO;

ARCHITECTURE BEHAVIOR OF FIFO IS

COMPONENT QUEUE_ARRAY 
	PORT(	WRITE_EN,CLK:	IN	STD_LOGIC;
			DATA_IN:	IN	STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
			DATA_OUT:	IN	STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
			ADDR:		IN	STD_LOGIC_VECTOR(CONV_STD_LOGIC(SIZE,4))
		);
END COMPONENT;

I don't think I am doing it correctly.

LIke I want ADDR signal in the component QUEUE_ARRAY be std_logic_vector in the code, but want to initialize it with an integer, so I can easily change it.

Any suggestions?

Thanks
 
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      11-17-2009
This will be a more correct start of your code.
You must use the conversion function inside QUEUE_ARRAY.

Code:
ENTITY FIFO IS
	GENERIC(	SIZE:	INTEGER:= 16;
				WIDE:	INTEGER:= 4
		   );
	PORT( 
	           CLK,RESET,WRITE_EN,READ_EN:	IN STD_LOGIC;
                   DATA_IN: 	IN  STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
		   DATA_OUT:  OUT   STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
     		   QUEUE_EMPTY,QUEUE_FULL:   OUT  STD_LOGIC
	    );
END FIFO;

ARCHITECTURE BEHAVIOR OF FIFO IS

COMPONENT QUEUE_ARRAY 
	PORT(	WRITE_EN,CLK:	IN	STD_LOGIC;
			DATA_IN:	IN	STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
			DATA_OUT:	OUT	STD_LOGIC_VECTOR(WIDE-1 DOWNTO 0);
			ADDR:		IN	STD_LOGIC_VECTOR(2**SIZE-1 DOWNTO 0);
END COMPONENT;
 
Reply With Quote
 
dcwang3 dcwang3 is offline
Junior Member
Join Date: Nov 2009
Posts: 8
 
      11-17-2009
what exactly does the 2**WIDE-1. Obviously it should turn out to be 3. What does ** do?

Thanks
 
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      11-17-2009
2**1 = 2
2**2 = 4
2**3 = 8 and so on ** means power of
2**4 = 16
so 2**SIZE-1 actually 15

UPS - sorry should be (SIZE-1 DOWNTO 0) in the code
 

Last edited by jeppe; 11-17-2009 at 01:58 PM..
Reply With Quote
 
dcwang3 dcwang3 is offline
Junior Member
Join Date: Nov 2009
Posts: 8
 
      11-18-2009
I need some help trying to figure out what is wrong with my code. I'm trying to make a continuous queue that will put data in until it is full, and then once it is full, it will overwrite the old data. I need a pointer at the start and the end of the queue. Can someone help me?

Code:
LIbrary IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

ENTITY FIFO_TEST IS
--	GENERIC(	SIZE:	INTEGER:= 16;
--				WIDE:	INTEGER:= 4
--		   );
	PORT( 
			CLK,RESET,WRITE_EN,READ_EN:		IN	STD_LOGIC;
		    DATA_IN: 						IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		    DATA_OUT: 						OUT	STD_LOGIC_VECTOR(3 DOWNTO 0);
     		ARRAY_COUNT:					OUT	STD_LOGIC_VECTOR(2 DOWNTO 0);
     		QUEUE_EMPTY,QUEUE_FULL:			OUT	STD_LOGIC;
			WRAP:							BUFFER	STD_LOGIC
	    );
END FIFO_TEST;

ARCHITECTURE BEHAVIOR OF FIFO_TEST IS

COMPONENT QUEUE_ARRAY 
	PORT(	WRITE_EN,CLK:	IN	STD_LOGIC;
			DATA_IN:	IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
			DATA_OUT:	OUT	STD_LOGIC_VECTOR(3 DOWNTO 0);
			ADDR:		IN	STD_LOGIC_VECTOR(2 DOWNTO 0)
		);
END COMPONENT;

SIGNAL START_POINTER:	STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL END_POINTER:		STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL COUNTER:			STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL WRITE_ENABLE_S:	STD_LOGIC;
SIGNAL ADDR_S:			STD_LOGIC_VECTOR(2 DOWNTO 0);
--SIGNAL WRAP:			STD_LOGIC;
SIGNAL QUEUE_FULL_S:	STD_LOGIC;
SIGNAL QUEUE_EMPTY_S:	STD_LOGIC;

BEGIN

    FifoRam : QUEUE_ARRAY
		PORT MAP(
					WRITE_EN    =>  WRITE_ENABLE_S,
					CLK         =>  CLK,
                    DATA_IN     =>  DATA_IN,
                    DATA_OUT    =>  DATA_OUT,
					ADDR        =>  START_POINTER
				);
	
	PROCESS(CLK,RESET)
	BEGIN
		IF (RESET = '1') THEN
			START_POINTER <= (OTHERS=>'0');
			END_POINTER <= (OTHERS=>'0');
			COUNTER  <= (OTHERS=>'0');
		ELSIF(RISING_EDGE(CLK)) THEN
			IF(WRITE_EN = '1' AND WRAP = '0' AND READ_EN = '0') THEN				
				IF(COUNTER = "11111111") THEN
					START_POINTER <= (OTHERS => '0');
					END_POINTER <= END_POINTER + 1;
					WRAP <= '1';
				ELSE
					START_POINTER <= START_POINTER + 1;
					COUNTER <= COUNTER + 1;
				END IF;
			END IF;
			
			IF(WRITE_EN = '1' AND WRAP ='1' AND READ_EN ='0') THEN
				IF(END_POINTER = "11111111") THEN
					END_POINTER <= (OTHERS => '0');	
				ELSIF(START_POINTER = "11111111") THEN
					START_POINTER <= (OTHERS =>'0');
				ELSE
					START_POINTER <= START_POINTER + 1;
					END_POINTER <= END_POINTER + 1;
				END IF;				
			END IF;

			IF(READ_EN = '1' AND WRITE_EN ='0') THEN	
				IF(START_POINTER = END_POINTER) THEN
					QUEUE_EMPTY_S <= '1';
				ELSE
					START_POINTER <= START_POINTER - 1;
					COUNTER <= COUNTER - 1;
				END IF;
				
				IF(COUNTER = 0) THEN
					QUEUE_EMPTY_S <= '1';
				ELSE
					QUEUE_EMPTY_S <= '0';
				END IF;
			END IF;				
		END IF;
	END PROCESS;
-----------------------------------------------------------
--  Combinatorial Logic
-----------------------------------------------------------
	ARRAY_COUNT <= COUNTER;
	
	WRAP <= '1' WHEN (COUNTER = "11111111") ELSE '0';

	QUEUE_FULL <= '1' WHEN  (COUNTER = "11111111") ELSE '0';
	QUEUE_EMPTY <= QUEUE_EMPTY_S;

	WRITE_ENABLE_S <= '1' WHEN (WRITE_EN = '1') ELSE '0';
	
	

------------------------------------------------------------
END BEHAVIOR;

Code:
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;


ENTITY QUEUE_ARRAY IS
	GENERIC(	LEN:	INTEGER:= 16;
				WIDE:	INTEGER:= 4
		   );
			
	PORT(	WRITE_EN,CLK:	IN	STD_LOGIC;
			DATA_IN:		IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
			DATA_OUT:		OUT	STD_LOGIC_VECTOR(3 DOWNTO 0);
			ADDR:			IN	STD_LOGIC_VECTOR(2 DOWNTO 0)
		);
END QUEUE_ARRAY;

ARCHITECTURE BEHAVIOR OF QUEUE_ARRAY IS
	TYPE QUEUE_SIZE IS ARRAY(7 DOWNTO 0) OF STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL QUEUE_ARRAY: QUEUE_SIZE;

BEGIN
	
PROCESS(CLK,QUEUE_ARRAY,ADDR)
BEGIN
	IF(RISING_EDGE(CLK)) THEN
		IF(WRITE_EN = '1') THEN
			QUEUE_ARRAY(CONV_INTEGER(ADDR)) <= DATA_IN;
		END IF;
	END IF;

DATA_OUT <= QUEUE_ARRAY(CONV_INTEGER(ADDR));

END PROCESS;

END BEHAVIOR;
 

Last edited by dcwang3; 11-18-2009 at 08:30 PM..
Reply With Quote
 
jeppe jeppe is offline
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 348
 
      11-18-2009
First must you realise - its not possible to drive the signal "WRAP" from both a process and from concurrent code.
Besides do you not need this I believe, as a VECTOR<= VECTOR+1 will wrap around automaticly.

Your code also miss a way to select among the START_POINTER and the END_POINTER. It seems that the START_POINTER connected permanently to the QUEUE_ARRAY.

My version would look like this (but OK - the RAM must be a DUAL-PORT type)

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity FIFO_TEST2 is
      generic (
            B : natural :=8; -- number of bit
            W: natural :=4 -- number of address bit
            );
      port ( clk, reset : in std_logic;
             rd, wr : in std_logic;
             w_data : in std_logic_vector ( B-1 downto 0);
             empty, full : inout std_logic;
             r_data : out std_logic_vector (B-1 downto 0));
end FIFO_TEST2;

architecture Behavioral of FIFO_TEST2 is
   type array_type is array (0 to 2**W-1) of std_logic_vector( B-1 downto 0);
   signal ringbuffer: array_type;
   signal w_index, r_index: std_logic_vector( W-1 downto 0);  --integer range 0 to 2**W-1;
   signal count:            std_logic_vector( W downto 0);
begin

   empty <= '1' when count=0    else '0';
   full  <= '1' when count=2**W else '0';
   r_data <= ringbuffer( conv_integer(r_index));
   
   process( clk)
      variable wr_edge, rd_edge: std_logic_vector( 1 downto 0) := "00";
   begin
      if rising_edge( clk) then
         if reset = '1' then
            w_index <= (others=>'0');
            r_index <= (others=>'0');
            count   <= (others=>'0');
            wr_edge := wr&wr;
            rd_edge := rd&rd;
         else
            if wr_edge="01" then 
               ringbuffer( conv_integer(w_index)) <= w_data;
               w_index <= w_index+1;
               if full='0' then
                  count   <= count+1;
               else
                  r_index <= r_index + 1; -- Remove oldest data
               end if;
            end if;
            if rd_edge="01" and empty='0' then
               r_index <= r_index+1;
               count <= count-1;
            end if;
            wr_edge := wr_edge(0) & wr;
            rd_edge := rd_edge(0) & rd;
         end if;
      end if;
   end process;
end Behavioral;
 
Reply With Quote
 
dcwang3 dcwang3 is offline
Junior Member
Join Date: Nov 2009
Posts: 8
 
      11-19-2009
I updated the code probably after you looked at it initially.

But the way I was trying to write my code was, that I would have a QUEUE of a a certain size (ie 16 entries). Then I would write continuously. If I write all the way up to the 16th entry and WRITE_EN is still '1', it would go back to the first entry and start filling over the old data.

I have the START_POINTER to point to the newest entry, and END_POINTER to the last old entry. I have the WRAP signal to fulfill the condition of if START = END. So in the beginning when it starts, I just want to increment the START_POINTER until it gets to the last entry, and if it fills up that 16th entry, for START_POINTER to go back to the first entry, and then END_POINTER increments to the second entry (because that is the oldest data entry).

I hope I am explaining it correctly?

I'll look over your code tonight and see how it works. Thanks for the help
 
Reply With Quote
 
dcwang3 dcwang3 is offline
Junior Member
Join Date: Nov 2009
Posts: 8
 
      11-19-2009
I'm looking at the code, what is the wr_edge and rd_edge for? especially in the reset part, with wr_edge:=wr&wr ; rd_edge:=rd&rd
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Program blocked in Queue.Queue.get and Queue.Queue.put Kris Python 0 01-04-2012 03:46 PM
why does the following with Queue, q.put('\x02', True) not put itin the queue? Gabriel Rossetti Python 3 04-25-2008 03:41 PM
Is Queue.Queue.queue.clear() thread-safe? Russell Warren Python 4 06-27-2006 03:03 PM
what's the difference between #include "queue.h" and #include "queue.cpp" Kceiw C++ 3 03-14-2006 03:01 AM
Queue.Queue-like class without the busy-wait Paul L. Du Bois Python 29 04-04-2005 01:28 PM



Advertisments