URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
Compare Revisions
- This comparison shows the changes necessary to convert path
/riscv_vhdl/trunk/debugger/src/cpu_sysc_plugin/riverlib/cache
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/cache_top.cpp
207,6 → 207,8
v.state = State_Idle; |
} |
|
w_ctrl_req_ready = 1; |
|
o_req_mem_valid = i.req_mem_valid | d.req_mem_valid; |
o_req_mem_write = w_mem_write; |
o_req_mem_addr = wb_mem_addr; |
/dcache.cpp
47,7 → 47,7
sc_trace(o_vcd, r.dline_addr_req, "/top/cache0/d0/r_dline_addr_req"); |
sc_trace(o_vcd, r.dline_size_req, "/top/cache0/d0/r_dline_size_req"); |
sc_trace(o_vcd, r.state, "/top/cache0/d0/r_state"); |
} |
sc_trace(o_vcd, w_wait_response, "/top/cache0/d0/w_wait_response"); } |
} |
|
void DCache::comb() { |
70,6 → 70,11
wb_o_resp_data = 0; |
wb_rtmp = 0; |
|
w_wait_response = 0; |
if (r.state.read() == State_WaitResp && i_resp_mem_data_valid.read() == 0) { |
w_wait_response = 1; |
} |
|
switch (i_req_data_sz.read()) { |
case 0: |
wb_o_req_wdata = (i_req_data_data.read()(7, 0), |
125,10 → 130,10
default:; |
} |
|
w_o_req_mem_valid = i_req_data_valid.read(); |
w_o_req_mem_valid = i_req_data_valid.read() && !w_wait_response; |
wb_o_req_mem_addr = i_req_data_addr.read()(BUS_ADDR_WIDTH-1, 3) << 3; |
w_o_req_data_ready = i_req_mem_ready.read(); |
w_req_fire = i_req_data_valid.read() && w_o_req_data_ready; |
w_req_fire = w_o_req_mem_valid && w_o_req_data_ready; |
switch (r.state.read()) { |
case State_Idle: |
if (i_req_data_valid.read()) { |
/dcache.h
61,10 → 61,9
sc_signal<sc_uint<2>> dline_size_req; |
sc_signal<sc_uint<2>> state; |
} v, r; |
|
bool w_wait_response; |
}; |
|
|
} // namespace debugger |
|
#endif // __DEBUGGER_RIVERLIB_DCACHE_H__ |
/icache.cpp
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief Instruction Cache. |
/* |
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
#include "icache.h" |
18,12 → 27,15
sensitive << i_resp_mem_data; |
sensitive << i_resp_ctrl_ready; |
sensitive << i_req_mem_ready; |
sensitive << r.iline_addr; |
sensitive << r.iline_data; |
sensitive << r.iline_addr_hit; |
sensitive << r.iline_data_hit; |
sensitive << r.iline[0].addr; |
sensitive << r.iline[0].data; |
sensitive << r.iline[1].addr; |
sensitive << r.iline[1].data; |
sensitive << r.iline_addr_req; |
sensitive << r.hit_line; |
sensitive << r.addr_processing; |
sensitive << r.double_req; |
sensitive << r.delay_valid; |
sensitive << r.delay_data; |
sensitive << r.state; |
|
SC_METHOD(registers); |
45,19 → 57,26
sc_trace(o_vcd, i_resp_ctrl_ready, "/top/cache0/i0/i_resp_ctrl_ready"); |
sc_trace(o_vcd, o_resp_ctrl_addr, "/top/cache0/i0/o_resp_ctrl_addr"); |
sc_trace(o_vcd, o_resp_ctrl_data, "/top/cache0/i0/o_resp_ctrl_data"); |
sc_trace(o_vcd, r.iline_addr, "/top/cache0/i0/r_iline_addr"); |
sc_trace(o_vcd, r.iline_data, "/top/cache0/i0/r_iline_data"); |
sc_trace(o_vcd, r.iline_addr_hit, "/top/cache0/i0/r_iline_addr_hit"); |
sc_trace(o_vcd, r.iline_data_hit, "/top/cache0/i0/r_iline_data_hit"); |
sc_trace(o_vcd, r.iline[0].addr, "/top/cache0/i0/r_iline(0)_addr"); |
sc_trace(o_vcd, r.iline[0].data, "/top/cache0/i0/r_iline(0)_data"); |
sc_trace(o_vcd, r.iline[1].addr, "/top/cache0/i0/r_iline(1)_addr"); |
sc_trace(o_vcd, r.iline[1].data, "/top/cache0/i0/r_iline(1)_data"); |
sc_trace(o_vcd, r.iline_addr_req, "/top/cache0/i0/r_iline_addr_req"); |
sc_trace(o_vcd, r.hit_line, "/top/cache0/i0/r_hit_line"); |
sc_trace(o_vcd, r.addr_processing, "/top/cache0/i0/r_addr_processing"); |
sc_trace(o_vcd, r.double_req, "/top/cache0/i0/double_req"); |
sc_trace(o_vcd, r.delay_valid, "/top/cache0/i0/r_delay_valid"); |
sc_trace(o_vcd, r.delay_data, "/top/cache0/i0/r_delay_valid"); |
sc_trace(o_vcd, r.state, "/top/cache0/i0/r_state"); |
sc_trace(o_vcd, w_hit, "/top/cache0/i0/w_hit"); |
sc_trace(o_vcd, w_hit_line, "/top/cache0/i0/w_hit_line"); |
sc_trace(o_vcd, w_hit_req, "/top/cache0/i0/w_hit_req"); |
//sc_trace(o_vcd, wb_req_line, "/top/cache0/i0/wb_req_line"); |
//sc_trace(o_vcd, wb_cached_addr, "/top/cache0/i0/wb_cached_addr"); |
//sc_trace(o_vcd, wb_cached_data, "/top/cache0/i0/wb_cached_data"); |
sc_trace(o_vcd, w_need_mem_req, "/top/cache0/i0/w_need_mem_req"); |
sc_trace(o_vcd, wb_l[0].hit, "/top/cache0/i0/wb_l(0)_hit"); |
sc_trace(o_vcd, wb_l[1].hit, "/top/cache0/i0/wb_l(1)_hit"); |
sc_trace(o_vcd, wb_l[0].hit_data, "/top/cache0/i0/wb_l(0)_hit_data"); |
sc_trace(o_vcd, wb_l[1].hit_data, "/top/cache0/i0/wb_l(1)_hit_data"); |
sc_trace(o_vcd, wb_hit_word, "/top/cache0/i0/wb_hit_word"); |
sc_trace(o_vcd, wb_l[0].hit_hold, "/top/cache0/i0/wb_l(0).hit_hold"); |
sc_trace(o_vcd, wb_l[1].hit_hold, "/top/cache0/i0/wb_l(1).hit_hold"); |
sc_trace(o_vcd, w_reuse_lastline, "/top/cache0/i0/w_reuse_lastline"); |
sc_trace(o_vcd, w_wait_response, "/top/cache0/i0/w_wait_response"); |
} |
} |
|
66,35 → 85,130
bool w_o_req_ctrl_ready; |
bool w_o_req_mem_valid; |
sc_uint<BUS_ADDR_WIDTH> wb_o_req_mem_addr; |
bool w_req_ctrl_valid; |
bool w_req_fire; |
bool w_o_resp_valid; |
sc_uint<BUS_ADDR_WIDTH> wb_o_resp_addr; |
sc_uint<32> wb_o_resp_data; |
sc_uint<BUS_ADDR_WIDTH - 3> wb_req_line; |
sc_uint<BUS_ADDR_WIDTH> wb_req_addr[2]; |
sc_uint<BUS_ADDR_WIDTH> wb_hold_addr[2]; |
|
v = r; |
w_hit_req = 0; |
w_hit_line = 0; |
w_hit = 0; |
|
wb_req_line = i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3); |
if (i_resp_mem_data_valid.read() |
&& (wb_req_line == r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3))) { |
w_hit_req = 1; |
w_wait_response = 0; |
if (r.state.read() == State_WaitResp && i_resp_mem_data_valid.read() == 0) { |
w_wait_response = 1; |
} |
if (wb_req_line == r.iline_addr.read()) { |
w_hit_line = 1; |
w_req_ctrl_valid = !w_wait_response |
&& (i_req_ctrl_valid.read() || r.double_req.read()); |
wb_req_addr[0] = i_req_ctrl_addr.read(); |
wb_req_addr[1] = i_req_ctrl_addr.read() + 2; |
|
wb_hold_addr[0] = r.addr_processing.read(); |
wb_hold_addr[1] = r.addr_processing.read() + 2; |
|
for (int i = 0; i < ILINE_TOTAL; i++) { |
wb_l[i].hit = 0; |
wb_l[i].hit_data = 0; |
if (wb_req_addr[i](BUS_ADDR_WIDTH-1, 3) == r.iline[0].addr.read()) { |
wb_l[i].hit[Hit_Line1] = w_req_ctrl_valid; |
wb_l[i].hit_data = r.iline[0].data.read(); |
} else if (wb_req_addr[i](BUS_ADDR_WIDTH-1, 3) == |
r.iline[1].addr.read()) { |
wb_l[i].hit[Hit_Line2] = w_req_ctrl_valid; |
wb_l[i].hit_data = r.iline[1].data.read(); |
} else if (wb_req_addr[i](BUS_ADDR_WIDTH-1, 3) == |
r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) { |
wb_l[i].hit[Hit_Response] = i_resp_mem_data_valid.read(); |
wb_l[i].hit_data = i_resp_mem_data.read(); |
} |
|
wb_l[i].hit_hold = 0; |
wb_l[i].hold_data = 0; |
if (wb_hold_addr[i](BUS_ADDR_WIDTH-1, 3) == r.iline[0].addr.read()) { |
wb_l[i].hit_hold[Hit_Line1] = 1; |
wb_l[i].hold_data = r.iline[0].data.read(); |
} else if (wb_hold_addr[i](BUS_ADDR_WIDTH-1, 3) == |
r.iline[1].addr.read()) { |
wb_l[i].hit_hold[Hit_Line2] = 1; |
wb_l[i].hold_data = r.iline[1].data.read(); |
} else if (wb_hold_addr[i](BUS_ADDR_WIDTH-1, 3) == |
r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) { |
wb_l[i].hold_data = i_resp_mem_data.read(); |
} |
} |
w_hit = w_hit_req || w_hit_line; |
|
w_o_req_mem_valid = !w_hit & i_req_ctrl_valid.read(); |
wb_o_req_mem_addr = i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3) << 3; |
w_o_req_ctrl_ready = w_hit | i_req_mem_ready.read(); |
w_req_fire = i_req_ctrl_valid.read() && w_o_req_ctrl_ready; |
wb_hit_word = 0; |
w_need_mem_req = 1; |
if (wb_l[0].hit != 0 && wb_l[1].hit != 0) { |
w_need_mem_req = 0; |
} |
switch (r.addr_processing.read()(2, 1)) { |
case 0: |
wb_hit_word = wb_l[0].hold_data(31, 0); |
break; |
case 1: |
wb_hit_word = wb_l[0].hold_data(47, 16); |
break; |
case 2: |
wb_hit_word = wb_l[0].hold_data(63, 32); |
break; |
default: |
wb_hit_word = (wb_l[1].hold_data(15, 0) << 16) |
| wb_l[0].hold_data(63, 48); |
} |
|
if (w_req_ctrl_valid && !w_need_mem_req) { |
v.delay_valid = 1; |
switch (i_req_ctrl_addr.read()(2, 1)) { |
case 0: |
v.delay_data = wb_l[0].hit_data(31, 0); |
break; |
case 1: |
v.delay_data = wb_l[0].hit_data(47, 16); |
break; |
case 2: |
v.delay_data = wb_l[0].hit_data(63, 32); |
break; |
default: |
v.delay_data = (wb_l[1].hit_data(15, 0) << 16) |
| wb_l[0].hit_data(63, 48); |
} |
} else if (i_resp_ctrl_ready.read()) { |
v.delay_valid = 0; |
v.delay_data = 0; |
} |
|
w_o_req_mem_valid = w_need_mem_req & w_req_ctrl_valid; |
if (r.double_req.read()) { |
if ((r.addr_processing.read()(BUS_ADDR_WIDTH-1, 3) == |
r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) |
|| (r.addr_processing.read()(BUS_ADDR_WIDTH-1, 3) == |
wb_hold_addr[0](BUS_ADDR_WIDTH-1, 3)) |
) { |
wb_o_req_mem_addr = wb_hold_addr[1](BUS_ADDR_WIDTH-1, 3) << 3; |
} else { |
wb_o_req_mem_addr = wb_hold_addr[0](BUS_ADDR_WIDTH-1, 3) << 3; |
} |
} else if (wb_l[0].hit == 0) { |
wb_o_req_mem_addr = wb_req_addr[0](BUS_ADDR_WIDTH-1, 3) << 3; |
} else { |
wb_o_req_mem_addr = wb_req_addr[1](BUS_ADDR_WIDTH-1, 3) << 3; |
} |
|
w_o_req_ctrl_ready = !w_need_mem_req |
| (i_req_mem_ready.read() & !w_wait_response); |
w_req_fire = w_req_ctrl_valid && w_o_req_ctrl_ready; |
|
if ((w_o_req_mem_valid && i_req_mem_ready.read() && !w_wait_response) |
|| r.double_req.read()) { |
v.iline_addr_req = wb_o_req_mem_addr; |
} |
|
switch (r.state.read()) { |
case State_Idle: |
if (i_req_ctrl_valid.read()) { |
if (w_hit_line) { |
if (w_req_ctrl_valid) { |
if (!w_need_mem_req) { |
v.state = State_WaitAccept; |
} else if (i_req_mem_ready.read()) { |
v.state = State_WaitResp; |
106,7 → 220,7
case State_WaitGrant: |
if (i_req_mem_ready.read()) { |
v.state = State_WaitResp; |
} else if (w_hit) { |
} else if (!w_need_mem_req) { |
/** Fetcher can change request address while request wasn't |
* accepteed. */ |
v.state = State_WaitAccept; |
116,11 → 230,11
if (i_resp_mem_data_valid.read()) { |
if (!i_resp_ctrl_ready.read()) { |
v.state = State_WaitAccept; |
} else if (!i_req_ctrl_valid.read()) { |
} else if (!w_req_ctrl_valid) { |
v.state = State_Idle; |
} else { |
// New request |
if (w_hit) { |
if (!w_need_mem_req) { |
v.state = State_WaitAccept; |
} else if (i_req_mem_ready.read()) { |
v.state = State_WaitResp; |
132,10 → 246,10
break; |
case State_WaitAccept: |
if (i_resp_ctrl_ready.read()) { |
if (!i_req_ctrl_valid.read()) { |
if (!w_req_ctrl_valid) { |
v.state = State_Idle; |
} else { |
if (w_hit) { |
if (!w_need_mem_req) { |
v.state = State_WaitAccept; |
} else if (i_req_mem_ready.read()) { |
v.state = State_WaitResp; |
149,54 → 263,69
} |
|
if (w_req_fire) { |
v.iline_addr_req = i_req_ctrl_addr; |
v.hit_line = 0; |
if (w_hit_line) { |
v.hit_line = 1; |
v.iline_addr_hit = i_req_ctrl_addr; |
if (i_req_ctrl_addr.read()[2] == 0) { |
v.iline_data_hit = r.iline_data.read()(31, 0); |
} else { |
v.iline_data_hit = r.iline_data.read()(63, 32); |
} |
v.double_req = 0; |
if (i_req_ctrl_addr.read()(2, 1) == 0x3 |
&& wb_l[0].hit == 0 && wb_l[1].hit == 0 |
&& r.double_req.read() == 0) { |
v.double_req = 1; |
} |
if (!r.double_req.read()) { |
v.addr_processing = i_req_ctrl_addr; |
} |
} |
|
w_reuse_lastline = 0; |
|
if (i_resp_mem_data_valid.read()) { |
v.iline_addr = r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3); |
v.iline_data = i_resp_mem_data; |
} |
|
wb_o_resp_addr = r.iline_addr_req; |
if (r.state.read() == State_WaitAccept) { |
w_o_resp_valid = 1; |
if (r.hit_line) { |
wb_o_resp_addr = r.iline_addr_hit; |
wb_o_resp_data = r.iline_data_hit; |
/** Condition to avoid removing the last line: |
*/ |
if (i_resp_ctrl_ready.read()) { |
if ((wb_l[0].hit[Hit_Line2] || wb_l[1].hit[Hit_Line2]) == 1 |
&& r.iline[1].addr.read() |
!= i_req_ctrl_addr.read()(BUS_ADDR_WIDTH-1, 3)) { |
w_reuse_lastline = w_need_mem_req; |
} |
} else { |
if (r.iline_addr_req.read()[2] == 0) { |
wb_o_resp_data = r.iline_data.read()(31, 0); |
} else { |
wb_o_resp_data = r.iline_data.read()(63, 32); |
if ((wb_l[0].hit_hold[Hit_Line2] || wb_l[1].hit_hold[Hit_Line2]) == 1 |
&& (wb_l[0].hit_hold[Hit_Line1] || wb_l[1].hit_hold[Hit_Line1]) == 0 |
&& r.iline[1].addr.read() |
!= r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3)) { |
w_reuse_lastline = 1; |
} |
} |
} else { |
w_o_resp_valid = i_resp_mem_data_valid; |
if (r.iline_addr_req.read()[2] == 0) { |
wb_o_resp_data = i_resp_mem_data.read()(31, 0); |
} else { |
wb_o_resp_data = i_resp_mem_data.read()(63, 32); |
if (!w_reuse_lastline) { |
v.iline[1].addr = r.iline[0].addr; |
v.iline[1].data = r.iline[0].data; |
} |
|
v.iline[0].addr = r.iline_addr_req.read()(BUS_ADDR_WIDTH-1, 3); |
v.iline[0].data = i_resp_mem_data; |
} |
|
if (r.state.read() == State_WaitAccept) { |
w_o_resp_valid = !r.double_req.read(); |
} else { |
w_o_resp_valid = i_resp_mem_data_valid && !r.double_req.read(); |
} |
if (r.delay_valid.read()) { |
wb_o_resp_data = r.delay_data.read(); |
} else { |
wb_o_resp_data = wb_hit_word; |
} |
wb_o_resp_addr = r.addr_processing; |
|
|
if (!i_nrst.read()) { |
v.iline[0].addr = ~0; |
v.iline[0].data = 0; |
v.iline[1].addr = ~0; |
v.iline[1].data = 0; |
v.iline_addr_req = 0; |
v.iline_addr = ~0; |
v.iline_data = 0; |
v.iline_addr_hit = ~0; |
v.iline_data_hit = 0; |
v.hit_line = 0; |
v.addr_processing = 0; |
v.state = State_Idle; |
v.double_req = 0; |
v.delay_valid = 0; |
v.delay_data = 0; |
} |
|
o_req_ctrl_ready = w_o_req_ctrl_ready; |
/icache.h
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief Instruction Cache. |
/* |
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
#ifndef __DEBUGGER_RIVERLIB_ICACHE_H__ |
53,19 → 62,39
State_WaitResp, |
State_WaitAccept |
}; |
enum EHit { |
Hit_Line1, |
Hit_Line2, |
Hit_Response, |
Hit_Total |
}; |
static const int ILINE_TOTAL = 2; |
|
struct line_type { |
sc_signal<sc_uint<BUS_ADDR_WIDTH - 3>> addr; |
sc_signal<sc_uint<BUS_DATA_WIDTH>> data; |
}; |
struct line_signal_type { |
sc_bv<ILINE_TOTAL + 1> hit; // Hit_Total = ILINE_TOTAL + 1 |
sc_bv<ILINE_TOTAL> hit_hold; |
sc_uint<BUS_DATA_WIDTH> hit_data; |
sc_uint<BUS_DATA_WIDTH> hold_data; |
}; |
|
struct RegistersType { |
sc_signal<sc_uint<BUS_ADDR_WIDTH - 3>> iline_addr; |
sc_signal<sc_uint<BUS_DATA_WIDTH>> iline_data; |
line_type iline[ILINE_TOTAL]; |
sc_signal<sc_uint<BUS_ADDR_WIDTH>> iline_addr_req; |
sc_signal<sc_uint<32>> iline_data_hit; |
sc_signal<sc_uint<BUS_ADDR_WIDTH>> iline_addr_hit; |
sc_signal<sc_uint<BUS_ADDR_WIDTH>> addr_processing; |
sc_signal<sc_uint<2>> state; |
sc_signal<bool> hit_line; |
sc_signal<bool> double_req; // request 2-lines |
sc_signal<bool> delay_valid; |
sc_signal<sc_uint<32>> delay_data; |
} v, r; |
bool w_hit_req; |
bool w_hit_line; |
bool w_hit; |
bool w_need_mem_req; |
sc_uint<32> wb_hit_word; |
line_signal_type wb_l[ILINE_TOTAL]; |
bool w_reuse_lastline; |
bool w_wait_response; |
}; |
|
|