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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_sysc_plugin/] [riverlib/] [core/] [br_predic.cpp] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Branch Predictor.
6
 * @details    This module gives about 5% of performance improvement (CPI)
7
 */
8
 
9
#include "br_predic.h"
10
 
11
namespace debugger {
12
 
13
BranchPredictor::BranchPredictor(sc_module_name name_) : sc_module(name_) {
14
    SC_METHOD(comb);
15
    sensitive << i_nrst;
16
    sensitive << i_req_mem_fire;
17
    sensitive << i_resp_mem_valid;
18
    sensitive << i_resp_mem_addr;
19
    sensitive << i_resp_mem_data;
20
    sensitive << i_f_predic_miss;
21
    sensitive << i_e_npc;
22
    sensitive << i_ra;
23
    sensitive << r.npc;
24
 
25
    SC_METHOD(registers);
26
    sensitive << i_clk.pos();
27
};
28
 
29
void BranchPredictor::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
30
    if (o_vcd) {
31
        sc_trace(o_vcd, i_req_mem_fire, "/top/proc0/bp0/i_req_mem_fire");
32
        sc_trace(o_vcd, i_resp_mem_valid, "/top/proc0/bp0/i_resp_mem_valid");
33
        sc_trace(o_vcd, i_resp_mem_addr, "/top/proc0/bp0/i_resp_mem_addr");
34
        sc_trace(o_vcd, i_resp_mem_data, "/top/proc0/bp0/i_resp_mem_data");
35
        sc_trace(o_vcd, i_f_predic_miss, "/top/proc0/bp0/i_f_predic_miss");
36
        sc_trace(o_vcd, i_e_npc, "/top/proc0/bp0/i_e_npc");
37
        sc_trace(o_vcd, i_ra, "/top/proc0/bp0/i_ra");
38
 
39
        sc_trace(o_vcd, o_npc_predict, "/top/proc0/bp0/o_npc_predict");
40
        sc_trace(o_vcd, r.npc, "/top/proc0/bp0/r_npc");
41
    }
42
}
43
 
44
void BranchPredictor::comb() {
45
    v = r;
46
    sc_uint<32> wb_tmp;
47
    sc_uint<BUS_ADDR_WIDTH> wb_npc;
48
    sc_uint<BUS_ADDR_WIDTH> wb_off;
49
 
50
    wb_tmp = i_resp_mem_data.read();
51
    if (i_f_predic_miss.read()) {
52
        wb_npc = i_e_npc.read() + 4;
53
    } else {
54
        wb_npc = r.npc.read() + 4;
55
    }
56
 
57
 
58
    if (wb_tmp[31]) {
59
        wb_off(BUS_ADDR_WIDTH-1, 20) = ~0;
60
    } else {
61
        wb_off(BUS_ADDR_WIDTH-1, 20) = 0;
62
    }
63
    wb_off(19, 12) = wb_tmp(19, 12);
64
    wb_off[11] = wb_tmp[20];
65
    wb_off(10, 1) = wb_tmp(30, 21);
66
    wb_off[0] = 0;
67
 
68
    if (i_resp_mem_valid.read()) {
69
        if (wb_tmp == 0x00008067) {
70
            // ret pseudo-instruction: Dhry score 34816 -> 35136
71
            v.npc = i_ra.read()(BUS_ADDR_WIDTH-1, 0);
72
        } else if (wb_tmp(6, 0) == 0x6f) {
73
            // jal instruction: Dhry score 35136 -> 36992
74
            v.npc = i_resp_mem_addr.read() + wb_off;
75
        } else if (i_req_mem_fire.read()) {
76
            v.npc = wb_npc;
77
        }
78
    } else if (i_req_mem_fire.read()) {
79
        v.npc = wb_npc;
80
    }
81
 
82
    if (!i_nrst.read()) {
83
        v.npc = RESET_VECTOR;
84
    }
85
 
86
    o_npc_predict = r.npc;
87
}
88
 
89
void BranchPredictor::registers() {
90
    r = v;
91
}
92
 
93
}  // namespace debugger
94
 

powered by: WebSVN 2.1.0

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