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

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      CSR registers module.
6
 */
7
 
8
#include "csr.h"
9
#include "riscv-isa.h"
10
 
11
namespace debugger {
12
 
13
CsrRegs::CsrRegs(sc_module_name name_) : sc_module(name_) {
14
    SC_METHOD(comb);
15
    sensitive << i_nrst;
16
    sensitive << i_xret;
17
    sensitive << i_addr;
18
    sensitive << i_wena;
19
    sensitive << i_wdata;
20
    sensitive << i_break_mode;
21
    sensitive << i_breakpoint;
22
    sensitive << i_trap_ena;
23
    sensitive << i_trap_code;
24
    sensitive << i_trap_pc;
25
    sensitive << i_dport_ena;
26
    sensitive << i_dport_write;
27
    sensitive << i_dport_addr;
28
    sensitive << i_dport_wdata;
29
    sensitive << r.mtvec;
30
    sensitive << r.mscratch;
31
    sensitive << r.mbadaddr;
32
    sensitive << r.mode;
33
    sensitive << r.uie;
34
    sensitive << r.mie;
35
    sensitive << r.mpie;
36
    sensitive << r.mpp;
37
    sensitive << r.mepc;
38
    sensitive << r.trap_irq;
39
    sensitive << r.trap_code;
40
 
41
    SC_METHOD(registers);
42
    sensitive << i_clk.pos();
43
};
44
 
45
void CsrRegs::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
46
    if (o_vcd) {
47
        sc_trace(o_vcd, i_xret, "/top/proc0/csr0/i_xret");
48
        sc_trace(o_vcd, i_addr, "/top/proc0/csr0/i_addr");
49
        sc_trace(o_vcd, i_wena, "/top/proc0/csr0/i_wena");
50
        sc_trace(o_vcd, i_wdata, "/top/proc0/csr0/i_wdata");
51
        sc_trace(o_vcd, i_trap_ena, "/top/proc0/csr0/i_trap_ena");
52
        sc_trace(o_vcd, i_trap_code, "/top/proc0/csr0/i_trap_code");
53
        sc_trace(o_vcd, i_trap_pc, "/top/proc0/csr0/i_trap_pc");
54
        sc_trace(o_vcd, o_mode, "/top/proc0/csr0/o_mode");
55
        sc_trace(o_vcd, o_ie, "/top/proc0/csr0/o_ie");
56
        sc_trace(o_vcd, o_rdata, "/top/proc0/csr0/o_rdata");
57
        sc_trace(o_vcd, o_mtvec, "/top/proc0/csr0/o_mtvec");
58
        sc_trace(o_vcd, i_dport_ena, "/top/proc0/csr0/i_dport_ena");
59
        sc_trace(o_vcd, i_dport_write, "/top/proc0/csr0/i_dport_write");
60
        sc_trace(o_vcd, i_dport_addr, "/top/proc0/csr0/i_dport_addr");
61
        sc_trace(o_vcd, i_dport_wdata, "/top/proc0/csr0/i_dport_wdata");
62
        sc_trace(o_vcd, o_dport_rdata, "/top/proc0/csr0/o_dport_rdata");
63
    }
64
}
65
 
