OpenCores
URL https://opencores.org/ocsvn/rv01_riscv_core/rv01_riscv_core/trunk

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_stack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2017 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------------
29
-- RV01 Stack
30
---------------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
 
36
library WORK;
37
use WORK.RV01_CONSTS_PKG.all;
38
use WORK.RV01_TYPES_PKG.all;
39
use WORK.RV01_ARITH_PKG.all;
40
 
41
entity RV01_STACK is
42
  generic(
43
    DEPTH : natural := 4;
44
    WIDTH : natural := 32
45
  );
46
  port(
47
    CLK_i : in std_logic;
48
    RST_i : in std_logic;
49
    CLR_i : in std_logic;
50
    PUSH_i : in std_logic;
51
    POP_i : in std_logic;
52
    D_i : in std_logic_vector(WIDTH-1 downto 0);
53
 
54
    SE_o : out std_logic;
55
    SF_o : out std_logic;
56
    Q_o : out std_logic_vector(WIDTH-1 downto 0)
57
  );
58
end RV01_STACK;
59
 
60
architecture ARC of RV01_STACK is
61
 
62
  subtype STACK_ENTRY_T is std_logic_vector(WIDTH-1 downto 0);
63
  type STACK_ENTRY_VEC_T is array (natural range<>) of STACK_ENTRY_T;
64
 
65
  signal TP : integer range -1 to DEPTH+1;
66
  signal TP_q : integer range 0 to DEPTH;
67
  signal Q,Q_q : STACK_ENTRY_VEC_T(DEPTH-1 downto 0);
68
  signal SE,SE_q : std_logic;
69
  signal SF,SF_q : std_logic;
70
 
71
begin
72
 
73
  ----------------------------------------------------
74
  -- Notes
75
  ----------------------------------------------------
76
 
77
  -- The Stack holds up to DEPTH entries, a new data
78
  -- word is added at the lowest empty entry when
79
  -- PUSH_i = '1', the oldest data word is removed
80
  -- from bottom entry when POP_i = '1' (shifting other
81
  -- entries down by one position).
82
  -- When the stack is empty, TP_q = 0.
83
  -- When the stack is full, TP_q = DEPTH.
84
  -- If PUSH_i = '1' when the stack if full, the bottom
85
  -- data word is discarded, and the new data word is
86
  -- stored into the top entry.
87
  -- If POP_i = '1' when the stack is empty, nothing
88
  -- happens.
89
  -- Stack supports push-ing and pop-ing in the same
90
  -- cycle (when this occurs, the tail pointer remains
91
  -- unchanged, unless stack is empty).
92
 
93
  ----------------------------------------------------
94
  -- Tail pointer
95
  ----------------------------------------------------
96
 
97
  -- The tail pointer always points at the stack lowest 
98
  -- empty entry.
99
 
100
  -- Tail pointer updating logic
101
 
102
  process(TP_q,PUSH_i,POP_i,SE_q,SF_q)
103
    variable TMP : std_logic_vector(4-1 downto 0);
104
  begin
105
    TMP := SE_q & SF_q & PUSH_i & POP_i;
106
    case TMP is
107
      -- regular case (stack is neither empty or full)
108
      when "0000" => TP <= TP_q;
109
      when "0001" => TP <= TP_q - 1;
110
      when "0010" => TP <= TP_q + 1;
111
      when "0011" => TP <= TP_q;
112
      -- stack full (PUSH discards bottom entry)
113
      when "0100" => TP <= TP_q;
114
      when "0101" => TP <= TP_q - 1;
115
      when "0110" => TP <= TP_q;
116
      when "0111" => TP <= TP_q;
117
      -- stack empty (POP is ignored)
118
      when "1000" => TP <= TP_q;
119
      when "1001" => TP <= TP_q;
120
      when "1010" => TP <= TP_q + 1;
121
      when "1011" => TP <= TP_q + 1;
122
      -- 
123
      when others => TP <= TP_q;
124
    end case;
125
 
126
  end process;
127
 
128
  -- Tail pointer register
129
 
130
  process(CLK_i)
131
  begin
132
    if(CLK_i = '1' and CLK_i'event) then
133
      if(RST_i = '1' or CLR_i = '1') then
134
        TP_q <= 0;
135
      else
136
        TP_q <= TP;
137
      end if;
138
    end if;
139
  end process;
140
 
141
  ----------------------------------------------------
142
  -- Stack empty flag register
143
  ----------------------------------------------------
144
 
145
  process(CLK_i)
146
  begin
147
    if(CLK_i = '1' and CLK_i'event) then
148
      if(RST_i = '1' or CLR_i = '1') then
149
        SE_q <= '0';
150
      elsif(
151
        (TP_q = 0 and PUSH_i = '0') or
152
        (TP_q = 1 and POP_i = '1')
153
      ) then
154
        SE_q <= '1';
155
      else
156
        SE_q <= '0';
157
      end if;
158
    end if;
159
  end process;
160
 
161
  ----------------------------------------------------
162
  -- Stack full flag register
163
  ----------------------------------------------------
164
 
165
  process(CLK_i)
166
  begin
167
    if(CLK_i = '1' and CLK_i'event) then
168
      if(RST_i = '1' or CLR_i = '1') then
169
        SF_q <= '0';
170
      elsif(
171
        (TP_q = DEPTH-1 and PUSH_i = '1') or
172
        (TP_q = DEPTH and POP_i = '0')
173
      ) then
174
        SF_q <= '1';
175
      else
176
        SF_q <= '0';
177
      end if;
178
    end if;
179
  end process;
180
 
181
  ----------------------------------------------------
182
  -- Stack data updating logic
183
  ----------------------------------------------------
184
 
185
  process(Q_q,SF_q,PUSH_i,POP_i,D_i)
186
  begin
187
    for k in DEPTH-1 downto 0 loop
188
      if(k = 0) then
189
        -- bottom entry
190
        if(PUSH_i = '1') then
191
          Q(k) <= D_i;
192
        elsif(POP_i = '1' and PUSH_i = '0') then
193
          Q(k) <= Q_q(k+1);
194
        else
195
          Q(k) <= Q_q(k);
196
        end if;
197
      elsif(k = DEPTH-1) then
198
        -- top entry
199
        if(PUSH_i = '1' and POP_i = '0') then
200
          Q(k) <= Q_q(k-1);
201
        else
202
          Q(k) <= Q_q(k);
203
        end if;
204
      else
205
        -- intermediate entry
206
        if(PUSH_i = '1' and POP_i = '0') then
207
          Q(k) <= Q_q(k-1);
208
        elsif(POP_i = '1' and PUSH_i = '0') then
209
          --Q(DEPTH-k-1) <= Q_q(DEPTH-k);
210
          Q(k) <= Q_q(k+1);
211
        else
212
          Q(k) <= Q_q(k);
213
        end if;
214
      end if;
215
    end loop;
216
  end process;
217
 
218
  ----------------------------------------------------
219
  -- Stack data registers
220
  ----------------------------------------------------
221
 
222
  process(CLK_i)
223
  begin
224
    if(CLK_i = '1' and CLK_i'event) then
225
      for k in 0 to DEPTH-1 loop
226
        Q_q(k) <= Q(k);
227
      end loop;
228
    end if;
229
  end process;
230
 
231
  ----------------------------------------------------
232
  -- Outputs
233
  ----------------------------------------------------
234
 
235
  Q_o <= Q_q(0);
236
 
237
  SE_o <= SE_q;
238
 
239
  SF_o <= SF_q;
240
 
241
end ARC;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.