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/] [fetch.cpp] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      CPU Fetch Instruction stage.
6
 */
7
 
8
#include "fetch.h"
9
 
10
namespace debugger {
11
 
12
InstrFetch::InstrFetch(sc_module_name name_) : sc_module(name_) {
13
    SC_METHOD(comb);
14
    sensitive << i_nrst;
15
    sensitive << i_pipeline_hold;
16
    sensitive << i_mem_req_ready;
17
    sensitive << i_mem_data_addr;
18
    sensitive << i_mem_data_valid;
19
    sensitive << i_mem_data;
20
    sensitive << i_e_npc;
21
    sensitive << i_predict_npc;
22
    sensitive << i_br_fetch_valid;
23
    sensitive << i_br_address_fetch;
24
    sensitive << i_br_instr_fetch;
25
    sensitive << r.pc_z1;
26
    sensitive << r.raddr_not_resp_yet;
27
    sensitive << r.wait_resp;
28
    sensitive << r.pipeline_init;
29
    sensitive << r.br_address;
30
    sensitive << r.br_instr;
31
 
32
    SC_METHOD(registers);
33
    sensitive << i_clk.pos();
34
};
35
 
36
void InstrFetch::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
37
    if (o_vcd) {
38
        sc_trace(o_vcd, i_mem_data_valid, "/top/proc0/fetch0/i_mem_data_valid");
39
        sc_trace(o_vcd, i_mem_data_addr, "/top/proc0/fetch0/i_mem_data_addr");
40
        sc_trace(o_vcd, i_mem_data, "/top/proc0/fetch0/i_mem_data");
41
        sc_trace(o_vcd, o_mem_resp_ready, "/top/proc0/fetch0/o_mem_resp_ready");
42
        sc_trace(o_vcd, i_e_npc, "/top/proc0/fetch0/i_e_npc");
43
        sc_trace(o_vcd, i_predict_npc, "/top/proc0/fetch0/i_predict_npc");
44
        sc_trace(o_vcd, i_pipeline_hold, "/top/proc0/fetch0/i_pipeline_hold");
45
        sc_trace(o_vcd, o_mem_addr_valid, "/top/proc0/fetch0/o_mem_addr_valid");
46
        sc_trace(o_vcd, o_mem_addr, "/top/proc0/fetch0/o_mem_addr");
47
        sc_trace(o_vcd, i_mem_req_ready, "/top/proc0/fetch0/i_mem_req_ready");
48
        sc_trace(o_vcd, o_predict_miss, "/top/proc0/fetch0/o_predict_miss");
49
        sc_trace(o_vcd, o_hold, "/top/proc0/fetch0/o_hold");
50
        sc_trace(o_vcd, o_valid, "/top/proc0/fetch0/o_valid");
51
        sc_trace(o_vcd, o_pc, "/top/proc0/fetch0/o_pc");
52
        sc_trace(o_vcd, o_instr, "/top/proc0/fetch0/o_instr");
53
        sc_trace(o_vcd, r.pc_z1, "/top/proc0/fetch0/r.pc_z1");
54
        sc_trace(o_vcd, r.wait_resp, "/top/proc0/fetch0/r.wait_resp");
55
        sc_trace(o_vcd, r.raddr_not_resp_yet, "/top/proc0/fetch0/r_raddr_not_resp_yet");
56
    }
57
}
58
 
59
void InstrFetch::comb() {
60
    sc_uint<BUS_ADDR_WIDTH> wb_o_addr_req;
61
    bool w_predict_miss;
62
    bool w_o_req_valid;
63
    bool w_o_req_fire;
64
    bool w_resp_fire;
65
    bool w_o_mem_resp_ready;
66
    sc_uint<BUS_ADDR_WIDTH> wb_o_pc;
67
    sc_uint<32> wb_o_instr;
68
 
69
    v = r;
70
 
71
    w_o_req_valid = i_nrst.read() & !i_pipeline_hold.read()
72
            & !(r.wait_resp.read() & !i_mem_data_valid.read());
73
    w_o_req_fire = w_o_req_valid && i_mem_req_ready.read();
74
 
75
    w_o_mem_resp_ready = !i_pipeline_hold.read();
76
    w_resp_fire = i_mem_data_valid.read() && w_o_mem_resp_ready;
77
 
78
    w_predict_miss = 1;
79
    if (i_e_npc == r.pc_z1
80
       || i_e_npc == i_predict_npc || i_e_npc == r.raddr_not_resp_yet) {
81
        w_predict_miss = 0;
82
    }
83
 
84
    if (w_predict_miss) {
85
        wb_o_addr_req = i_e_npc.read();
86
    } else {
87
        wb_o_addr_req = i_predict_npc.read();
88
    }
89
 
90
 
91
    // Debug last fetched instructions buffer:
92
    sc_biguint<DBG_FETCH_TRACE_SIZE*64> wb_instr_buf = r.instr_buf;
93
    if (w_o_req_fire) {
94
        wb_instr_buf(DBG_FETCH_TRACE_SIZE*64-1, 64) =
95
            wb_instr_buf((DBG_FETCH_TRACE_SIZE-1)*64-1, 0);
96
        if (w_resp_fire) {
97
            wb_instr_buf(95, 64) = i_mem_data.read();
98
        }
99
        wb_instr_buf(63, 32) = wb_o_addr_req;
100
        wb_instr_buf(31, 0) = 0;
101
    } else if (w_resp_fire) {
102
        wb_instr_buf(31, 0) = i_mem_data.read();
103
    }
104
    v.instr_buf = wb_instr_buf;
105
 
106
 
107
    if (w_o_req_fire) {
108
        v.wait_resp = 1;
109
        v.pc_z1 = r.raddr_not_resp_yet;
110
        v.raddr_not_resp_yet = wb_o_addr_req;
111
        v.pipeline_init = (r.pipeline_init.read() << 1) | 1;
112
    } else if (i_mem_data_valid.read() && !w_o_req_fire && !i_pipeline_hold.read()) {
113
        v.wait_resp = 0;
114
    }
115
 
116
    if (i_br_fetch_valid.read()) {
117
        v.br_address = i_br_address_fetch;
118
        v.br_instr = i_br_instr_fetch;
119
    }
120
 
121
    if (i_mem_data_addr.read() == r.br_address.read()) {
122
        wb_o_pc = r.br_address;
123
        wb_o_instr = r.br_instr;
124
        if (w_resp_fire) {
125
            v.br_address = ~0;
126
        }
127
    } else {
128
        wb_o_pc = i_mem_data_addr;
129
        wb_o_instr = i_mem_data;
130
    }
131
 
132
    if (!i_nrst.read()) {
133
        v.wait_resp = 0;
134
        v.pipeline_init = 0;
135
        v.pc_z1 = 0;
136
        v.raddr_not_resp_yet = 0;
137
        v.br_address = ~0;
138
        v.br_instr = 0;
139
        v.instr_buf = 0;
140
    }
141
 
142
    o_mem_addr_valid = w_o_req_valid;
143
    o_mem_addr = wb_o_addr_req;
144
    o_mem_req_fire = w_o_req_fire;
145
    o_valid = w_resp_fire;
146
    o_pc = wb_o_pc;
147
    o_instr = wb_o_instr;
148
    o_predict_miss = w_predict_miss;
149
    o_mem_resp_ready = w_o_mem_resp_ready;
150
    o_hold = !w_resp_fire;
151
    o_instr_buf = r.instr_buf;
152
}
153
 
154
void InstrFetch::registers() {
155
    r = v;
156
}
157
 
158
}  // namespace debugger
159
 

powered by: WebSVN 2.1.0

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