66
void CsrRegs::procedure_RegAccess(uint64_t iaddr, bool iwena,
67
                                 sc_uint<RISCV_ARCH> iwdata,
68
                                 RegistersType &ir, RegistersType *ov,
69
                                 sc_uint<RISCV_ARCH> *ordata) {
70
    *ordata = 0;
71
    switch (iaddr) {
72
    case CSR_misa:
73
        /** Base[XLEN-1:XLEN-2]
74
         *      1 = 32
75
         *      2 = 64
76
         *      3 = 128
77
         */
78
        (*ordata)(RISCV_ARCH-1, RISCV_ARCH-2) = 2;
79
        /** BitCharacterDescription
80
         * 0  A Atomic extension
81
         * 1  B Tentatively reserved for Bit operations extension
82
         * 2  C Compressed extension3DDouble-precision Foating-point extension
83
         * 4  E RV32E base ISA
84
         * 5  F Single-precision Foating-point extension
85
         * 6  G Additional standard extensions present
86
         * 7  H Hypervisor mode implemented
87
         * 8  I RV32I/64I/128I base ISA
88
         * 9  J Reserved
89
         * 10 K Reserved
90
         * 11 L Tentatively reserved for Decimal Floating-Point extension
91
         * 12 M Integer Multiply/Divide extension
92
         * 13 N User-level interrupts supported
93
         * 14 O Reserved
94
         * 15 P Tentatively reserved for Packed-SIMD extension
95
         * 16 Q Quad-precision Foating-point extension
96
         * 17 R Reserved
97
         * 18 S Supervisor mode implemented
98
         * 19 T Tentatively reserved for Transactional Memory extension
99
         * 20 U User mode implemented
100
         * 21 V Tentatively reserved for Vector extension
101
         * 22 W Reserved
102
         * 23 X Non-standard extensions present
103
         * 24 Y Reserved
104
         * 25 Z Reserve
105
         */
106
        //(*ordata)['A' - 'A'] = 1;
107
        (*ordata)['I' - 'A'] = 1;
108
        (*ordata)['M' - 'A'] = 1;
109
        (*ordata)['U' - 'A'] = 1;
110
        break;
111
    case CSR_mvendorid:
112
        break;
113
    case CSR_marchid:
114
        break;
115
    case CSR_mimplementationid:
116
        break;
117
    case CSR_mhartid:
118
        break;
119
    case CSR_uepc:// - User mode program counter
120
        break;
121
    case CSR_mstatus:// - Machine mode status register
122
        (*ordata)[0] = ir.uie;
123
        (*ordata)[3] = ir.mie;
124
        (*ordata)[7] = ir.mpie;
125
        (*ordata)(12, 11) = ir.mpp;
126
        if (iwena) {
127
            ov->uie = iwdata[0];
128
            ov->mie = iwdata[3];
129
            ov->mpie = iwdata[7];
130
            ov->mpp = iwdata(12, 11);
131
        }
132
        break;
133
    case CSR_medeleg:// - Machine exception delegation
134
        break;
135
    case CSR_mideleg:// - Machine itnerrupt delegation
136
        break;
137
    case CSR_mie:// - Machine interrupt enable bit
138
        break;
139
    case CSR_mtvec:
140
        (*ordata) = ir.mtvec;
141
        if (iwena) {
142
            ov->mtvec = iwdata;
143
        }
144
        break;
145
    case CSR_mtimecmp:// - Machine wall-clock timer compare value
146
        break;
147
    case CSR_mscratch:// - Machine scratch register
148
        (*ordata) = ir.mscratch;
149
        if (iwena) {
150
            ov->mscratch = iwdata;
151
        }
152
        break;
153
    case CSR_mepc:// - Machine program counter
154
        (*ordata) = ir.mepc;
155
        if (iwena) {
156
            ov->mepc = iwdata;
157
        }
158
        break;
159
    case CSR_mcause:// - Machine trap cause
160
        (*ordata) = 0;
161
        (*ordata)[63] = ir.trap_irq;
162
        (*ordata)(3, 0) = ir.trap_code;
163
        break;
164
    case CSR_mbadaddr:// - Machine bad address
165
        (*ordata) = ir.mbadaddr;
166
        break;
167
    case CSR_mip:// - Machine interrupt pending
168
        break;
169
    default:;
170
    }
171
 
172
}
173
 
174
void CsrRegs::comb() {
175
    sc_uint<RISCV_ARCH> wb_rdata = 0;
176
    sc_uint<RISCV_ARCH> wb_dport_rdata = 0;
177
    bool w_ie;
178
    bool w_dport_wena;
179
 
180
    v = r;
181
 
182
    w_dport_wena = i_dport_ena & i_dport_write;
183
 
184
    procedure_RegAccess(i_addr.read(), i_wena.read(), i_wdata.read(),
185
                        r, &v, &wb_rdata);
186
 
187
    procedure_RegAccess(i_dport_addr.read(), w_dport_wena,
188
                        i_dport_wdata.read(), r, &v, &wb_dport_rdata);
189
 
190
 
191
    if (i_addr.read() == CSR_mepc && i_xret.read()) {
192
        // Switch to previous mode
193
        v.mie = r.mpie;
194
        v.mpie = 1;
195
        v.mode = r.mpp;
196
        v.mpp = PRV_U;
197
    }
198
 
199
    if (i_trap_ena.read() && (i_break_mode.read() || !i_breakpoint.read())) {
200
        v.mie = 0;
201
        v.mpp = r.mode;
202
        v.mepc = i_trap_pc.read();
203
        v.mbadaddr = i_trap_pc.read();
204
        v.trap_code = i_trap_code.read()(3, 0);
205
        v.trap_irq = i_trap_code.read()[4];
206
        v.mode = PRV_M;
207
        switch (r.mode.read()) {
208
        case PRV_U:
209
            v.mpie = r.uie;
210
            break;
211
        case PRV_M:
212
            v.mpie = r.mie;
213
            break;
214
        default:;
215
        }
216
    }
217
 
218
    w_ie = 0;
219
    if ((r.mode.read() != PRV_M) || r.mie.read()) {
220
        w_ie = 1;
221
    }
222
 
223
    if (!i_nrst.read()) {
224
        v.mtvec = 0;
225
        v.mscratch = 0;
226
        v.mbadaddr = 0;
227
        v.mode = PRV_M;
228
        v.uie = 0;
229
        v.mie = 0;
230
        v.mpie = 0;
231
        v.mpp = 0;
232
        v.mepc = 0;
233
        v.trap_code = 0;
234
        v.trap_irq = 0;
235
    }
236
 
237
 
238
    o_rdata = wb_rdata;
239
    o_ie = w_ie;
240
    o_mode = r.mode;
241
    o_mtvec = r.mtvec.read()(BUS_ADDR_WIDTH - 1, 0);
242
    o_dport_rdata = wb_dport_rdata;
243
}
244
 
245
void CsrRegs::registers() {
246
    r = v;
247
}
248
 
249
}  // namespace debugger
250
 

powered by: WebSVN 2.1.0

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