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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_sysc_plugin/] [rtl_wrapper.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      SystemC CPU wrapper. To interact with the SoC simulator.
6
 */
7
 
8
#include "api_core.h"
9
#include "rtl_wrapper.h"
10
#if 1
11
#include "iservice.h"
12
#include "coreservices/iserial.h"
13
#endif
14
 
15
//#define SIMULATE_WAIT_STATES
16
 
17
namespace debugger {
18
 
19
RtlWrapper::RtlWrapper(IFace *parent, sc_module_name name) : sc_module(name),
20
    o_clk("clk", 10, SC_NS) {
21
    iparent_ = parent;
22
    generate_ref_ = false;
23
    clockCycles_ = 1000000; // 1 MHz when default resolution = 1 ps
24
 
25
    SC_METHOD(registers);
26
    sensitive << o_clk.posedge_event();
27
 
28
    SC_METHOD(comb);
29
    sensitive << i_req_mem_valid;
30
    sensitive << i_req_mem_addr;
31
    sensitive << r.nrst;
32
    sensitive << r.resp_mem_data_valid;
33
    sensitive << r.resp_mem_data;
34
    sensitive << r.interrupt;
35
    sensitive << r.wait_state_cnt;
36
 
37
    SC_METHOD(clk_negedge_proc);
38
    sensitive << o_clk.negedge_event();
39
 
40
    w_nrst = 0;
41
    v.nrst = 0;
42
    v.interrupt = false;
43
    w_interrupt = 0;
44
    v.resp_mem_data = 0;
45
    v.resp_mem_data_valid = false;
46
    RISCV_event_create(&dport_.valid, "dport_valid");
47
    dport_.trans_idx_up = 0;
48
    dport_.trans_idx_down = 0;
49
}
50
 
51
RtlWrapper::~RtlWrapper() {
52
    RISCV_event_close(&dport_.valid);
53
}
54
 
55
void RtlWrapper::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
56
    if (i_vcd) {
57
    }
58
    if (o_vcd) {
59
        sc_trace(o_vcd, w_nrst, "wrapper0/w_nrst");
60
        sc_trace(o_vcd, r.nrst, "wrapper0/r_nrst");
61
    }
62
}
63
 
64
void RtlWrapper::clk_gen() {
65
    // todo: instead sc_clock
66
}
67
 
68
void RtlWrapper::comb() {
69
 
70
    o_nrst = r.nrst.read()[1];
71
    o_resp_mem_data_valid = r.resp_mem_data_valid;
72
    o_resp_mem_data = r.resp_mem_data;
73
    o_interrupt = r.interrupt;
74
#ifdef SIMULATE_WAIT_STATES
75
    if (r.wait_state_cnt.read() == 1) {
76
        o_req_mem_ready = 1;
77
    } else {
78
        o_req_mem_ready = 0;
79
    }
80
#else
81
    o_req_mem_ready = i_req_mem_valid;
82
#endif
83
 
84
    o_dport_valid = r.dport_valid;
85
    o_dport_write = r.dport_write;
86
    o_dport_region = r.dport_region;
87
    o_dport_addr = r.dport_addr;
88
    o_dport_wdata = r.dport_wdata;
89
 
90
    if (!r.nrst.read()[1]) {
91
    }
92
}
93
 
94
void RtlWrapper::registers() {
95
    r = v;
96
}
97
 
98
void RtlWrapper::clk_negedge_proc() {
99
    /** Simulation events queue */
100
    IFace *cb;
101
 
102
    step_queue_.initProc();
103
    step_queue_.pushPreQueued();
104
    uint64_t step_cnt = i_time.read();
105
    while ((cb = step_queue_.getNext(step_cnt)) != 0) {
106
        static_cast<IClockListener *>(cb)->stepCallback(step_cnt);
107
    }
108
    if (generate_ref_ && step_cnt != step_cnt_z) {
109
        char msg[16];
110
        int msg_len = 0;
111
        IService *uart = NULL;
112
        switch (step_cnt) {
113
        case 22077:
114
            uart = static_cast<IService *>(RISCV_get_service("uart0"));
115
            msg[0] = 'h';
116
            msg_len = 1;
117
            break;
118
        case 22500:
119
            uart = static_cast<IService *>(RISCV_get_service("uart0"));
120
            msg[0] = 'e';
121
            msg[1] = 'l';
122
            msg_len = 2;
123
            break;
124
        case 24347:
125
            uart = static_cast<IService *>(RISCV_get_service("uart0"));
126
            msg[0] = 'p';
127
            msg[1] = '\r';
128
            msg[2] = '\n';
129
            msg_len = 3;
130
            break;
131
        default:;
132
        }
133
        if (uart) {
134
            ISerial *iserial = static_cast<ISerial *>(
135
                        uart->getInterface(IFACE_SERIAL));
136
            iserial->writeData(msg, msg_len);
137
        }
138
    }
139
    step_cnt_z = i_time.read();
140
 
141
    /** */
142
    v.interrupt = w_interrupt;
143
    v.nrst = (r.nrst.read() << 1) | w_nrst;
144
    v.wait_state_cnt = r.wait_state_cnt.read() + 1;
145
 
146
 
147
    v.resp_mem_data = 0;
148
    v.resp_mem_data_valid = false;
149
    bool w_req_fire = 0;
150
#ifdef SIMULATE_WAIT_STATES
151
    if (r.wait_state_cnt.read() == 1)
152
#endif
153
    {
154
        w_req_fire = i_req_mem_valid.read();
155
    }
156
    if (w_req_fire) {
157
        Axi4TransactionType trans;
158
        trans.source_idx = CFG_NASTI_MASTER_CACHED;
159
        trans.addr = i_req_mem_addr.read();
160
        if (i_req_mem_write.read()) {
161
            uint8_t strob = i_req_mem_strob.read();
162
            uint64_t offset = mask2offset(strob);
163
            trans.addr += offset;
164
            trans.action = MemAction_Write;
165
            trans.xsize = mask2size(strob >> offset);
166
            trans.wstrb = (1 << trans.xsize) - 1;
167
            trans.wpayload.b64[0] = i_req_mem_data.read();
168
            ibus_->b_transport(&trans);
169
            v.resp_mem_data = 0;
170
        } else {
171
            trans.action = MemAction_Read;
172
            trans.xsize = BUS_DATA_BYTES;
173
            ibus_->b_transport(&trans);
174
            v.resp_mem_data = trans.rpayload.b64[0];
175
        }
176
        v.resp_mem_data_valid = true;
177
    }
178
 
179
    // Debug port handling:
180
    v.dport_valid = 0;
181
    if (RISCV_event_is_set(&dport_.valid)) {
182
        RISCV_event_clear(&dport_.valid);
183
        v.dport_valid = 1;
184
        v.dport_write = dport_.trans->write;
185
        v.dport_region = dport_.trans->region;
186
        v.dport_addr = dport_.trans->addr;
187
        v.dport_wdata = dport_.trans->wdata;
188
    }
189
    dport_.idx_missmatch = 0;
190
    if (i_dport_ready.read()) {
191
        dport_.trans->rdata = i_dport_rdata.read().to_uint64();
192
        dport_.trans_idx_down++;
193
        if (dport_.trans_idx_down != dport_.trans_idx_up) {
194
            dport_.idx_missmatch = 1;
195
            RISCV_error("error: sync. is lost: up=%d, down=%d",
196
                         dport_.trans_idx_up, dport_.trans_idx_down);
197
            dport_.trans_idx_down = dport_.trans_idx_up;
198
        }
199
        dport_.cb->nb_response_debug_port(dport_.trans);
200
    }
201
}
202
 
203
uint64_t RtlWrapper::mask2offset(uint8_t mask) {
204
    for (int i = 0; i < BUS_DATA_BYTES; i++) {
205
        if (mask & 0x1) {
206
            return static_cast<uint64_t>(i);
207
        }
208
        mask >>= 1;
209
    }
210
    return 0;
211
}
212
 
213
uint32_t RtlWrapper::mask2size(uint8_t mask) {
214
    uint32_t bytes = 0;
215
    for (int i = 0; i < BUS_DATA_BYTES; i++) {
216
        if (!(mask & 0x1)) {
217
            break;
218
        }
219
        bytes++;
220
        mask >>= 1;
221
    }
222
    return bytes;
223
}
224
 
225
void RtlWrapper::setClockHz(double hz) {
226
    sc_time dt = sc_get_time_resolution();
227
    clockCycles_ = static_cast<int>((1.0 / hz) / dt.to_seconds() + 0.5);
228
}
229
 
230
void RtlWrapper::registerStepCallback(IClockListener *cb, uint64_t t) {
231
    if (!w_nrst) {
232
        if (i_time.read() == t) {
233
            cb->stepCallback(t);
234
        }
235
    } else {
236
        step_queue_.put(t, cb);
237
    }
238
}
239
 
240
void RtlWrapper::raiseSignal(int idx) {
241
    switch (idx) {
242
    case CPU_SIGNAL_RESET:
243
        w_nrst = 0;
244
        break;
245
    case CPU_SIGNAL_EXT_IRQ:
246
        w_interrupt = true;
247
        break;
248
    default:;
249
    }
250
}
251
 
252
void RtlWrapper::lowerSignal(int idx) {
253
    switch (idx) {
254
    case CPU_SIGNAL_RESET:
255
        w_nrst = 1;
256
        break;
257
    case CPU_SIGNAL_EXT_IRQ:
258
        w_interrupt = false;
259
        break;
260
    default:;
261
    }
262
}
263
 
264
void RtlWrapper::nb_transport_debug_port(DebugPortTransactionType *trans,
265
                                         IDbgNbResponse *cb) {
266
    dport_.trans = trans;
267
    dport_.cb = cb;
268
    dport_.trans_idx_up++;
269
    RISCV_event_set(&dport_.valid);
270
}
271
 
272
}  // namespace debugger
273
 

powered by: WebSVN 2.1.0

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