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 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 sergeykhbr
/*
2
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
3
 *
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 *  you may not use this file except in compliance with the License.
6
 *  You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *  Unless required by applicable law or agreed to in writing, software
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *  See the License for the specific language governing permissions and
14
 *  limitations under the License.
15 3 sergeykhbr
 */
16
 
17
#include "api_core.h"
18
#include "rtl_wrapper.h"
19
#include "iservice.h"
20 4 sergeykhbr
#include <riscv-isa.h>
21 3 sergeykhbr
#include "coreservices/iserial.h"
22 4 sergeykhbr
#include "coreservices/isocinfo.h"
23 3 sergeykhbr
 
24
//#define SIMULATE_WAIT_STATES
25
 
26
namespace debugger {
27
 
28
RtlWrapper::RtlWrapper(IFace *parent, sc_module_name name) : sc_module(name),
29
    o_clk("clk", 10, SC_NS) {
30
    iparent_ = parent;
31
    generate_ref_ = false;
32
    clockCycles_ = 1000000; // 1 MHz when default resolution = 1 ps
33
 
34
    SC_METHOD(registers);
35
    sensitive << o_clk.posedge_event();
36
 
37
    SC_METHOD(comb);
38
    sensitive << i_req_mem_valid;
39
    sensitive << i_req_mem_addr;
40
    sensitive << r.nrst;
41
    sensitive << r.resp_mem_data_valid;
42
    sensitive << r.resp_mem_data;
43
    sensitive << r.interrupt;
44
    sensitive << r.wait_state_cnt;
45
 
46
    SC_METHOD(clk_negedge_proc);
47
    sensitive << o_clk.negedge_event();
48
 
49 4 sergeykhbr
    w_nrst = 1;//0;
50
    v.nrst = 1;//0;
51 3 sergeykhbr
    v.interrupt = false;
52
    w_interrupt = 0;
53
    v.resp_mem_data = 0;
54
    v.resp_mem_data_valid = false;
55
    RISCV_event_create(&dport_.valid, "dport_valid");
56
    dport_.trans_idx_up = 0;
57
    dport_.trans_idx_down = 0;
58
}
59
 
60
RtlWrapper::~RtlWrapper() {
61
    RISCV_event_close(&dport_.valid);
62
}
63
 
64
void RtlWrapper::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
65
    if (i_vcd) {
66
    }
67
    if (o_vcd) {
68
        sc_trace(o_vcd, w_nrst, "wrapper0/w_nrst");
69
        sc_trace(o_vcd, r.nrst, "wrapper0/r_nrst");
70
    }
71
}
72
 
73
void RtlWrapper::clk_gen() {
74
    // todo: instead sc_clock
75
}
76
 
77
void RtlWrapper::comb() {
78
 
79 4 sergeykhbr
    o_nrst = r.nrst.read()[1].to_bool();
80 3 sergeykhbr
    o_resp_mem_data_valid = r.resp_mem_data_valid;
81
    o_resp_mem_data = r.resp_mem_data;
82
    o_interrupt = r.interrupt;
83
#ifdef SIMULATE_WAIT_STATES
84
    if (r.wait_state_cnt.read() == 1) {
85
        o_req_mem_ready = 1;
86
    } else {
87
        o_req_mem_ready = 0;
88
    }
89
#else
90
    o_req_mem_ready = i_req_mem_valid;
91
#endif
92
 
93
    o_dport_valid = r.dport_valid;
94
    o_dport_write = r.dport_write;
95
    o_dport_region = r.dport_region;
96
    o_dport_addr = r.dport_addr;
97
    o_dport_wdata = r.dport_wdata;
98
 
99
    if (!r.nrst.read()[1]) {
100
    }
101
}
102
 
103
void RtlWrapper::registers() {
104
    r = v;
105
}
106
 
