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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_bjxlog_bv.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 Branch/Jump eXecute & branch verificatio nLogic 
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_FUNCS_PKG.all;
40
use work.RV01_ARITH_PKG.all;
41
use work.RV01_OP_PKG.all;
42
 
43
entity RV01_BJXLOG_BV is
44
  generic(
45
    JRPE : std_logic := '1'
46
  );
47
  port(
48
    CLK_i : in std_logic;
49
    RST_i : in std_logic;
50
    BJ_OP_i : in BJ_OP_T;
51
    SU_i : in std_logic;
52
    PC_i : in ADR_T;
53
    OPA_i : in SDWORD_T;
54
    OPB_i : in SDWORD_T;
55
    IMM_i : in SDWORD_T;
56
    IV_i : in std_logic;
57
    FSTLL_i : in std_logic;
58
    -- verification port
59
    BPVD_i : std_logic_vector(3-1 downto 0);
60
    MPJRX_i : in std_logic;
61
 
62
    BJX_o : out std_logic;
63
    BJTA_o : out unsigned(ALEN-1 downto 0);
64
    -- verification port
65
    BHT_WE_o : out std_logic;
66
    BHT_TA_o : out ADR_T;
67
    BHT_PC_o : out ADR_T;
68
    BHT_CNT_o : out std_logic_vector(2-1 downto 0)
69
  );
70
end RV01_BJXLOG_BV;
71
 
72
architecture ARC of RV01_BJXLOG_BV is
73
 
74
  function updt_cnt(
75
    CNT : std_logic_vector(2-1 downto 0);
76
    TKN : std_logic
77
  ) return std_logic_vector is
78
    variable TMP : std_logic_vector(3-1 downto 0);
79
    variable UCNT : std_logic_vector(2-1 downto 0);
80
  begin
81
    TMP := CNT & TKN;
82
    case TMP is
83
      when "000" => UCNT := "11";
84
      when "001" => UCNT := "01";
85
      when "010" => UCNT := "00";
86
      when "011" => UCNT := "01";
87
      when "100" => UCNT := "10";
88
      when "101" => UCNT := "11";
89
      when "110" => UCNT := "10";
90
      when others => UCNT := "00";
91
    end case;
92
    return(UCNT);
93
  end function;
94
 
95
  signal BJX,BJX_q : std_logic;
96
  signal BX,JX,PBX,MPBX : std_logic;
97
  signal BP_HIT : std_logic;
98
  signal BP_CNT,BP_UCNT : std_logic_vector(2-1 downto 0);
99
  signal BJTA,BJTA_q : ADR_T;
100
  signal BJAL_TA,JALR_TA,PCP4 : ADR_T;
101
  signal OPB_N,SUB_RES : SDWORD_T;
102
  signal AEQB,ALTB : std_logic;
103
 
104
begin
105
 
106
  ---------------------------------------
107
  -- Notes
108
  ---------------------------------------
109
 
110
  -- This module performs branch and jal instructions
111
  -- prediction verification and jalr instructions
112
  -- executions. Jal instructions are treated as
113
  -- always-taken branches and are therefore
114
  -- assigned an entry in BHT. Jal instructions
115
  -- are surely mispredicted as not taken the first
116
  -- time they're encountered.
117
  -- Jalr instructions are not predicted at all
118
  -- and so no entry is assigned to them in BHT.
119
  -- If a branch/jal instruction is predicted correctly,
120
  -- it's treated as a nop, otherwise a branch is
121
  -- executed to the correct target address or to
122
  -- the address following the branch instruction
123
  -- itself.
124
  -- BHT is updated every time a valid branch/jal
125
  -- instruction reaches IX1 stage, regardless of
126
  -- prediction correctness.
127
 
128
  ---------------------------------------
129
  -- Branch/Jump execution
130
  ---------------------------------------
131
 
132
  -- Calculate B/J target addresses
133
 
134
  process(OPA_i,PC_i,IMM_i)
