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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_sysc_plugin/] [riverlib/] [cache/] [icache.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 2017 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Instruction Cache.
6
 */
7
 
8
#include "icache.h"
9
 
10
namespace debugger {
11
 
12
ICache::ICache(sc_module_name name_) : sc_module(name_) {
13
    SC_METHOD(comb);
14
    sensitive << i_nrst;
15
    sensitive << i_req_ctrl_valid;
16
    sensitive << i_req_ctrl_addr;
17
    sensitive << i_resp_mem_data_valid;
18
    sensitive << i_resp_mem_data;
19
    sensitive << i_resp_ctrl_ready;
20
    sensitive << i_req_mem_ready;
21
    sensitive << r.iline_addr;
22
    sensitive << r.iline_data;
23
    sensitive << r.iline_addr_hit;
24
    sensitive << r.iline_data_hit;
25
    sensitive << r.iline_addr_req;
26
    sensitive << r.hit_line;
27
    sensitive << r.state;
28
 
29
    SC_METHOD(registers);
30
    sensitive << i_clk.pos();
31
};
32
 
33
void ICache::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
34
    if (o_vcd) {
35
        sc_trace(o_vcd, i_nrst, "/top/cache0/i0/i_nrst");
36
        sc_trace(o_vcd, i_req_ctrl_valid, "/top/cache0/i0/i_req_ctrl_valid");
37
        sc_trace(o_vcd, i_req_ctrl_addr, "/top/cache0/i0/i_req_ctrl_addr");
38
        sc_trace(o_vcd, o_req_ctrl_ready, "/top/cache0/i0/o_req_ctrl_ready");
39
        sc_trace(o_vcd, o_req_mem_valid, "/top/cache0/i0/o_req_mem_valid");
40
        sc_trace(o_vcd, o_req_mem_addr, "/top/cache0/i0/o_req_mem_addr");
41
        sc_trace(o_vcd, i_req_mem_ready, "/top/cache0/i0/i_req_mem_ready");
42
        sc_trace(o_vcd, i_resp_mem_data_valid, "/top/cache0/i0/i_resp_mem_data_valid");
43
        sc_trace(o_vcd, i_resp_mem_data, "/top/cache0/i0/i_resp_mem_data");
44
        sc_trace(o_vcd, o_resp_ctrl_valid, "/top/cache0/i0/o_resp_ctrl_valid");
45
        sc_trace(o_vcd, i_resp_ctrl_ready, "/top/cache0/i0/i_resp_ctrl_ready");
46
        sc_trace(o_vcd, o_resp_ctrl_addr, "/top/cache0/i0/o_resp_ctrl_addr");
47
        sc_trace(o_vcd, o_resp_ctrl_data, "/top/cache0/i0/o_resp_ctrl_data");
48
        sc_trace(o_vcd, r.iline_addr, "/top/cache0/i0/r_iline_addr");
49
        sc_trace(o_vcd, r.iline_data, "/top/cache0/i0/r_iline_data");
50
        sc_trace(o_vcd, r.iline_addr_hit, "/top/cache0/i0/r_iline_addr_hit");
51
        sc_trace(o_vcd, r.iline_data_hit, "/top/cache0/i0/r_iline_data_hit");
52
        sc_trace(o_vcd, r.iline_addr_req, "/top/cache0/i0/r_iline_addr_req");
53
        sc_trace(o_vcd, r.hit_line, "/top/cache0/i0/r_hit_line");
54
        sc_trace(o_vcd, r.state, "/top/cache0/i0/r_state");
55
        sc_trace(o_vcd, w_hit, "/top/cache0/i0/w_hit");
56
        sc_trace(o_vcd, w_hit_line, "/top/cache0/i0/w_hit_line");
57
        sc_trace(o_vcd, w_hit_req, "/top/cache0/i0/w_hit_req");
58
        //sc_trace(o_vcd, wb_req_line, "/top/cache0/i0/wb_req_line");
59
        //sc_trace(o_vcd, wb_cached_addr, "/top/cache0/i0/wb_cached_addr");
60
        //sc_trace(o_vcd, wb_cached_data, "/top/cache0/i0/wb_cached_data");
61
    }
62
}
63
 
64
void ICache::comb() {
65
    // Instruction cache:
66
    bool w_o_req_ctrl_ready;
67
    bool w_o_req_mem_valid;
68
    sc_uint<BUS_ADDR_WIDTH> wb_o_req_mem_addr;
69
    bool w_req_fire;
70
    bool w_o_resp_valid;
71
    sc_uint<BUS_ADDR_WIDTH> wb_o_resp_addr;
72
    sc_uint<32> wb_o_resp_data;
73
    sc_uint<BUS_ADDR_WIDTH - 3> wb_req_line;
74
 
75
    v = r;
76
    w_hit_req = 0;
77
    w_hit_line = 0;
78
    w_hit = 0;
79
 
80
    wb_req_line = i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3);
81
    if (i_resp_mem_data_valid.read()
82
      && (wb_req_line == r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3))) {
83
        w_hit_req = 1;
84
    }
