From f4d72942b0553d99508ac89e1cd5aa4ce0171e9b Mon Sep 17 00:00:00 2001 From: tmeissner Date: Thu, 13 Nov 2014 21:08:47 +0100 Subject: [PATCH] initial commit of simple queue design file & testbench --- sim/QueueP.vhd | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ test/Makefile | 17 +++++++++ test/QueueT.vhd | 56 +++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 sim/QueueP.vhd create mode 100644 test/Makefile create mode 100644 test/QueueT.vhd diff --git a/sim/QueueP.vhd b/sim/QueueP.vhd new file mode 100644 index 0000000..1c7d1ad --- /dev/null +++ b/sim/QueueP.vhd @@ -0,0 +1,93 @@ +-- simple queue protected type +-- inspired by noasic article http://noasic.com/blog/a-simple-fifo-using-vhdl-protected-types/ + + +library ieee; + use ieee.std_logic_1164.all; + + + +package QueueP is + + + type t_simple_queue is protected + + procedure push (data : in std_logic_vector); + procedure pop (data : out std_logic_vector); + impure function is_empty return boolean; + impure function is_full return boolean; + impure function fillstate return natural; + impure function freeslots return natural; + + end protected t_simple_queue; + + +end package QueueP; + + + +package body QueueP is + + + type t_simple_queue is protected body + + constant C_QUEUE_DEPTH : natural := 64; + constant C_QUEUE_WIDTH : natural := 64; + + type t_queue_array is array (0 to C_QUEUE_DEPTH-1) of std_logic_vector(C_QUEUE_WIDTH-1 downto 0); + + variable v_queue : t_queue_array := (others => (others => '0')); + variable v_count : natural range 0 to t_queue_array'length := 0; + variable v_head : natural range 0 to t_queue_array'high := 0; + variable v_tail : natural range 0 to t_queue_array'high := 0; + + -- write one entry into queue + procedure push (data : in std_logic_vector) is + begin + assert not(is_full) + report "push into full queue -> discarded" + severity failure; + v_queue(v_head) := data; + v_head := (v_head + 1) mod t_queue_array'length; + v_count := v_count + 1; + end procedure push; + + -- read one entry from queue + procedure pop (data : out std_logic_vector) is + begin + assert not(is_empty) + report "pop from empty queue -> discarded" + severity failure; + data := v_queue(v_tail); + v_tail := (v_tail + 1) mod t_queue_array'length; + v_count := v_count - 1; + end procedure pop; + + -- returns true if queue is empty, false otherwise + impure function is_empty return boolean is + begin + return v_count = 0; + end function is_empty; + + -- returns true if queue is full, false otherwise + impure function is_full return boolean is + begin + return v_count = t_queue_array'length; + end function is_full; + + -- returns number of filled slots in queue + impure function fillstate return natural is + begin + return v_count; + end function fillstate; + + -- returns number of free slots in queue + impure function freeslots return natural is + begin + return t_queue_array'length - v_count; + end function freeslots; + + end protected body t_simple_queue; + + +end package body QueueP; \ No newline at end of file diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..af7c95a --- /dev/null +++ b/test/Makefile @@ -0,0 +1,17 @@ +SIM_SRC = ../sim +VHD_STD = 02 + +.PHONY: sim +sim: queuet + +queuet : QueueT.vhd $(SIM_SRC)/QueueP.vhd + ghdl -a --std=$(VHD_STD) $(SIM_SRC)/QueueP.vhd QueueT.vhd + ghdl -e --std=$(VHD_STD) QueueT + ghdl -r --std=$(VHD_STD) QueueT + + +.PHONY: clean +clean: + rm -f *.o + rm -f *.cf + rm -f queuet diff --git a/test/QueueT.vhd b/test/QueueT.vhd new file mode 100644 index 0000000..c646a22 --- /dev/null +++ b/test/QueueT.vhd @@ -0,0 +1,56 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + + + +entity QueueT is +end entity QueueT; + + + +architecture sim of QueueT is + + + shared variable sv_queue : work.QueueP.t_simple_queue; + + +begin + + + QueueTestP : process is + variable v_data : std_logic_vector(63 downto 0); + variable v_count : natural := 0; + begin + -- check initial emptiness + assert sv_queue.is_empty + report "ERROR: queue should be empty!" + severity failure; + for i in 0 to 63 loop + sv_queue.push(std_logic_vector(to_unsigned(v_count, 64))); + v_count := v_count + 1; + end loop; + -- check that it's full + assert sv_queue.is_full + report "ERROR: queue should be full!" + severity failure; + -- empty the queue + v_count := 0; + for i in 0 to 63 loop + sv_queue.pop(v_data); + assert v_data = std_logic_vector(to_unsigned(v_count, 64)) + report "ERROR: read data should be " & integer'image(v_count) & + " instead of " & integer'image(to_integer(unsigned(v_data))) + severity failure; + v_count := v_count + 1; + end loop; + -- check emptiness + assert sv_queue.is_empty + report "ERROR: queue should be empty!" + severity failure; + report "INFO: Test finished successfully"; + wait; + end process QueueTestP; + + +end architecture sim; \ No newline at end of file