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/] [memaccess.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 Memory Access stage.
6
 */
7
 
8
#include "memaccess.h"
9
 
10
namespace debugger {
11
 
12
MemAccess::MemAccess(sc_module_name name_)
13
    : sc_module(name_) {
14
    SC_METHOD(comb);
15
    sensitive << i_nrst;
16
    sensitive << i_mem_req_ready;
17
    sensitive << i_e_valid;
18
    sensitive << i_e_pc;
19
    sensitive << i_e_instr;
20
    sensitive << i_res_addr;
21
    sensitive << i_res_data;
22
    sensitive << i_memop_sign_ext;
23
    sensitive << i_memop_load;
24
    sensitive << i_memop_store;
25
    sensitive << i_memop_size;
26
    sensitive << i_memop_addr;
27
    sensitive << i_mem_data_valid;
28
    sensitive << i_mem_data_addr;
29
    sensitive << i_mem_data;
30
    sensitive << r.valid;
31
    sensitive << r.wdata;
32
    sensitive << r.wait_req;
33
    sensitive << r.wait_resp;
34
 
35
    SC_METHOD(registers);
36
    sensitive << i_clk.pos();
37
};
38
 
39
void MemAccess::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
40
    if (o_vcd) {
41
        sc_trace(o_vcd, i_e_valid, "/top/proc0/mem0/i_e_valid");
42
        sc_trace(o_vcd, i_e_pc, "/top/proc0/mem0/i_e_pc");
43
        sc_trace(o_vcd, i_e_instr, "/top/proc0/mem0/i_e_instr");
44
        sc_trace(o_vcd, o_mem_valid, "/top/proc0/mem0/o_mem_valid");
45
        sc_trace(o_vcd, o_mem_write, "/top/proc0/mem0/o_mem_write");
46
        sc_trace(o_vcd, i_mem_req_ready, "/top/proc0/mem0/i_mem_req_ready");
47
        sc_trace(o_vcd, o_mem_sz, "/top/proc0/mem0/o_mem_sz");
48
        sc_trace(o_vcd, o_mem_addr, "/top/proc0/mem0/o_mem_addr");
49
        sc_trace(o_vcd, o_mem_data, "/top/proc0/mem0/o_mem_data");
50
        sc_trace(o_vcd, i_mem_data_valid, "/top/proc0/mem0/i_mem_data_valid");
51
        sc_trace(o_vcd, i_mem_data_addr, "/top/proc0/mem0/i_mem_data_addr");
52
        sc_trace(o_vcd, i_mem_data, "/top/proc0/mem0/i_mem_data");
53
        sc_trace(o_vcd, o_mem_resp_ready, "/top/proc0/mem0/o_mem_resp_ready");
54
 
55
        sc_trace(o_vcd, o_valid, "/top/proc0/mem0/o_valid");
56
        sc_trace(o_vcd, o_pc, "/top/proc0/mem0/o_pc");
57
        sc_trace(o_vcd, o_instr, "/top/proc0/mem0/o_instr");
58
        sc_trace(o_vcd, o_wena, "/top/proc0/mem0/o_wena");
59
        sc_trace(o_vcd, o_waddr, "/top/proc0/mem0/o_waddr");
60
        sc_trace(o_vcd, o_wdata, "/top/proc0/mem0/o_wdata");
61
        sc_trace(o_vcd, o_hold, "/top/proc0/mem0/o_hold");
62
        sc_trace(o_vcd, r.wait_resp, "/top/proc0/mem0/r.wait_resp");
63
    }
64
}
65
 
66
void MemAccess::comb() {
67
    bool w_o_mem_valid;
68
    bool w_o_mem_write;
69
    sc_uint<2> wb_o_mem_sz;
70
    sc_uint<BUS_ADDR_WIDTH> wb_o_mem_addr;
71
    sc_uint<RISCV_ARCH> wb_o_mem_wdata;
72
    sc_uint<RISCV_ARCH> wb_res_wdata;
73
    bool w_memop;
74
    bool w_o_valid;
75
    bool w_o_wena;
76
    bool w_o_hold;
77
    bool w_mem_fire;
78
 
79
    v = r;
80
 
81
    w_o_mem_valid = 0;
82
    w_o_mem_write = 0;
83
    wb_o_mem_sz = 0;
84
    wb_o_mem_addr = 0;
85
    wb_o_mem_wdata = 0;
86
    v.valid = 0;
87
    w_o_hold = 0;
88
 
89
    w_memop = i_memop_load.read() || i_memop_store.read();
90
 
91
    if (r.wait_req.read()) {
92
        if (i_mem_req_ready.read()) {
93
            v.wait_req = 0;
94
            v.wait_resp = 1;
95
        }
96
        w_o_mem_valid = 1;
97
        w_o_mem_write = r.wait_req_write;
98
        wb_o_mem_sz = r.wait_req_sz;
99
        wb_o_mem_addr = r.wait_req_addr;
100
        wb_o_mem_wdata = r.wait_req_wdata;
101
    } else if (i_e_valid.read()) {
102
        v.valid = !w_memop;
103
        v.pc = i_e_pc;
104
        v.instr = i_e_instr;
105
        v.waddr = i_res_addr;
106
        v.wdata = i_res_data;
107
        if (i_res_addr.read() == 0) {
108
            v.wena = 0;
109
        } else {
110
            v.wena = 1;
111
        }
112
 
113
        if (w_memop) {
114
            w_o_mem_valid = 1;
115
            w_o_mem_write = i_memop_store;
116
            wb_o_mem_sz = i_memop_size;
117
            wb_o_mem_addr = i_memop_addr;
118
            wb_o_mem_wdata = i_res_data;
119
            v.sign_ext = i_memop_sign_ext;
120
            v.size = i_memop_size;
121
 
122
            v.wait_resp = i_mem_req_ready;
123
            v.wait_req = !i_mem_req_ready;
124
            v.wait_req_write = i_memop_store;
125
            v.wait_req_sz = i_memop_size;
126
            v.wait_req_addr = i_memop_addr;
127
            v.wait_req_wdata = i_res_data;
128
        } else {
129
            w_o_mem_valid = 0;
130
            w_o_mem_write = 0;
131
            wb_o_mem_sz = 0;
132
            wb_o_mem_addr = 0;
133
            wb_o_mem_wdata = 0;
134
            v.sign_ext = 0;
135
            v.size = 0;
136
            v.wait_req_addr = 0;
137
            v.wait_req = 0;
138
            v.wait_resp = 0;
139
        }
140
    } else if (i_mem_data_valid.read()) {
141
        v.wait_resp = 0;
142
    }
143
 
144
    w_o_hold = (i_e_valid.read() && w_memop) || r.wait_req.read()
145
            || (r.wait_resp.read() && !i_mem_data_valid.read());
146
 
147
    w_mem_fire = i_mem_data_valid;
148
    if (w_mem_fire) {
149
        if (r.sign_ext.read()) {
150
            switch (r.size.read()) {
151
            case MEMOP_1B:
152
                wb_res_wdata = i_mem_data;
153
                if (i_mem_data.read()[7]) {
154
                    wb_res_wdata(63, 8) = ~0;
155
                }
156
                break;
157
            case MEMOP_2B:
158
                wb_res_wdata = i_mem_data;
159
                if (i_mem_data.read()[15]) {
160
                    wb_res_wdata(63, 16) = ~0;
161
                }
162
                break;
163
            case MEMOP_4B:
164
                wb_res_wdata = i_mem_data;
165
                if (i_mem_data.read()[31]) {
166
                    wb_res_wdata(63, 32) = ~0;
167
                }
168
                break;
169
            default:
170
                wb_res_wdata = i_mem_data;
171
            }
172
        } else {
173
            wb_res_wdata = i_mem_data;
174
        }
175
    } else {
176
        wb_res_wdata = r.wdata;
177
    }
178
 
179
    w_o_valid = r.valid.read() || w_mem_fire;
180
    w_o_wena = r.wena & w_o_valid;
181
 
182
    if (!i_nrst.read()) {
183
        v.valid = false;
184
        v.pc = 0;
185
        v.instr = 0;
186
        v.waddr = 0;
187
        v.wdata = 0;
188
        v.wena = 0;
189
        v.size = 0;
190
        v.sign_ext = 0;
191
        v.wait_req = 0;
192
        v.wait_req_write = 0;
193
        v.wait_req_sz = 0;
194
        v.wait_req_addr = 0;
195
        v.wait_req_wdata = 0;
196
        v.wait_resp = 0;
197
    }
198
 
199
    o_mem_resp_ready = 1;
200
 
201
    o_mem_valid = w_o_mem_valid;
202
    o_mem_write = w_o_mem_write;
203
    o_mem_sz = wb_o_mem_sz;
204
    o_mem_addr = wb_o_mem_addr;
205
    o_mem_data = wb_o_mem_wdata;
206
 
207
    o_wena = w_o_wena;
208
    o_waddr = r.waddr;
209
    o_wdata = wb_res_wdata;
210
    o_valid = w_o_valid;
211
    o_pc = r.pc;
212
    o_instr = r.instr;
213
    o_hold = w_o_hold;
214
}
215
 
216
void MemAccess::registers() {
217
    r = v;
218
}
219
 
220
}  // namespace debugger
221
 

powered by: WebSVN 2.1.0

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