-
Notifications
You must be signed in to change notification settings - Fork 1
/
lifo.vhd
104 lines (85 loc) · 3.38 KB
/
lifo.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
--
-- Last-In-First-Out (LIFO
-- https://github.com/dominiksalvet/vhdl-collection/blob/master/rtl/lifo.vhdl
--
--------------------------------------------------------------------------------
-- Copyright (C) 2018 Dominik Salvet
-- SPDX-License-Identifier: MIT
--------------------------------------------------------------------------------
-- Compliant: IEEE Std 1076-1993
-- Target: independent
--------------------------------------------------------------------------------
-- Description:
-- This file represents a generic LIFO structure (also known as stack). It
-- is possible to setup it's capacity and stored data's bit width.
--------------------------------------------------------------------------------
-- Notes:
-- 1. If both write and read operations are enabled at the same time,
-- only write will be performed. In this case it is needed to be careful
-- when LIFO is full as write will be performed anyway.
-- 2. The final internal LIFO capacity is equal to 2^g_INDEX_WIDTH only. It
-- is not possible to choose another capacity.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lifo is
generic (
g_INDEX_WIDTH : positive := 2; -- internal index bit width affecting the LIFO capacity
g_DATA_WIDTH : positive := 8 -- bit width of stored data
);
port (
i_clk : in std_logic; -- clock signal
i_rst : in std_logic; -- reset signal
i_we : in std_logic; -- write enable (push)
i_data : in std_logic_vector(g_DATA_WIDTH - 1 downto 0); -- written data
o_full : out std_logic; -- full LIFO indicator
i_re : in std_logic; -- read enable (pop)
o_data : out std_logic_vector(g_DATA_WIDTH - 1 downto 0); -- read data
o_empty : out std_logic -- empty LIFO indicator
);
end entity lifo;
architecture rtl of lifo is
-- output buffers
signal b_full : std_logic;
signal b_empty : std_logic;
-- definition of internal memory type
type t_MEM is array(0 to integer((2 ** g_INDEX_WIDTH) - 1)) of
std_logic_vector(g_DATA_WIDTH - 1 downto 0);
signal r_mem : t_MEM; -- accessible internal memory signal
signal r_wr_index : unsigned(g_INDEX_WIDTH - 1 downto 0); -- current write index
signal w_rd_index : unsigned(g_INDEX_WIDTH - 1 downto 0); -- current read index
begin
o_full <= b_full;
o_empty <= b_empty;
w_rd_index <= r_wr_index - 1; -- read index is always less by 1 than write index
-- Description:
-- Internal memory read and write mechanism description.
mem_access : process (i_clk)
begin
if (rising_edge(i_clk)) then -- synchronous reset
if (i_rst = '1') then
b_full <= '0';
b_empty <= '1';
r_wr_index <= to_unsigned(0, r_wr_index'length);
else
if (i_we = '1') then -- write mechanism
-- the LIFO is never empty after write and no read
b_empty <= '0';
r_mem(to_integer(r_wr_index)) <= i_data;
r_wr_index <= r_wr_index + 1;
if (r_wr_index = (2 ** g_INDEX_WIDTH) - 1) then -- full LIFO check
b_full <= '1';
end if;
elsif (i_re = '1') then -- read mechanism
b_full <= '0'; -- the LIFO is never full after read and no write
o_data <= r_mem(to_integer(w_rd_index));
r_wr_index <= w_rd_index;
if (w_rd_index = 0) then -- empty LIFO check
b_empty <= '1';
end if;
end if;
end if;
end if;
end process mem_access;
end architecture rtl;