107
void RtlWrapper::clk_negedge_proc() {
108
    /** Simulation events queue */
109
    IFace *cb;
110
 
111
    step_queue_.initProc();
112
    step_queue_.pushPreQueued();
113
    uint64_t step_cnt = i_time.read();
114
    while ((cb = step_queue_.getNext(step_cnt)) != 0) {
115
        static_cast<IClockListener *>(cb)->stepCallback(step_cnt);
116
    }
117
 
118
    /** */
119
    v.interrupt = w_interrupt;
120
    v.nrst = (r.nrst.read() << 1) | w_nrst;
121
    v.wait_state_cnt = r.wait_state_cnt.read() + 1;
122
 
123
 
124
    v.resp_mem_data = 0;
125
    v.resp_mem_data_valid = false;
126
    bool w_req_fire = 0;
127
#ifdef SIMULATE_WAIT_STATES
128
    if (r.wait_state_cnt.read() == 1)
129
#endif
130
    {
131
        w_req_fire = i_req_mem_valid.read();
132
    }
133
    if (w_req_fire) {
134
        Axi4TransactionType trans;
135
        trans.source_idx = CFG_NASTI_MASTER_CACHED;
136
        trans.addr = i_req_mem_addr.read();
137
        if (i_req_mem_write.read()) {
138
            uint8_t strob = i_req_mem_strob.read();
139
            uint64_t offset = mask2offset(strob);
140
            trans.addr += offset;
141
            trans.action = MemAction_Write;
142
            trans.xsize = mask2size(strob >> offset);
143
            trans.wstrb = (1 << trans.xsize) - 1;
144
            trans.wpayload.b64[0] = i_req_mem_data.read();
145
            ibus_->b_transport(&trans);
146
            v.resp_mem_data = 0;
147
        } else {
148
            trans.action = MemAction_Read;
149
            trans.xsize = BUS_DATA_BYTES;
150
            ibus_->b_transport(&trans);
151
            v.resp_mem_data = trans.rpayload.b64[0];
152
        }
153
        v.resp_mem_data_valid = true;
154
    }
155
 
156
    // Debug port handling:
157
    v.dport_valid = 0;
158
    if (RISCV_event_is_set(&dport_.valid)) {
159
        RISCV_event_clear(&dport_.valid);
160
        v.dport_valid = 1;
161
        v.dport_write = dport_.trans->write;
162
        v.dport_region = dport_.trans->region;
163 4 sergeykhbr
        v.dport_addr = dport_.trans->addr >> 3;
164 3 sergeykhbr
        v.dport_wdata = dport_.trans->wdata;
165
    }
166
    dport_.idx_missmatch = 0;
167
    if (i_dport_ready.read()) {
168
        dport_.trans->rdata = i_dport_rdata.read().to_uint64();
169
        dport_.trans_idx_down++;
170
        if (dport_.trans_idx_down != dport_.trans_idx_up) {
171
            dport_.idx_missmatch = 1;
172
            RISCV_error("error: sync. is lost: up=%d, down=%d",
173
                         dport_.trans_idx_up, dport_.trans_idx_down);
174
            dport_.trans_idx_down = dport_.trans_idx_up;
175
        }
176
        dport_.cb->nb_response_debug_port(dport_.trans);
177
    }
178
}
179
 
180
uint64_t RtlWrapper::mask2offset(uint8_t mask) {
181
    for (int i = 0; i < BUS_DATA_BYTES; i++) {
182
        if (mask & 0x1) {
183
            return static_cast<uint64_t>(i);
184
        }
185
        mask >>= 1;
186
    }
187
    return 0;
188
}
189
 
190
uint32_t RtlWrapper::mask2size(uint8_t mask) {
191
    uint32_t bytes = 0;
192
    for (int i = 0; i < BUS_DATA_BYTES; i++) {
193
        if (!(mask & 0x1)) {
194
            break;
195
        }
196
        bytes++;
197
        mask >>= 1;
198
    }
199
    return bytes;
200
}
201
 
202
void RtlWrapper::setClockHz(double hz) {
203
    sc_time dt = sc_get_time_resolution();
204
    clockCycles_ = static_cast<int>((1.0 / hz) / dt.to_seconds() + 0.5);
205
}
206
 
207
void RtlWrapper::registerStepCallback(IClockListener *cb, uint64_t t) {
208
    if (!w_nrst) {
209
        if (i_time.read() == t) {
210
            cb->stepCallback(t);
211
        }
212
    } else {
213
        step_queue_.put(t, cb);
214
    }
215
}
216
 
217
void RtlWrapper::raiseSignal(int idx) {
218
    switch (idx) {
219 4 sergeykhbr
    case SIGNAL_HardReset:
220 3 sergeykhbr
        w_nrst = 0;
221
        break;
222 4 sergeykhbr
    case INTERRUPT_MExternal:
223 3 sergeykhbr
        w_interrupt = true;
224
        break;
225
    default:;
226
    }
227
}
228
 
229
void RtlWrapper::lowerSignal(int idx) {
230
    switch (idx) {
231 4 sergeykhbr
    case SIGNAL_HardReset:
232 3 sergeykhbr
        w_nrst = 1;
233
        break;
234 4 sergeykhbr
    case INTERRUPT_MExternal:
235 3 sergeykhbr
        w_interrupt = false;
236
        break;
237
    default:;
238
    }
239
}
240
 
241
void RtlWrapper::nb_transport_debug_port(DebugPortTransactionType *trans,
242
                                         IDbgNbResponse *cb) {
243
    dport_.trans = trans;
244
    dport_.cb = cb;
245
    dport_.trans_idx_up++;
246
    RISCV_event_set(&dport_.valid);
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.