85
    if (wb_req_line == r.iline_addr.read()) {
86
        w_hit_line = 1;
87
    }
88
    w_hit = w_hit_req || w_hit_line;
89
 
90
    w_o_req_mem_valid = !w_hit & i_req_ctrl_valid.read();
91
    wb_o_req_mem_addr = i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3) << 3;
92
    w_o_req_ctrl_ready = w_hit | i_req_mem_ready.read();
93
    w_req_fire = i_req_ctrl_valid.read() && w_o_req_ctrl_ready;
94
    switch (r.state.read()) {
95
    case State_Idle:
96
        if (i_req_ctrl_valid.read()) {
97
            if (w_hit_line) {
98
                v.state = State_WaitAccept;
99
            } else if (i_req_mem_ready.read()) {
100
                v.state = State_WaitResp;
101
            } else {
102
                v.state = State_WaitGrant;
103
            }
104
        }
105
        break;
106
    case State_WaitGrant:
107
        if (i_req_mem_ready.read()) {
108
            v.state = State_WaitResp;
109
        } else if (w_hit) {
110
            /** Fetcher can change request address while request wasn't
111
             *  accepteed. */
112
            v.state = State_WaitAccept;
113
        }
114
        break;
115
    case State_WaitResp:
116
        if (i_resp_mem_data_valid.read()) {
117
            if (!i_resp_ctrl_ready.read()) {
118
                v.state = State_WaitAccept;
119
            } else if (!i_req_ctrl_valid.read()) {
120
                v.state = State_Idle;
121
            } else {
122
                // New request
123
                if (w_hit) {
124
                    v.state = State_WaitAccept;
125
                } else if (i_req_mem_ready.read()) {
126
                    v.state = State_WaitResp;
127
                } else {
128
                    v.state = State_WaitGrant;
129
                }
130
            }
131
        }
132
        break;
133
    case State_WaitAccept:
134
        if (i_resp_ctrl_ready.read()) {
135
            if (!i_req_ctrl_valid.read()) {
136
                v.state = State_Idle;
137
            } else {
138
                if (w_hit) {
139
                    v.state = State_WaitAccept;
140
                } else if (i_req_mem_ready.read()) {
141
                    v.state = State_WaitResp;
142
                } else {
143
                    v.state = State_WaitGrant;
144
                }
145
            }
146
        }
147
        break;
148
    default:;
149
    }
150
 
151
    if (w_req_fire) {
152
        v.iline_addr_req = i_req_ctrl_addr;
153
        v.hit_line = 0;
154
        if (w_hit_line) {
155
            v.hit_line = 1;
156
            v.iline_addr_hit = i_req_ctrl_addr;
157
            if (i_req_ctrl_addr.read()[2] == 0) {
158
                v.iline_data_hit =  r.iline_data.read()(31, 0);
159
            } else {
160
                v.iline_data_hit =  r.iline_data.read()(63, 32);
161
            }
162
        }
163
    }
164
    if (i_resp_mem_data_valid.read()) {
165
        v.iline_addr = r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3);
166
        v.iline_data =  i_resp_mem_data;
167
    }
168
 
169
    wb_o_resp_addr = r.iline_addr_req;
170
    if (r.state.read() == State_WaitAccept) {
171
        w_o_resp_valid = 1;
172
        if (r.hit_line) {
173
            wb_o_resp_addr = r.iline_addr_hit;
174
            wb_o_resp_data = r.iline_data_hit;
175
        } else {
176
            if (r.iline_addr_req.read()[2] == 0) {
177
                wb_o_resp_data = r.iline_data.read()(31, 0);
178
            } else {
179
                wb_o_resp_data = r.iline_data.read()(63, 32);
180
            }
181
        }
182
    } else {
183
        w_o_resp_valid = i_resp_mem_data_valid;
184
        if (r.iline_addr_req.read()[2] == 0) {
185
            wb_o_resp_data = i_resp_mem_data.read()(31, 0);
186
        } else {
187
            wb_o_resp_data = i_resp_mem_data.read()(63, 32);
188
        }
189
    }
190
 
191
 
192
    if (!i_nrst.read()) {
193
        v.iline_addr_req = 0;
194
        v.iline_addr = ~0;
195
        v.iline_data = 0;
196
        v.iline_addr_hit = ~0;
197
        v.iline_data_hit = 0;
198
        v.hit_line = 0;
199
        v.state = State_Idle;
200
    }