135
    variable IOPA,IPC,IIMM : signed(SDLEN downto 0);
136
    variable TA0,TA1 : signed(SDLEN downto 0);
137
  begin
138
 
139
    -- sign-extend OPA_i by one bit
140
    if(OPA_i >= 0) then
141
      IOPA := '0' & OPA_i;
142
    else
143
      IOPA := '1' & OPA_i;
144
    end if;
145
 
146
    -- sign-extend IMM_i by one bit
147
    if(IMM_i >= 0) then
148
      IIMM := '0' & IMM_i;
149
    else
150
      IIMM := '1' & IMM_i;
151
    end if;
152
 
153
    -- sign-extend PC_i by one bit
154
    IPC := '0' & to_signed(PC_i);
155
 
156
    -- Note: there's no timing benefit from
157
    -- replacing these adders with carry-select
158
    -- ones.
159
 
160
    TA0 := IOPA + IIMM;
161
 
162
    TA1 := IPC + IIMM;
163
 
164
    -- Jalr target address
165
    JALR_TA <= to_unsigned(TA0(SDLEN-1 downto 0));
166
 
167
    -- branch/jal target address
168
    BJAL_TA <= to_unsigned(TA1(SDLEN-1 downto 0));
169
 
170
  end process;
171
 
172
  -- Address of instruction following the branch/jal
173
  PCP4 <= PC_i + 4;
174
 
175
  -- Select address to branch at in case of
176
  -- misprediction
177
 
178
  process(BX,JX,MPJRX_i,BJX_q,PCP4,BJAL_TA,JALR_TA,BJTA_q)
179
  begin
180
    if(BX = '1' and BJX_q = '0') then
181
      BJTA <= BJAL_TA;
182
    elsif((JX = '1' or MPJRX_i = '1') and BJX_q = '0') then
183
      BJTA <= JALR_TA(SDLEN-1 downto 1) & '0' ;
184
    elsif(BJX_q = '0') then
185
      BJTA <= PCP4;
186
    else
187
      BJTA <= BJTA_q;
188
    end if;
189
  end process;
190
 
191
  ------------------------------------
192
  -- Calculate OPA_i - OPB_i (for blt* and bge*)
193
  ------------------------------------
194
 
195
  SUB_RES <= OPA_i - OPB_i;
196
 
197
  ------------------------------------
198
  -- Branch control flags
199
  ------------------------------------
200
 
201
  -- OPA_i less-than OPB_i flag
202
  AEQB <= '1' when (OPA_i = OPB_i) else '0';
203
 
204
  -- if OPA > 0 and OPB > 0, then ALTB = sign(SUB_RES)
205
  -- if OPA < 0 and OPB < 0, then ALTB = sign(SUB_RES)
206
  -- if OPA > 0 and OPB < 0, then ALTB = '0'
207
  -- if OPA < 0 and OPB > 0, then ALTB = '1'
208
 
209
  -- OPA_i less-than OPB_i flag
210
  ALTB <=
211
    SUB_RES(SDLEN-1) when (OPA_i(SDLEN-1) = OPB_i(SDLEN-1)) else
212
    OPA_i(SDLEN-1) when (SU_i = '1') else
213
    OPB_i(SDLEN-1) ;
214
 
215
  ------------------------------------
216
  -- Set branch and jal execute flag
217
  ------------------------------------
218
 
219
  process(BJ_OP_i,AEQB,ALTB,IV_i)
220
  begin
221
 
222
    if(ALTB = '1') then
223
 
224
      case BJ_OP_i is
225
 
226
        when BJ_BEQ =>
227
          BX <= AEQB and IV_i;
228
 
229
        when BJ_BNE =>
230
          BX <= not(AEQB) and IV_i;
231
 
232
        when BJ_BLT =>
233
          BX <= IV_i;
234
 
235
        when BJ_BGE =>
236
          BX <= '0';
237
 
