1 |
2 |
madsilicon |
-----------------------------------------------------------------
|
2 |
|
|
-- --
|
3 |
|
|
-----------------------------------------------------------------
|
4 |
|
|
-- --
|
5 |
|
|
-- Copyright (C) 2015 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 Exception processing logic
|
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_OP_PKG.all;
|
40 |
|
|
use work.RV01_IDEC_PKG.all;
|
41 |
|
|
use work.RV01_CSR_PKG.all;
|
42 |
|
|
|
43 |
|
|
entity RV01_EXCPLOG_IX3 is
|
44 |
|
|
generic(
|
45 |
|
|
NW : natural := 2
|
46 |
|
|
);
|
47 |
|
|
port(
|
48 |
|
|
V_i : in std_logic_vector(NW-1 downto 0); -- slot #0,1 valid flag
|
49 |
|
|
EV_i : in std_logic_vector(NW-1 downto 0); -- slot #0,1 valid flag
|
50 |
|
|
INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0); -- slot #0/1 inst.
|
51 |
|
|
PC0_i : in ADR_T; -- slot #0 pc
|
52 |
|
|
PC1_i : in ADR_T; -- slot #1 pc
|
53 |
|
|
DADR0_i : in ADR_T; -- slot #0 L/S addr.
|
54 |
|
|
DADR1_i : in ADR_T; -- slot #1 L/S addr.
|
55 |
|
|
HALT_i : in std_logic; -- halt flag
|
56 |
|
|
HIS_i : in std_logic; -- debug halt instruction selector
|
57 |
|
|
|
58 |
|
|
|
59 |
|
|
EXCP_o : out std_logic; -- exc. flag
|
60 |
|
|
ERET_o : out std_logic; -- return from exc. flag
|
61 |
|
|
RFTCH_o : out std_logic; -- re-fetch flag
|
62 |
|
|
KPRD_o : out std_logic_vector(NW-1 downto 0); -- slot #0/1 keep pipe reg. data flag
|
63 |
|
|
CLRP_o : out std_logic; -- clear pipe flag
|
64 |
|
|
CLRB_o : out std_logic; -- clear store buffer flag
|
65 |
|
|
CLRD_o : out std_logic; -- clear divider flag
|
66 |
|
|
EPC_o : out ADR_T; -- exc. pc
|
67 |
|
|
ECAUSE_o : out std_logic_vector(5-1 downto 0); -- exc. cause
|
68 |
|
|
EDADR_o : out ADR_T -- exc. L/S addr.
|
69 |
|
|
);
|
70 |
|
|
end RV01_EXCPLOG_IX3;
|
71 |
|
|
|
72 |
|
|
architecture ARC of RV01_EXCPLOG_IX3 is
|
73 |
|
|
|
74 |
|
|
signal EXCP : std_logic;
|
75 |
|
|
signal ERET : std_logic;
|
76 |
|
|
signal RFTCH : std_logic;
|
77 |
|
|
signal EIS : std_logic;
|
78 |
|
|
signal DIV_REM : std_logic;
|
79 |
|
|
|
80 |
|
|
begin
|
81 |
|
|
|
82 |
|
|
------------------------------------
|
83 |
|
|
-- Notes
|
84 |
|
|
------------------------------------
|
85 |
|
|
|
86 |
|
|
-- This modules generates most part of signals
|
87 |
|
|
-- associated with re-fetching and exception
|
88 |
|
|
-- processing. Such signals are generated in
|
89 |
|
|
-- stage IX3 to insure that all instructions
|
90 |
|
|
-- older than the one requiring re-fetching or
|
91 |
|
|
-- raising an exception have complete their
|
92 |
|
|
-- execution.
|
93 |
|
|
|
94 |
|
|
-- Exception are raised and re-fetching started
|
95 |
|
|
-- only when store buffer is empty of pending
|
96 |
|
|
-- store (which are older than the instructions
|
97 |
|
|
-- in stage IX3) and fetching is not stalled
|
98 |
|
|
-- (to insure change of program flow doesn't get
|
99 |
|
|
-- "ignored" because there's no room for new
|
100 |
|
|
-- instructions in fetch queue).
|
101 |
|
|
|
102 |
|
|
-- When an exception is raised or an instruction
|
103 |
|
|
-- is re-fetched all instructions in the pipeline
|
104 |
|
|
-- are invalidated and store buffer is cleared of
|
105 |
|
|
-- pending store requests.
|
106 |
|
|
-- Divider is also reset (aborting possibly ongoing
|
107 |
|
|
-- operations) in case of exception or re-fetching,
|
108 |
|
|
-- unless re-fetching is triggered by the same
|
109 |
|
|
-- division instruction which is under processing.
|
110 |
|
|
|
111 |
|
|
-- EV_i flags are asserted only for instruction
|
112 |
|
|
-- raising an exception. Instruction eret is not
|
113 |
|
|
-- treated an exception-raising instruction and
|
114 |
|
|
-- therefore its valid bit is provided by V_i.
|
115 |
|
|
|
116 |
|
|
-- Exception flag
|
117 |
|
|
EXCP <= (
|
118 |
|
|
(EV_i(0) and INSTR_i(0).EXCP) or
|
119 |
|
|
(EV_i(1) and INSTR_i(1).EXCP)
|
120 |
|
|
) and not(HALT_i);
|
121 |
|
|
|
122 |
|
|
-- Exception is actually raised only when store buffer
|
123 |
|
|
-- is empty because pending stores are older than
|
124 |
|
|
-- instructions in IX3.
|
125 |
|
|
|
126 |
|
|
EXCP_o <= EXCP;
|
127 |
|
|
|
128 |
|
|
-- Return from exception flag
|
129 |
|
|
ERET <= V_i(0) when (
|
130 |
|
|
(INSTR_i(0).IMNMC = IM_ERET) and
|
131 |
|
|
HALT_i = '0'
|
132 |
|
|
) else '0';
|
133 |
|
|
|
134 |
|
|
-- Return from exception can take place only when
|
135 |
|
|
-- store buffer is empty because pending stores are
|
136 |
|
|
-- older than instructions in IX3.
|
137 |
|
|
|
138 |
|
|
ERET_o <= ERET;
|
139 |
|
|
|
140 |
|
|
-- Re-fetch flag
|
141 |
|
|
RFTCH <= (
|
142 |
|
|
(EV_i(0) and INSTR_i(0).RFTCH) or
|
143 |
|
|
(EV_i(1) and INSTR_i(1).RFTCH)
|
144 |
|
|
) and not(HALT_i);
|
145 |
|
|
|
146 |
|
|
-- Re-fetching can take place only when
|
147 |
|
|
-- store buffer is empty because pending stores are
|
148 |
|
|
-- older than instructions in IX3.
|
149 |
|
|
|
150 |
|
|
RFTCH_o <= RFTCH;
|
151 |
|
|
|
152 |
|
|
-- IX3 instructions must be kept in pipe registers
|
153 |
|
|
-- until store buffer is empty (to be deleted).
|
154 |
|
|
|
155 |
|
|
KPRD_o(0) <= '0';
|
156 |
|
|
|
157 |
|
|
KPRD_o(1) <= '0';
|
158 |
|
|
|
159 |
|
|
-- clear pipe flag
|
160 |
|
|
CLRP_o <= EXCP or ERET or RFTCH;
|
161 |
|
|
|
162 |
|
|
-- clear store buffer flag
|
163 |
|
|
CLRB_o <= (EXCP or ERET or RFTCH);
|
164 |
|
|
|
165 |
|
|
-- instruction #0 division/reminder flag
|
166 |
|
|
|
167 |
|
|
DIV_REM <= '1' when (
|
168 |
|
|
(INSTR_i(0).ALU_OP = ALU_DIV) or
|
169 |
|
|
(INSTR_i(0).ALU_OP = ALU_REM)
|
170 |
|
|
) else '0';
|
171 |
|
|
|
172 |
|
|
-- clear divider flag
|
173 |
|
|
|
174 |
|
|
-- a possible division operation in progress must be stopped
|
175 |
|
|
-- (resetting divider) in case exception, return from exception
|
176 |
|
|
-- or re-fetching occurs, unless the re-fetching is triggered
|
177 |
|
|
-- by a division instruction.
|
178 |
|
|
|
179 |
|
|
CLRD_o <= '1' when (
|
180 |
|
|
EXCP = '1' or
|
181 |
|
|
ERET = '1' or
|
182 |
|
|
(EV_i(0) = '1' and INSTR_i(0).RFTCH = '1' and DIV_REM = '0') or
|
183 |
|
|
(EV_i(1) = '1' and INSTR_i(1).RFTCH = '1' and INSTR_i(0).RFTCH = '0')
|
184 |
|
|
)else '0';
|
185 |
|
|
|
186 |
|
|
-- Exception instruction selector
|
187 |
|
|
EIS <= HIS_i when (HALT_i = '1') else not(EV_i(0) and INSTR_i(0).EXCP);
|
188 |
|
|
|
189 |
|
|
-- Exception PC
|
190 |
|
|
EPC_o <=
|
191 |
|
|
PC0_i when (EIS = '0') else
|
192 |
|
|
PC1_i;
|
193 |
|
|
|
194 |
|
|
-- Exception cause
|
195 |
|
|
ECAUSE_o <=
|
196 |
|
|
INSTR_i(0).ECAUSE when (EIS = '0') else
|
197 |
|
|
INSTR_i(1).ECAUSE;
|
198 |
|
|
|
199 |
|
|
-- Exception L/S address (aka the "bad addr")
|
200 |
|
|
EDADR_o <=
|
201 |
|
|
DADR0_i when (EIS = '0') else
|
202 |
|
|
DADR1_i;
|
203 |
|
|
|
204 |
|
|
end ARC;
|