201
 
202
    o_req_ctrl_ready = w_o_req_ctrl_ready;
203
 
204
    o_req_mem_valid = w_o_req_mem_valid;
205
    o_req_mem_addr = wb_o_req_mem_addr;
206
    o_req_mem_write = false;
207
    o_req_mem_strob = 0;
208
    o_req_mem_data = 0;
209
 
210
    o_resp_ctrl_valid = w_o_resp_valid;
211
    o_resp_ctrl_data = wb_o_resp_data;
212
    o_resp_ctrl_addr = wb_o_resp_addr;
213
    o_istate = r.state;
214
}
215
 
216
void ICache::registers() {
217
    r = v;
218
}
219
 
220
#ifdef DBG_ICACHE_TB
221
void ICache_tb::comb0() {
222
    v = r;
223
    v.clk_cnt = r.clk_cnt.read() + 1;
224
 
225
    if (r.clk_cnt.read() < 10) {
226
        w_nrst = 0;
227
        v.mem_state = 0;
228
        v.mem_cnt = 0;
229
        v.fetch_state = 0;
230
        v.fetch_cnt = 0;
231
        return;
232
    }
233
    w_nrst = 1;
234
 
235
    w_req_ctrl_valid = 0;
236
    wb_req_ctrl_addr = 0;
237
    w_resp_ctrl_ready = 0;
238
 
239
    struct FetchDelayType {
240
        uint32_t raddr;
241
        int req_wait;
242
        int accept_wait;
243
    };
244
    static const FetchDelayType RADDR[4] = {{0x100008f4, 0, 0}, {0x100007b0, 0, 0}, {0x100008f0, 2, 0}, {0x100007b4, 0, 0}};
245
    struct MemDelayType {
246
        unsigned rdy_wait;
247
        unsigned valid_wait;
248
    };
249
    //static const MemDelayType MEM_DELAY[4] = {{2,3}, {2,3}, {0,0}, {0,0}};
250
    static const MemDelayType MEM_DELAY[4] = {{0,0}, {0,0}, {5,0}, {5,0}};
251
 
252
 
253
    // fetch model:
254
    w_resp_ctrl_ready = 0;
255
    if (r.clk_cnt.read() >= 15) {
256
        switch (r.fetch_state.read()) {
257
        case 0:
258
            if (r.fetch_cnt.read() < 4) {
259
                if (RADDR[r.fetch_cnt.read()].req_wait == 0) {
260
                    w_req_ctrl_valid = 1;
261
                    wb_req_ctrl_addr = RADDR[r.fetch_cnt.read()].raddr;
262
                    if (w_req_ctrl_ready) {
263
                        v.fetch_state = 3;
264
                        v.fetch_cnt = r.fetch_cnt.read() + 1;
265
                        v.fetch_wait_cnt = RADDR[r.fetch_cnt.read()].accept_wait;
266
                    } else {
267
                        v.fetch_state = 2;
268
                    }
269
                } else {
270
                    if (RADDR[r.fetch_cnt.read()].req_wait == 1) {
271
                        v.fetch_state = 2;
272
                    } else {
273
                        v.fetch_state = 1;
274
                    }
275
                    v.fetch_wait_cnt = RADDR[r.fetch_cnt.read()].req_wait;
276
                }
277
            }
278
            break;
279
        case 1:
280
            // wait to request:
281
            v.fetch_wait_cnt = r.fetch_wait_cnt.read() - 1;
282
            if (r.fetch_wait_cnt.read() == 1) {
283
                v.fetch_state = 2;
284
            }
285
            break;
286
        case 2:// wait ready signal
287
            w_req_ctrl_valid = 1;
288
            wb_req_ctrl_addr = RADDR[r.fetch_cnt.read()].raddr;
289
            if (w_req_ctrl_ready) {
290
                v.fetch_state = 3;
291
                v.fetch_cnt = r.fetch_cnt.read() + 1;
292
                v.fetch_wait_cnt = RADDR[r.fetch_cnt.read()].accept_wait;
293
            }
294
            break;
295
        case 3: // wait valid signal:
296
            if (w_resp_ctrl_valid) {
297
                w_resp_ctrl_ready = 1;
298
                if (r.fetch_wait_cnt.read()) {
299
                    v.fetch_wait_cnt = r.fetch_wait_cnt.read() - 1;
300
                    w_resp_ctrl_ready = 0;
301
                } else if (r.fetch_cnt.read() < 4) {
302
                    if (RADDR[r.fetch_cnt.read()].req_wait == 0) {
303
                        w_req_ctrl_valid = 1;
304
                        wb_req_ctrl_addr = RADDR[r.fetch_cnt.read()].raddr;
305
                        if (w_req_ctrl_ready) {
306
                            v.fetch_state = 3;
307
                            v.fetch_cnt = r.fetch_cnt.read() + 1;
308
                            v.fetch_wait_cnt = RADDR[r.fetch_cnt.read()].accept_wait;
309
                        } else {
310
                            v.fetch_state = 2;
311
                        }
312
                    } else {
313
                        if (RADDR[r.fetch_cnt.read()].req_wait == 1) {
314
                            v.fetch_state = 2;
315
                        } else {
316
                            v.fetch_state = 1;
317
                        }
318
                        v.fetch_wait_cnt = RADDR[r.fetch_cnt.read()].req_wait;
319
                    }
320
                } else {
321
                    v.fetch_state = 0;
322
                }
323
            }
324
            break;
325
        default:;
326
        }
327
    }
328
 
329
    if (r.clk_cnt.read() == 21) {
330
        wb_req_ctrl_addr = 0x100008f8;
331
    } else if (r.clk_cnt.read() == 22) {
332
        wb_req_ctrl_addr = 0x100007b4;
333
    }
334
 
335
 
336
    // Memory model:
337
    w_req_mem_ready = 0;
338
    w_resp_mem_data_valid = 0;
339
 
340
    switch (r.mem_state.read()) {
341
    case 0: // MemIdle
342
        if (w_req_mem_valid && r.mem_cnt.read() < 4) {
343
            if (MEM_DELAY[r.mem_cnt.read()].rdy_wait == 0) {
344
                if (MEM_DELAY[r.mem_cnt.read()].valid_wait == 0) {
345
                    v.mem_state = 3;
346
                    v.mem_raddr = wb_req_mem_addr;
347
                    w_req_mem_ready = 1;
348
                    v.mem_cnt = r.mem_cnt.read() + 1;
349
                } else {
350
                    v.mem_state = 2;
351
                    v.mem_wait_cnt = MEM_DELAY[r.mem_cnt.read()].valid_wait;
352
                }
353
            } else {
354
                v.mem_state = 1;
355
                v.mem_wait_cnt = MEM_DELAY[r.mem_cnt.read()].rdy_wait;
356
            }
357
        }
358
        break;
359
    case 1:
360
        v.mem_wait_cnt = r.mem_wait_cnt.read() - 1;
361
        if (r.mem_wait_cnt.read() == 1) {
362
            if (w_req_mem_valid) {
363
                v.mem_raddr = wb_req_mem_addr;
364
                w_req_mem_ready = 1;
365
                v.mem_cnt = r.mem_cnt.read() + 1;
366
                if (MEM_DELAY[r.mem_cnt.read()].valid_wait == 0) {
367
                    v.mem_state = 3;
368
                } else {
369
                    v.mem_state = 2;
370
                    v.mem_wait_cnt = MEM_DELAY[r.mem_cnt.read()].valid_wait;
371
                }
372
            } else {
373
                v.mem_state = 0;
374
            }
375
        }
376
        break;
377
    case 2:
378
        v.mem_wait_cnt = r.mem_wait_cnt.read() - 1;
379
        if (r.mem_wait_cnt.read() == 1) {
380
            v.mem_state = 3;
381
        }
382
        break;
383
    case 3:
384
        w_resp_mem_data_valid = 1;
385
        if (r.mem_raddr.read() == 0x100008f0) {
386
            wb_resp_mem_data = 0xffdff06fea9ff0efull;
387
        } else if (r.mem_raddr.read() == 0x100007b0) {
388
            wb_resp_mem_data = 0xfa0a0a1300004a17;
389
        }
390
 
391
        if (w_req_mem_valid && r.mem_cnt.read() < 4) {
392
            if (MEM_DELAY[r.mem_cnt.read()].rdy_wait == 0) {
393
                if (MEM_DELAY[r.mem_cnt.read()].valid_wait == 0) {
394
                    v.mem_state = 3;
395
                    v.mem_raddr = wb_req_mem_addr;
396
                    w_req_mem_ready = 1;
397
                    v.mem_cnt = r.mem_cnt.read() + 1;
398
                } else {
399
                    v.mem_state = 2;
400
                    v.mem_wait_cnt = MEM_DELAY[r.mem_cnt.read()].valid_wait;
401
                }
402
            } else {
403
                v.mem_state = 1;
404
                v.mem_wait_cnt = MEM_DELAY[r.mem_cnt.read()].rdy_wait;
405
            }
406
        } else {
407
            v.mem_state = 0;
408
        }
409
        break;
410
    default:;
411
    }
412
 
413
 
414
}
415
#endif
416
 
417
}  // namespace debugger
418
 

powered by: WebSVN 2.1.0

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