238
        when BJ_JAL =>
239
          BX <= IV_i;
240
 
241
        when others =>
242
          BX <= '0';
243
 
244
      end case;
245
 
246
    else
247
 
248
      case BJ_OP_i is
249
 
250
        when BJ_BEQ =>
251
          BX <= AEQB and IV_i;
252
 
253
        when BJ_BNE =>
254
          BX <= not(AEQB) and IV_i;
255
 
256
        when BJ_BLT =>
257
          BX <= '0';
258
 
259
        when BJ_BGE =>
260
          BX <= IV_i;
261
 
262
        when BJ_JAL =>
263
          BX <= IV_i;
264
 
265
        when others =>
266
          BX <= '0';
267
 
268
      end case;
269
 
270
    end if;
271
  end process;
272
 
273
  ------------------------------------
274
  -- Set jalr execute flag
275
  ------------------------------------
276
 
277
  GJRPE0_1 : if(JRPE = '1') generate
278
 
279
  JX <= '0';
280
 
281
  end generate;
282
 
283
  GJRPE0_0 : if(JRPE = '0') generate
284
 
285
  JX <= IV_i when (BJ_OP_i = BJ_JALR) else '0';
286
 
287
  end generate;
288
 
289
  ------------------------------------
290
  -- Set B/J execute flag
291
  ------------------------------------
292
 
293
  BJX <= (MPBX or JX);
294
 
295
  -- B/J execute flag and target address register.
296
  -- These registers are needed when a B/J is taken
297
  -- while fetch is stalled: in such condition B/J
298
  -- must deferred to first un-stalled cycle.
299
 
300
  process(CLK_i)
301
  begin
302
    if(CLK_i = '1' and CLK_i'event) then
303
      if(FSTLL_i = '1') then
304
        BJTA_q <= BJTA;
305
      end if;
306
      if(RST_i = '1' or FSTLL_i = '0') then
307
        BJX_q <= '0';
308
      elsif(FSTLL_i = '1') then
309
        BJX_q <= (BJX and IV_i);
310
      end if;
311
    end if;
312
  end process;
313
 
314
  -- A branch/jump is actually executed if:
315
  -- 1) there's a valid B/J instruction in IX1 stage, OR
316
  -- 2) there's a pending B/J.
317
 
318
  BJX_o <= BJX or BJX_q;
319
 
320
  BJTA_o <= BJTA;
321
 
322
  ---------------------------------------
323
  -- Branch verification
324
  ---------------------------------------
325
 
326
  -- branch prediction hit flag
327
  BP_HIT <= BPVD_i(0);
328
 
329
  -- branch prediction count
330
  BP_CNT <= BPVD_i(3-1 downto 1);
331
 
332
  -- branch prediction updated count
333
  BP_UCNT <= updt_cnt(BP_CNT,BX) when BP_HIT = '1' else (not(BX) & not(BX));
334
 
335
  -- predicted branch execute flag
336
  -- (1 -> predicted taken, 0 -> predicted not taken)
337
 
338
  PBX <= BP_HIT and not(BP_CNT(1)) and IV_i;
339
 
340
  -- branch mis-prediction flag
341
  MPBX <= (PBX xor BX) or MPJRX_i;
342
 
343
  -- BHT updated data
344
 
345
  BHT_WE_o <= IV_i when(
346
    BJ_OP_i = BJ_BEQ or
347
    BJ_OP_i = BJ_BNE or
348
    BJ_OP_i = BJ_BLT or
349
    BJ_OP_i = BJ_BGE or
350
    BJ_OP_i = BJ_JAL
351
  ) else '0';
352
 
353
  BHT_CNT_o <= BP_UCNT;
354
 
355
  BHT_TA_o <= JALR_TA when (BJ_OP_i = BJ_JALR) else BJAL_TA;
356
 
357
  BHT_PC_o <= PC_i;
358
 
359
end ARC;

powered by: WebSVN 2.1.0

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