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
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/cache/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; |
/cache/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()) { |
/cache/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__ |
/cache/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; |
/cache/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; |
}; |
|
|
/core/br_predic.cpp
1,9 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief Branch Predictor. |
* @details This module gives about 5% of performance improvement (CPI) |
/* |
* 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 "br_predic.h" |
21,6 → 29,8
sensitive << i_e_npc; |
sensitive << i_ra; |
sensitive << r.npc; |
sensitive << r.resp_mem_data; |
sensitive << r.resp_mem_addr; |
|
SC_METHOD(registers); |
sensitive << i_clk.pos(); |
38,52 → 48,57
|
sc_trace(o_vcd, o_npc_predict, "/top/proc0/bp0/o_npc_predict"); |
sc_trace(o_vcd, r.npc, "/top/proc0/bp0/r_npc"); |
sc_trace(o_vcd, r.resp_mem_data, "/top/proc0/bp0/r_resp_mem_data"); |
sc_trace(o_vcd, r.resp_mem_addr, "/top/proc0/bp0/r_resp_mem_addr"); |
sc_trace(o_vcd, wb_npc, "/top/proc0/bp0/wb_npc"); |
} |
} |
|
void BranchPredictor::comb() { |
v = r; |
sc_uint<BUS_ADDR_WIDTH> wb_jal_off; |
sc_uint<32> wb_tmp; |
sc_uint<BUS_ADDR_WIDTH> wb_npc; |
sc_uint<BUS_ADDR_WIDTH> wb_off; |
|
wb_tmp = i_resp_mem_data.read(); |
if (i_f_predic_miss.read()) { |
wb_npc = i_e_npc.read() + 4; |
} else { |
wb_npc = r.npc.read() + 4; |
if (i_resp_mem_valid.read()) { |
v.resp_mem_addr = i_resp_mem_addr.read(); |
v.resp_mem_data = i_resp_mem_data.read(); |
} |
wb_tmp = r.resp_mem_data.read(); |
wb_npc = r.npc.read(); |
|
|
if (wb_tmp[31]) { |
wb_off(BUS_ADDR_WIDTH-1, 20) = ~0; |
wb_jal_off(BUS_ADDR_WIDTH-1, 20) = ~0; |
} else { |
wb_off(BUS_ADDR_WIDTH-1, 20) = 0; |
wb_jal_off(BUS_ADDR_WIDTH-1, 20) = 0; |
} |
wb_off(19, 12) = wb_tmp(19, 12); |
wb_off[11] = wb_tmp[20]; |
wb_off(10, 1) = wb_tmp(30, 21); |
wb_off[0] = 0; |
wb_jal_off(19, 12) = wb_tmp(19, 12); |
wb_jal_off[11] = wb_tmp[20]; |
wb_jal_off(10, 1) = wb_tmp(30, 21); |
wb_jal_off[0] = 0; |
|
if (i_resp_mem_valid.read()) { |
if (wb_tmp == 0x00008067) { |
// ret pseudo-instruction: Dhry score 34816 -> 35136 |
v.npc = i_ra.read()(BUS_ADDR_WIDTH-1, 0); |
} else if (wb_tmp(6, 0) == 0x6f) { |
// jal instruction: Dhry score 35136 -> 36992 |
v.npc = i_resp_mem_addr.read() + wb_off; |
} else if (i_req_mem_fire.read()) { |
v.npc = wb_npc; |
} |
} else if (i_req_mem_fire.read()) { |
if (i_f_predic_miss.read()) { |
wb_npc = i_e_npc.read(); |
} else if (wb_tmp == 0x00008067) { |
// ret32 pseudo-instruction: |
wb_npc = i_ra.read()(BUS_ADDR_WIDTH-1, 0); |
//} else if (wb_tmp(6, 0) == 0x6f) { |
// jal instruction: Dhry score 35136 -> 36992 |
//wb_npc = r.resp_mem_addr.read() + wb_jal_off; |
} else { |
wb_npc = r.npc.read() + 2; |
} |
|
if (i_req_mem_fire.read()) { |
v.npc = wb_npc; |
} |
|
if (!i_nrst.read()) { |
v.npc = RESET_VECTOR; |
v.npc = RESET_VECTOR - 2; |
v.resp_mem_addr = RESET_VECTOR; |
v.resp_mem_data = 0; |
} |
|
o_npc_predict = r.npc; |
o_npc_predict = wb_npc; |
} |
|
void BranchPredictor::registers() { |
/core/br_predic.h
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief Branch predictor. |
/* |
* 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_BR_PREDIC_H__ |
37,8 → 46,10
private: |
struct RegistersType { |
sc_signal<sc_uint<BUS_ADDR_WIDTH>> npc; |
sc_signal<sc_uint<BUS_ADDR_WIDTH>> resp_mem_addr; |
sc_signal<sc_uint<32>> resp_mem_data; |
} v, r; |
sc_signal<sc_uint<BUS_ADDR_WIDTH>> wb_npc; |
sc_uint<BUS_ADDR_WIDTH> wb_npc; |
}; |
|
|
/core/csr.cpp
iwdata,
+ RegistersType &ir, RegistersType *ov,
+ sc_uint *ordata) {
+ *ordata = 0;
+ switch (iaddr) {
+ case CSR_misa:
+ /** Base[XLEN-1:XLEN-2]
+ * 1 = 32
+ * 2 = 64
+ * 3 = 128
+ */
+ (*ordata)(RISCV_ARCH-1, RISCV_ARCH-2) = 2;
+ /** BitCharacterDescription
+ * 0 A Atomic extension
+ * 1 B Tentatively reserved for Bit operations extension
+ * 2 C Compressed extension
+ * 3 D Double-precision Foating-point extension
+ * 4 E RV32E base ISA (embedded)
+ * 5 F Single-precision Foating-point extension
+ * 6 G Additional standard extensions present
+ * 7 H Hypervisor mode implemented
+ * 8 I RV32I/64I/128I base ISA
+ * 9 J Reserved
+ * 10 K Reserved
+ * 11 L Tentatively reserved for Decimal Floating-Point extension
+ * 12 M Integer Multiply/Divide extension
+ * 13 N User-level interrupts supported
+ * 14 O Reserved
+ * 15 P Tentatively reserved for Packed-SIMD extension
* 16 Q Quad-precision Foating-point extension
* 17 R Reserved
* 18 S Supervisor mode implemented
@@ -103,148 +113,149 @@
* 24 Y Reserved
* 25 Z Reserve
*/
- //(*ordata)['A' - 'A'] = 1;
- (*ordata)['I' - 'A'] = 1;
- (*ordata)['M' - 'A'] = 1;
- (*ordata)['U' - 'A'] = 1;
- break;
- case CSR_mvendorid:
- break;
- case CSR_marchid:
- break;
- case CSR_mimplementationid:
- break;
- case CSR_mhartid:
- break;
- case CSR_uepc:// - User mode program counter
- break;
- case CSR_mstatus:// - Machine mode status register
- (*ordata)[0] = ir.uie;
- (*ordata)[3] = ir.mie;
- (*ordata)[7] = ir.mpie;
- (*ordata)(12, 11) = ir.mpp;
- if (iwena) {
- ov->uie = iwdata[0];
- ov->mie = iwdata[3];
- ov->mpie = iwdata[7];
- ov->mpp = iwdata(12, 11);
- }
- break;
- case CSR_medeleg:// - Machine exception delegation
- break;
- case CSR_mideleg:// - Machine itnerrupt delegation
- break;
- case CSR_mie:// - Machine interrupt enable bit
- break;
- case CSR_mtvec:
- (*ordata) = ir.mtvec;
- if (iwena) {
- ov->mtvec = iwdata;
- }
- break;
- case CSR_mtimecmp:// - Machine wall-clock timer compare value
- break;
- case CSR_mscratch:// - Machine scratch register
- (*ordata) = ir.mscratch;
- if (iwena) {
- ov->mscratch = iwdata;
- }
- break;
- case CSR_mepc:// - Machine program counter
- (*ordata) = ir.mepc;
- if (iwena) {
- ov->mepc = iwdata;
- }
- break;
- case CSR_mcause:// - Machine trap cause
- (*ordata) = 0;
- (*ordata)[63] = ir.trap_irq;
- (*ordata)(3, 0) = ir.trap_code;
- break;
- case CSR_mbadaddr:// - Machine bad address
- (*ordata) = ir.mbadaddr;
- break;
- case CSR_mip:// - Machine interrupt pending
- break;
- default:;
- }
-
-}
-
-void CsrRegs::comb() {
- sc_uint wb_rdata = 0;
- sc_uint wb_dport_rdata = 0;
- bool w_ie;
- bool w_dport_wena;
-
- v = r;
-
- w_dport_wena = i_dport_ena & i_dport_write;
-
- procedure_RegAccess(i_addr.read(), i_wena.read(), i_wdata.read(),
- r, &v, &wb_rdata);
-
- procedure_RegAccess(i_dport_addr.read(), w_dport_wena,
- i_dport_wdata.read(), r, &v, &wb_dport_rdata);
-
-
- if (i_addr.read() == CSR_mepc && i_xret.read()) {
- // Switch to previous mode
- v.mie = r.mpie;
- v.mpie = 1;
- v.mode = r.mpp;
- v.mpp = PRV_U;
- }
-
- if (i_trap_ena.read() && (i_break_mode.read() || !i_breakpoint.read())) {
- v.mie = 0;
- v.mpp = r.mode;
- v.mepc = i_trap_pc.read();
- v.mbadaddr = i_trap_pc.read();
- v.trap_code = i_trap_code.read()(3, 0);
- v.trap_irq = i_trap_code.read()[4];
- v.mode = PRV_M;
- switch (r.mode.read()) {
- case PRV_U:
- v.mpie = r.uie;
- break;
- case PRV_M:
- v.mpie = r.mie;
- break;
- default:;
- }
- }
-
- w_ie = 0;
- if ((r.mode.read() != PRV_M) || r.mie.read()) {
- w_ie = 1;
- }
-
- if (!i_nrst.read()) {
- v.mtvec = 0;
- v.mscratch = 0;
- v.mbadaddr = 0;
- v.mode = PRV_M;
- v.uie = 0;
- v.mie = 0;
- v.mpie = 0;
- v.mpp = 0;
- v.mepc = 0;
- v.trap_code = 0;
- v.trap_irq = 0;
- }
-
-
- o_rdata = wb_rdata;
- o_ie = w_ie;
- o_mode = r.mode;
- o_mtvec = r.mtvec.read()(BUS_ADDR_WIDTH - 1, 0);
- o_dport_rdata = wb_dport_rdata;
-}
-
-void CsrRegs::registers() {
- r = v;
-}
-
-} // namespace debugger
-
+ //(*ordata)['A' - 'A'] = 1;
+ (*ordata)['I' - 'A'] = 1;
+ (*ordata)['M' - 'A'] = 1;
+ (*ordata)['U' - 'A'] = 1;
+ (*ordata)['C' - 'A'] = 1;
+ break;
+ case CSR_mvendorid:
+ break;
+ case CSR_marchid:
+ break;
+ case CSR_mimplementationid:
+ break;
+ case CSR_mhartid:
+ break;
+ case CSR_uepc:// - User mode program counter
+ break;
+ case CSR_mstatus:// - Machine mode status register
+ (*ordata)[0] = ir.uie;
+ (*ordata)[3] = ir.mie;
+ (*ordata)[7] = ir.mpie;
+ (*ordata)(12, 11) = ir.mpp;
+ if (iwena) {
+ ov->uie = iwdata[0];
+ ov->mie = iwdata[3];
+ ov->mpie = iwdata[7];
+ ov->mpp = iwdata(12, 11);
+ }
+ break;
+ case CSR_medeleg:// - Machine exception delegation
+ break;
+ case CSR_mideleg:// - Machine itnerrupt delegation
+ break;
+ case CSR_mie:// - Machine interrupt enable bit
+ break;
+ case CSR_mtvec:
+ (*ordata) = ir.mtvec;
+ if (iwena) {
+ ov->mtvec = iwdata;
+ }
+ break;
+ case CSR_mtimecmp:// - Machine wall-clock timer compare value
+ break;
+ case CSR_mscratch:// - Machine scratch register
+ (*ordata) = ir.mscratch;
+ if (iwena) {
+ ov->mscratch = iwdata;
+ }
+ break;
+ case CSR_mepc:// - Machine program counter
+ (*ordata) = ir.mepc;
+ if (iwena) {
+ ov->mepc = iwdata;
+ }
+ break;
+ case CSR_mcause:// - Machine trap cause
+ (*ordata) = 0;
+ (*ordata)[63] = ir.trap_irq;
+ (*ordata)(3, 0) = ir.trap_code;
+ break;
+ case CSR_mbadaddr:// - Machine bad address
+ (*ordata) = ir.mbadaddr;
+ break;
+ case CSR_mip:// - Machine interrupt pending
+ break;
+ default:;
+ }
+
+}
+
+void CsrRegs::comb() {
+ sc_uint wb_rdata = 0;
+ sc_uint wb_dport_rdata = 0;
+ bool w_ie;
+ bool w_dport_wena;
+
+ v = r;
+
+ w_dport_wena = i_dport_ena & i_dport_write;
+
+ procedure_RegAccess(i_addr.read(), i_wena.read(), i_wdata.read(),
+ r, &v, &wb_rdata);
+
+ procedure_RegAccess(i_dport_addr.read(), w_dport_wena,
+ i_dport_wdata.read(), r, &v, &wb_dport_rdata);
+
+
+ if (i_addr.read() == CSR_mepc && i_xret.read()) {
+ // Switch to previous mode
+ v.mie = r.mpie;
+ v.mpie = 1;
+ v.mode = r.mpp;
+ v.mpp = PRV_U;
+ }
+
+ if (i_trap_ena.read() && (i_break_mode.read() || !i_breakpoint.read())) {
+ v.mie = 0;
+ v.mpp = r.mode;
+ v.mepc = i_trap_pc.read();
+ v.mbadaddr = i_trap_pc.read();
+ v.trap_code = i_trap_code.read()(3, 0);
+ v.trap_irq = i_trap_code.read()[4];
+ v.mode = PRV_M;
+ switch (r.mode.read()) {
+ case PRV_U:
+ v.mpie = r.uie;
+ break;
+ case PRV_M:
+ v.mpie = r.mie;
+ break;
+ default:;
+ }
+ }
+
+ w_ie = 0;
+ if ((r.mode.read() != PRV_M) || r.mie.read()) {
+ w_ie = 1;
+ }
+
+ if (!i_nrst.read()) {
+ v.mtvec = 0;
+ v.mscratch = 0;
+ v.mbadaddr = 0;
+ v.mode = PRV_M;
+ v.uie = 0;
+ v.mie = 0;
+ v.mpie = 0;
+ v.mpp = 0;
+ v.mepc = 0;
+ v.trap_code = 0;
+ v.trap_irq = 0;
+ }
+
+
+ o_rdata = wb_rdata;
+ o_ie = w_ie;
+ o_mode = r.mode;
+ o_mtvec = r.mtvec.read()(BUS_ADDR_WIDTH - 1, 0);
+ o_dport_rdata = wb_dport_rdata;
+}
+
+void CsrRegs::registers() {
+ r = v;
+}
+
+} // namespace debugger
+
1,97 → 1,107
+/*
+ * 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 "csr.h"
+#include "riscv-isa.h"
+
+namespace debugger {
+
+CsrRegs::CsrRegs(sc_module_name name_) : sc_module(name_) {
+ SC_METHOD(comb);
+ sensitive << i_nrst;
+ sensitive << i_xret;
+ sensitive << i_addr;
+ sensitive << i_wena;
+ sensitive << i_wdata;
+ sensitive << i_break_mode;
+ sensitive << i_breakpoint;
+ sensitive << i_trap_ena;
+ sensitive << i_trap_code;
+ sensitive << i_trap_pc;
+ sensitive << i_dport_ena;
+ sensitive << i_dport_write;
+ sensitive << i_dport_addr;
+ sensitive << i_dport_wdata;
+ sensitive << r.mtvec;
+ sensitive << r.mscratch;
+ sensitive << r.mbadaddr;
+ sensitive << r.mode;
+ sensitive << r.uie;
+ sensitive << r.mie;
+ sensitive << r.mpie;
+ sensitive << r.mpp;
+ sensitive << r.mepc;
+ sensitive << r.trap_irq;
+ sensitive << r.trap_code;
+
+ SC_METHOD(registers);
+ sensitive << i_clk.pos();
+};
+
+void CsrRegs::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) {
+ if (o_vcd) {
+ sc_trace(o_vcd, i_xret, "/top/proc0/csr0/i_xret");
+ sc_trace(o_vcd, i_addr, "/top/proc0/csr0/i_addr");
+ sc_trace(o_vcd, i_wena, "/top/proc0/csr0/i_wena");
+ sc_trace(o_vcd, i_wdata, "/top/proc0/csr0/i_wdata");
+ sc_trace(o_vcd, i_trap_ena, "/top/proc0/csr0/i_trap_ena");
+ sc_trace(o_vcd, i_trap_code, "/top/proc0/csr0/i_trap_code");
+ sc_trace(o_vcd, i_trap_pc, "/top/proc0/csr0/i_trap_pc");
+ sc_trace(o_vcd, o_mode, "/top/proc0/csr0/o_mode");
+ sc_trace(o_vcd, o_ie, "/top/proc0/csr0/o_ie");
+ sc_trace(o_vcd, o_rdata, "/top/proc0/csr0/o_rdata");
+ sc_trace(o_vcd, o_mtvec, "/top/proc0/csr0/o_mtvec");
+ sc_trace(o_vcd, i_dport_ena, "/top/proc0/csr0/i_dport_ena");
+ sc_trace(o_vcd, i_dport_write, "/top/proc0/csr0/i_dport_write");
+ sc_trace(o_vcd, i_dport_addr, "/top/proc0/csr0/i_dport_addr");
+ sc_trace(o_vcd, i_dport_wdata, "/top/proc0/csr0/i_dport_wdata");
+ sc_trace(o_vcd, o_dport_rdata, "/top/proc0/csr0/o_dport_rdata");
+ }
+}
+
+void CsrRegs::procedure_RegAccess(uint64_t iaddr, bool iwena,
+ sc_uint/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief CSR registers module. |
*/ |
|
#include "csr.h" |
#include "riscv-isa.h" |
|
namespace debugger { |
|
CsrRegs::CsrRegs(sc_module_name name_) : sc_module(name_) { |
SC_METHOD(comb); |
sensitive << i_nrst; |
sensitive << i_xret; |
sensitive << i_addr; |
sensitive << i_wena; |
sensitive << i_wdata; |
sensitive << i_break_mode; |
sensitive << i_breakpoint; |
sensitive << i_trap_ena; |
sensitive << i_trap_code; |
sensitive << i_trap_pc; |
sensitive << i_dport_ena; |
sensitive << i_dport_write; |
sensitive << i_dport_addr; |
sensitive << i_dport_wdata; |
sensitive << r.mtvec; |
sensitive << r.mscratch; |
sensitive << r.mbadaddr; |
sensitive << r.mode; |
sensitive << r.uie; |
sensitive << r.mie; |
sensitive << r.mpie; |
sensitive << r.mpp; |
sensitive << r.mepc; |
sensitive << r.trap_irq; |
sensitive << r.trap_code; |
|
SC_METHOD(registers); |
sensitive << i_clk.pos(); |
}; |
|
void CsrRegs::generateVCD(sc_trace_file *i_vcd, sc_trace_file *o_vcd) { |
if (o_vcd) { |
sc_trace(o_vcd, i_xret, "/top/proc0/csr0/i_xret"); |
sc_trace(o_vcd, i_addr, "/top/proc0/csr0/i_addr"); |
sc_trace(o_vcd, i_wena, "/top/proc0/csr0/i_wena"); |
sc_trace(o_vcd, i_wdata, "/top/proc0/csr0/i_wdata"); |
sc_trace(o_vcd, i_trap_ena, "/top/proc0/csr0/i_trap_ena"); |
sc_trace(o_vcd, i_trap_code, "/top/proc0/csr0/i_trap_code"); |
sc_trace(o_vcd, i_trap_pc, "/top/proc0/csr0/i_trap_pc"); |
sc_trace(o_vcd, o_mode, "/top/proc0/csr0/o_mode"); |
sc_trace(o_vcd, o_ie, "/top/proc0/csr0/o_ie"); |
sc_trace(o_vcd, o_rdata, "/top/proc0/csr0/o_rdata"); |
sc_trace(o_vcd, o_mtvec, "/top/proc0/csr0/o_mtvec"); |
sc_trace(o_vcd, i_dport_ena, "/top/proc0/csr0/i_dport_ena"); |
sc_trace(o_vcd, i_dport_write, "/top/proc0/csr0/i_dport_write"); |
sc_trace(o_vcd, i_dport_addr, "/top/proc0/csr0/i_dport_addr"); |
sc_trace(o_vcd, i_dport_wdata, "/top/proc0/csr0/i_dport_wdata"); |
sc_trace(o_vcd, o_dport_rdata, "/top/proc0/csr0/o_dport_rdata"); |
} |
} |
|
void CsrRegs::procedure_RegAccess(uint64_t iaddr, bool iwena, |
sc_uint<RISCV_ARCH> iwdata, |
RegistersType &ir, RegistersType *ov, |
sc_uint<RISCV_ARCH> *ordata) { |
*ordata = 0; |
switch (iaddr) { |
case CSR_misa: |
/** Base[XLEN-1:XLEN-2] |
* 1 = 32 |
* 2 = 64 |
* 3 = 128 |
*/ |
(*ordata)(RISCV_ARCH-1, RISCV_ARCH-2) = 2; |
/core/csr.h
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief CSR registers module. |
/* |
* 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_CSR_H__ |
/core/decoder.cpp
35,6 → 35,7
sc_trace(o_vcd, o_isa_type, "/top/proc0/dec0/o_isa_type"); |
sc_trace(o_vcd, o_instr_vec, "/top/proc0/dec0/o_instr_vec"); |
sc_trace(o_vcd, o_exception, "/top/proc0/dec0/o_exception"); |
sc_trace(o_vcd, o_compressed, "/top/proc0/dec0/o_compressed"); |
} |
} |
|
43,352 → 44,617
|
bool w_o_valid; |
bool w_error = false; |
bool w_compressed = false; |
sc_uint<32> wb_instr = i_f_instr.read(); |
sc_uint<5> wb_opcode1 = wb_instr(6, 2); |
sc_uint<3> wb_opcode2 = wb_instr(14, 12); |
sc_uint<32> wb_instr_out; |
sc_uint<5> wb_opcode1; |
sc_uint<3> wb_opcode2; |
sc_bv<Instr_Total> wb_dec = 0; |
sc_bv<ISA_Total> wb_isa_type = 0; |
|
if (wb_instr(1, 0) != 0x3) { |
w_error = true; |
} |
|
switch (wb_opcode1) { |
case OPCODE_ADD: |
wb_isa_type[ISA_R_type] = 1; |
switch (wb_opcode2) { |
case 0: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_ADD] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_MUL] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SUB] = 1; |
} else { |
w_error = true; |
w_compressed = 1; |
wb_opcode1 = (wb_instr(15, 13), wb_instr(1, 0)); |
wb_instr_out = 0x00000003; |
switch (wb_opcode1) { |
case OPCODE_C_ADDI4SPN: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_ADDI] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(4, 2); // rd |
wb_instr_out(19, 15) = 0x2; // rs1 = sp |
wb_instr_out(29, 22) = |
(wb_instr(10, 7), wb_instr(12, 11), wb_instr[5], wb_instr[6]); |
break; |
case OPCODE_C_NOP_ADDI: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_ADDI] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = wb_instr(11, 7); // rs1 |
wb_instr_out(24, 20) = wb_instr(6, 2); // imm |
if (wb_instr[12]) { |
wb_instr_out(31, 25) = ~0; |
} |
break; |
case 0x1: |
wb_dec[Instr_SLL] = 1; |
case OPCODE_C_SLLI: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_SLLI] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = wb_instr(11, 7); // rs1 |
wb_instr_out(25, 20) = (wb_instr[12], wb_instr(6, 2)); // shamt |
break; |
case 0x2: |
wb_dec[Instr_SLT] = 1; |
case OPCODE_C_JAL_ADDIW: |
// JAL is the RV32C only instruction |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_ADDIW] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = wb_instr(11, 7); // rs1 |
wb_instr_out(24, 20) = wb_instr(6, 2); // imm |
if (wb_instr[12]) { |
wb_instr_out(31, 25) = ~0; |
} |
break; |
case 0x3: |
wb_dec[Instr_SLTU] = 1; |
case OPCODE_C_LW: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_LW] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(4, 2); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(26, 22) = |
(wb_instr[5], wb_instr(12, 10), wb_instr[6]); |
break; |
case 0x4: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_XOR] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIV] = 1; |
} else { |
w_error = true; |
case OPCODE_C_LI: // ADDI rd = r0 + imm |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_ADDI] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(24, 20) = wb_instr(6, 2); // imm |
if (wb_instr[12]) { |
wb_instr_out(31, 25) = ~0; |
} |
break; |
case 0x5: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_SRL] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIVU] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SRA] = 1; |
case OPCODE_C_LWSP: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_LW] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = 0x2; // rs1 = sp |
wb_instr_out(27, 22) = |
(wb_instr(3, 2), wb_instr[12], wb_instr(6, 4)); |
break; |
case OPCODE_C_LD: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_LD] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(4, 2); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(27, 23) = |
(wb_instr[6], wb_instr[5], wb_instr(12, 10)); |
break; |
case OPCODE_C_ADDI16SP_LUI: |
if (wb_instr(11, 7) == 0x2) { |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_ADDI] = 1; |
wb_instr_out(11, 7) = 0x2; // rd = sp |
wb_instr_out(19, 15) = 0x2; // rs1 = sp |
wb_instr_out(28, 24) = |
(wb_instr(4, 3), wb_instr[5], wb_instr[2], wb_instr[6]); |
if (wb_instr[12]) { |
wb_instr_out(31, 29) = ~0; |
} |
} else { |
w_error = true; |
wb_isa_type[ISA_U_type] = 1; |
wb_dec[Instr_LUI] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(16, 12) = wb_instr(6, 2); |
if (wb_instr[12]) { |
wb_instr_out(31, 17) = ~0; |
} |
} |
break; |
case 0x6: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_OR] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REM] = 1; |
case OPCODE_C_LDSP: |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_LD] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = 0x2; // rs1 = sp |
wb_instr_out(28, 23) = |
(wb_instr(4, 2), wb_instr[12], wb_instr(6, 5)); |
break; |
case OPCODE_C_MATH: |
if (wb_instr(11, 10) == 0) { |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_SRLI] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(9, 7); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(25, 20) = (wb_instr[12], wb_instr(6, 2)); // shamt |
} else if (wb_instr(11, 10) == 1) { |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_SRAI] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(9, 7); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(25, 20) = (wb_instr[12], wb_instr(6, 2)); // shamt |
} else if (wb_instr(11, 10) == 2) { |
wb_isa_type[ISA_I_type] = 1; |
wb_dec[Instr_ANDI] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(9, 7); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(24, 20) = wb_instr(6, 2); // imm |
if (wb_instr[12]) { |
wb_instr_out(31, 25) = ~0; |
} |
} else if (wb_instr[12] == 0) { |
wb_isa_type[ISA_R_type] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(9, 7); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(24, 20) = 0x8 | wb_instr(4, 2); // rs2 |
switch (wb_instr(6, 5)) { |
case 0: |
wb_dec[Instr_SUB] = 1; |
break; |
case 1: |
wb_dec[Instr_XOR] = 1; |
break; |
case 2: |
wb_dec[Instr_OR] = 1; |
break; |
default: |
wb_dec[Instr_AND] = 1; |
} |
} else { |
w_error = true; |
wb_isa_type[ISA_R_type] = 1; |
wb_instr_out(11, 7) = 0x8 | wb_instr(9, 7); // rd |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(24, 20) = 0x8 | wb_instr(4, 2); // rs2 |
switch (wb_instr(6, 5)) { |
case 0: |
wb_dec[Instr_SUBW] = 1; |
break; |
case 1: |
wb_dec[Instr_ADDW] = 1; |
break; |
default: |
w_error = true; |
} |
} |
break; |
case 0x7: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_AND] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REMU] = 1; |
case OPCODE_C_JR_MV_EBREAK_JALR_ADD: |
wb_isa_type[ISA_I_type] = 1; |
if (wb_instr[12] == 0) { |
if (wb_instr(6, 2) == 0) { |
wb_dec[Instr_JALR] = 1; |
wb_instr_out(19, 15) = wb_instr(11, 7); // rs1 |
} else { |
wb_dec[Instr_ADDI] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = wb_instr(6, 2); // rs1 |
} |
} else { |
w_error = true; |
if (wb_instr(11, 7) == 0 && wb_instr(6, 2) == 0) { |
wb_dec[Instr_EBREAK] = 1; |
} else if (wb_instr(6, 2) == 0) { |
wb_dec[Instr_JALR] = 1; |
wb_instr_out(11, 7) = 0x1; // rd = ra |
wb_instr_out(19, 15) = wb_instr(11, 7); // rs1 |
} else { |
wb_dec[Instr_ADD] = 1; |
wb_isa_type[ISA_R_type] = 1; |
wb_instr_out(11, 7) = wb_instr(11, 7); // rd |
wb_instr_out(19, 15) = wb_instr(11, 7); // rs1 |
wb_instr_out(24, 20) = wb_instr(6, 2); // rs2 |
} |
} |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_ADDI: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_ADDI] = 1; |
case OPCODE_C_J: // JAL with rd = 0 |
wb_isa_type[ISA_UJ_type] = 1; |
wb_dec[Instr_JAL] = 1; |
wb_instr_out[20] = wb_instr[12]; // imm11 |
wb_instr_out(23, 21) = wb_instr(5, 3); // imm10_1(3:1) |
wb_instr_out[24] = wb_instr[11]; // imm10_1(4) |
wb_instr_out[25] = wb_instr[2]; // imm10_1(5) |
wb_instr_out[26] = wb_instr[7]; // imm10_1(6) |
wb_instr_out[27] = wb_instr[6]; // imm10_1(7) |
wb_instr_out(29, 28) = wb_instr(10, 9); // imm10_1(9:8) |
wb_instr_out[30] = wb_instr[8]; // imm10_1(10) |
if (wb_instr[12]) { |
wb_instr_out(19, 12) = ~0; // imm19_12 |
wb_instr_out[31] = 1; // imm20 |
} |
break; |
case 0x1: |
wb_dec[Instr_SLLI] = 1; |
case OPCODE_C_SW: |
wb_isa_type[ISA_S_type] = 1; |
wb_dec[Instr_SW] = 1; |
wb_instr_out(24, 20) = 0x8 | wb_instr(4, 2); // rs2 |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(11, 9) = (wb_instr(11, 10), wb_instr[6]); |
wb_instr_out(26, 25) = (wb_instr[5] , wb_instr[12]); |
break; |
case 0x2: |
wb_dec[Instr_SLTI] = 1; |
case OPCODE_C_BEQZ: |
wb_isa_type[ISA_SB_type] = 1; |
wb_dec[Instr_BEQ] = 1; |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(11, 8) = (wb_instr(11, 10), wb_instr(4, 3)); |
wb_instr_out(27, 25) = (wb_instr(6, 5), wb_instr[2]); |
if (wb_instr[12]) { |
wb_instr_out(30, 28) = ~0; |
wb_instr_out[7] = 1; |
wb_instr_out[31] = 1; |
} |
break; |
case 0x3: |
wb_dec[Instr_SLTIU] = 1; |
case OPCODE_C_SWSP: |
wb_isa_type[ISA_S_type] = 1; |
wb_dec[Instr_SW] = 1; |
wb_instr_out(24, 20) = wb_instr(6, 2); // rs2 |
wb_instr_out(19, 15) = 0x2; // rs1 = sp |
wb_instr_out(11, 9) = wb_instr(11, 9); |
wb_instr_out(27, 25) = (wb_instr(8, 7), wb_instr[12]); |
break; |
case 0x4: |
wb_dec[Instr_XORI] = 1; |
case OPCODE_C_SD: |
wb_isa_type[ISA_S_type] = 1; |
wb_dec[Instr_SD] = 1; |
wb_instr_out(24, 20) = 0x8 | wb_instr(4, 2); // rs2 |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(11, 10) = wb_instr(11, 10); |
wb_instr_out(27, 25) = (wb_instr(6, 5), wb_instr[12]); |
break; |
case 0x5: |
if (wb_instr(31, 26) == 0x00) { |
wb_dec[Instr_SRLI] = 1; |
} else if (wb_instr(31, 26) == 0x10) { |
wb_dec[Instr_SRAI] = 1; |
} else { |
w_error = true; |
case OPCODE_C_BNEZ: |
wb_isa_type[ISA_SB_type] = 1; |
wb_dec[Instr_BNE] = 1; |
wb_instr_out(19, 15) = 0x8 | wb_instr(9, 7); // rs1 |
wb_instr_out(11, 8) = (wb_instr(11, 10), wb_instr(4, 3)); |
wb_instr_out(27, 25) = (wb_instr(6, 5), wb_instr[2]); |
if (wb_instr[12]) { |
wb_instr_out(30, 28) = ~0; |
wb_instr_out[7] = 1; |
wb_instr_out[31] = 1; |
} |
break; |
case 0x6: |
wb_dec[Instr_ORI] = 1; |
case OPCODE_C_SDSP: |
wb_isa_type[ISA_S_type] = 1; |
wb_dec[Instr_SD] = 1; |
wb_instr_out(24, 20) = wb_instr(6, 2); // rs2 |
wb_instr_out(19, 15) = 0x2; // rs1 = sp |
wb_instr_out(11, 10) = wb_instr(11, 10); |
wb_instr_out(28, 25) = (wb_instr(9, 7), wb_instr[12]); |
break; |
case 7: |
wb_dec[Instr_ANDI] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_ADDIW: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_ADDIW] = 1; |
} else { |
wb_opcode1 = wb_instr(6, 2); |
wb_opcode2 = wb_instr(14, 12); |
switch (wb_opcode1) { |
case OPCODE_ADD: |
wb_isa_type[ISA_R_type] = 1; |
switch (wb_opcode2) { |
case 0: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_ADD] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_MUL] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SUB] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x1: |
wb_dec[Instr_SLL] = 1; |
break; |
case 0x2: |
wb_dec[Instr_SLT] = 1; |
break; |
case 0x3: |
wb_dec[Instr_SLTU] = 1; |
break; |
case 0x4: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_XOR] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIV] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x5: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_SRL] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIVU] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SRA] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x6: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_OR] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REM] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x7: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_AND] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REMU] = 1; |
} else { |
w_error = true; |
} |
break; |
default: |
w_error = true; |
} |
break; |
case 0x1: |
wb_dec[Instr_SLLIW] = 1; |
case OPCODE_ADDI: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_ADDI] = 1; |
break; |
case 0x1: |
wb_dec[Instr_SLLI] = 1; |
break; |
case 0x2: |
wb_dec[Instr_SLTI] = 1; |
break; |
case 0x3: |
wb_dec[Instr_SLTIU] = 1; |
break; |
case 0x4: |
wb_dec[Instr_XORI] = 1; |
break; |
case 0x5: |
if (wb_instr(31, 26) == 0x00) { |
wb_dec[Instr_SRLI] = 1; |
} else if (wb_instr(31, 26) == 0x10) { |
wb_dec[Instr_SRAI] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x6: |
wb_dec[Instr_ORI] = 1; |
break; |
case 7: |
wb_dec[Instr_ANDI] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case 0x5: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_SRLIW] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SRAIW] = 1; |
} else { |
case OPCODE_ADDIW: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_ADDIW] = 1; |
break; |
case 0x1: |
wb_dec[Instr_SLLIW] = 1; |
break; |
case 0x5: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_SRLIW] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SRAIW] = 1; |
} else { |
w_error = true; |
} |
break; |
default: |
w_error = true; |
} |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_ADDW: |
wb_isa_type[ISA_R_type] = 1; |
switch (wb_opcode2) { |
case 0: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_ADDW] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_MULW] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SUBW] = 1; |
} else { |
case OPCODE_ADDW: |
wb_isa_type[ISA_R_type] = 1; |
switch (wb_opcode2) { |
case 0: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_ADDW] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_MULW] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SUBW] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x1: |
wb_dec[Instr_SLLW] = 1; |
break; |
case 0x4: |
if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIVW] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x5: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_SRLW] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIVUW] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SRAW] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x6: |
if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REMW] = 1; |
} else { |
w_error = true; |
} |
break; |
case 0x7: |
if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REMUW] = 1; |
} else { |
w_error = true; |
} |
break; |
default: |
w_error = true; |
} |
break; |
case 0x1: |
wb_dec[Instr_SLLW] = 1; |
case OPCODE_AUIPC: |
wb_isa_type[ISA_U_type] = 1; |
wb_dec[Instr_AUIPC] = 1; |
break; |
case 0x4: |
if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIVW] = 1; |
} else { |
case OPCODE_BEQ: |
wb_isa_type[ISA_SB_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_BEQ] = 1; |
break; |
case 1: |
wb_dec[Instr_BNE] = 1; |
break; |
case 4: |
wb_dec[Instr_BLT] = 1; |
break; |
case 5: |
wb_dec[Instr_BGE] = 1; |
break; |
case 6: |
wb_dec[Instr_BLTU] = 1; |
break; |
case 7: |
wb_dec[Instr_BGEU] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case 0x5: |
if (wb_instr(31, 25) == 0x00) { |
wb_dec[Instr_SRLW] = 1; |
} else if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_DIVUW] = 1; |
} else if (wb_instr(31, 25) == 0x20) { |
wb_dec[Instr_SRAW] = 1; |
} else { |
case OPCODE_JAL: |
wb_isa_type[ISA_UJ_type] = 1; |
wb_dec[Instr_JAL] = 1; |
break; |
case OPCODE_JALR: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_JALR] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case 0x6: |
if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REMW] = 1; |
} else { |
case OPCODE_LB: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_LB] = 1; |
break; |
case 1: |
wb_dec[Instr_LH] = 1; |
break; |
case 2: |
wb_dec[Instr_LW] = 1; |
break; |
case 3: |
wb_dec[Instr_LD] = 1; |
break; |
case 4: |
wb_dec[Instr_LBU] = 1; |
break; |
case 5: |
wb_dec[Instr_LHU] = 1; |
break; |
case 6: |
wb_dec[Instr_LWU] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case 0x7: |
if (wb_instr(31, 25) == 0x01) { |
wb_dec[Instr_REMUW] = 1; |
} else { |
case OPCODE_LUI: |
wb_isa_type[ISA_U_type] = 1; |
wb_dec[Instr_LUI] = 1; |
break; |
case OPCODE_SB: |
wb_isa_type[ISA_S_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_SB] = 1; |
break; |
case 1: |
wb_dec[Instr_SH] = 1; |
break; |
case 2: |
wb_dec[Instr_SW] = 1; |
break; |
case 3: |
wb_dec[Instr_SD] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_AUIPC: |
wb_isa_type[ISA_U_type] = 1; |
wb_dec[Instr_AUIPC] = 1; |
break; |
case OPCODE_BEQ: |
wb_isa_type[ISA_SB_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_BEQ] = 1; |
case OPCODE_CSRR: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
if (wb_instr == 0x00000073) { |
wb_dec[Instr_ECALL] = 1; |
} else if (wb_instr == 0x00100073) { |
wb_dec[Instr_EBREAK] = 1; |
} else if (wb_instr == 0x00200073) { |
wb_dec[Instr_URET] = 1; |
} else if (wb_instr == 0x10200073) { |
wb_dec[Instr_SRET] = 1; |
} else if (wb_instr == 0x20200073) { |
wb_dec[Instr_HRET] = 1; |
} else if (wb_instr == 0x30200073) { |
wb_dec[Instr_MRET] = 1; |
} else { |
w_error = true; |
} |
break; |
case 1: |
wb_dec[Instr_CSRRW] = 1; |
break; |
case 2: |
wb_dec[Instr_CSRRS] = 1; |
break; |
case 3: |
wb_dec[Instr_CSRRC] = 1; |
break; |
case 5: |
wb_dec[Instr_CSRRWI] = 1; |
break; |
case 6: |
wb_dec[Instr_CSRRSI] = 1; |
break; |
case 7: |
wb_dec[Instr_CSRRCI] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case 1: |
wb_dec[Instr_BNE] = 1; |
break; |
case 4: |
wb_dec[Instr_BLT] = 1; |
break; |
case 5: |
wb_dec[Instr_BGE] = 1; |
break; |
case 6: |
wb_dec[Instr_BLTU] = 1; |
break; |
case 7: |
wb_dec[Instr_BGEU] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_JAL: |
wb_isa_type[ISA_UJ_type] = 1; |
wb_dec[Instr_JAL] = 1; |
break; |
case OPCODE_JALR: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_JALR] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_LB: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_LB] = 1; |
break; |
case 1: |
wb_dec[Instr_LH] = 1; |
break; |
case 2: |
wb_dec[Instr_LW] = 1; |
break; |
case 3: |
wb_dec[Instr_LD] = 1; |
break; |
case 4: |
wb_dec[Instr_LBU] = 1; |
break; |
case 5: |
wb_dec[Instr_LHU] = 1; |
break; |
case 6: |
wb_dec[Instr_LWU] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_LUI: |
wb_isa_type[ISA_U_type] = 1; |
wb_dec[Instr_LUI] = 1; |
break; |
case OPCODE_SB: |
wb_isa_type[ISA_S_type] = 1; |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_SB] = 1; |
break; |
case 1: |
wb_dec[Instr_SH] = 1; |
break; |
case 2: |
wb_dec[Instr_SW] = 1; |
break; |
case 3: |
wb_dec[Instr_SD] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case OPCODE_CSRR: |
wb_isa_type[ISA_I_type] = 1; |
switch (wb_opcode2) { |
case 0: |
if (wb_instr == 0x00000073) { |
wb_dec[Instr_ECALL] = 1; |
} else if (wb_instr == 0x00100073) { |
wb_dec[Instr_EBREAK] = 1; |
} else if (wb_instr == 0x00200073) { |
wb_dec[Instr_URET] = 1; |
} else if (wb_instr == 0x10200073) { |
wb_dec[Instr_SRET] = 1; |
} else if (wb_instr == 0x20200073) { |
wb_dec[Instr_HRET] = 1; |
} else if (wb_instr == 0x30200073) { |
wb_dec[Instr_MRET] = 1; |
} else { |
case OPCODE_FENCE: |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_FENCE] = 1; |
break; |
case 1: |
wb_dec[Instr_FENCE_I] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
case 1: |
wb_dec[Instr_CSRRW] = 1; |
break; |
case 2: |
wb_dec[Instr_CSRRS] = 1; |
break; |
case 3: |
wb_dec[Instr_CSRRC] = 1; |
break; |
case 5: |
wb_dec[Instr_CSRRWI] = 1; |
break; |
case 6: |
wb_dec[Instr_CSRRSI] = 1; |
break; |
case 7: |
wb_dec[Instr_CSRRCI] = 1; |
break; |
|
default: |
w_error = true; |
} |
break; |
case OPCODE_FENCE: |
switch (wb_opcode2) { |
case 0: |
wb_dec[Instr_FENCE] = 1; |
break; |
case 1: |
wb_dec[Instr_FENCE_I] = 1; |
break; |
default: |
w_error = true; |
} |
break; |
wb_instr_out = wb_instr; |
} // compressed/!compressed |
|
default: |
w_error = true; |
} |
|
|
if (i_f_valid.read()) { |
v.valid = 1; |
v.pc = i_f_pc; |
v.instr = wb_instr; |
v.instr = wb_instr_out; |
v.compressed = w_compressed; |
|
v.isa_type = wb_isa_type; |
v.instr_vec = wb_dec; |
437,6 → 703,7
v.memop_size = MEMOP_1B; |
v.unsigned_op = 0; |
v.rv32 = 0; |
v.compressed = 0; |
|
v.instr_unimplemented = !wb_dec.or_reduce(); |
} |
450,6 → 717,7
o_memop_size = r.memop_size; |
o_unsigned_op = r.unsigned_op; |
o_rv32 = r.rv32; |
o_compressed = r.compressed; |
o_isa_type = r.isa_type; |
o_instr_vec = r.instr_vec; |
o_exception = r.instr_unimplemented; |
/core/decoder.h
26,6 → 26,26
const uint8_t OPCODE_JALR = 0x19; // 11001: JALR |
const uint8_t OPCODE_JAL = 0x1B; // 11011: JAL |
const uint8_t OPCODE_CSRR = 0x1C; // 11100: CSRRC, CSRRCI, CSRRS, CSRRSI, CSRRW, CSRRWI, URET, SRET, HRET, MRET |
// Compressed instruction set |
const uint8_t OPCODE_C_ADDI4SPN = 0x00; |
const uint8_t OPCODE_C_NOP_ADDI = 0x01; |
const uint8_t OPCODE_C_SLLI = 0x02; |
const uint8_t OPCODE_C_JAL_ADDIW = 0x05; |
const uint8_t OPCODE_C_LW = 0x08; |
const uint8_t OPCODE_C_LI = 0x09; |
const uint8_t OPCODE_C_LWSP = 0x0A; |
const uint8_t OPCODE_C_LD = 0x0C; |
const uint8_t OPCODE_C_ADDI16SP_LUI = 0xD; |
const uint8_t OPCODE_C_LDSP = 0x0E; |
const uint8_t OPCODE_C_MATH = 0x11; |
const uint8_t OPCODE_C_JR_MV_EBREAK_JALR_ADD = 0x12; |
const uint8_t OPCODE_C_J = 0x15; |
const uint8_t OPCODE_C_SW = 0x18; |
const uint8_t OPCODE_C_BEQZ = 0x19; |
const uint8_t OPCODE_C_SWSP = 0x1A; |
const uint8_t OPCODE_C_SD = 0x1C; |
const uint8_t OPCODE_C_BNEZ = 0x1D; |
const uint8_t OPCODE_C_SDSP = 0x1E; |
|
SC_MODULE(InstrDecoder) { |
sc_in<bool> i_clk; |
43,6 → 63,7
sc_out<bool> o_memop_sign_ext; // Load memory value with sign extending |
sc_out<sc_uint<2>> o_memop_size; // Memory transaction size |
sc_out<bool> o_rv32; // 32-bits instruction |
sc_out<bool> o_compressed; // C-type instruction |
sc_out<bool> o_unsigned_op; // Unsigned operands |
sc_out<sc_bv<ISA_Total>> o_isa_type; // Instruction format accordingly with ISA |
sc_out<sc_bv<Instr_Total>> o_instr_vec; // One bit per decoded instruction bus |
70,6 → 91,7
sc_signal<sc_uint<2>> memop_size; |
sc_signal<bool> unsigned_op; |
sc_signal<bool> rv32; |
sc_signal<bool> compressed; |
|
sc_signal<bool> instr_unimplemented; |
} v, r; |
/core/execute.cpp
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief CPU Instruction Execution stage. |
/* |
* 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 "execute.h" |
18,44 → 27,65
sensitive << i_d_pc; |
sensitive << i_d_instr; |
sensitive << i_wb_done; |
sensitive << i_memop_store; |
sensitive << i_memop_load; |
sensitive << i_memop_store; |
sensitive << i_memop_sign_ext; |
sensitive << i_memop_size; |
sensitive << i_unsigned_op; |
sensitive << i_rv32;; |
sensitive << i_rv32; |
sensitive << i_compressed; |
sensitive << i_isa_type; |
sensitive << i_ivec; |
sensitive << i_rdata1; |
sensitive << i_rdata2; |
sensitive << i_csr_rdata; |
sensitive << i_ext_irq; |
sensitive << i_ie; |
sensitive << i_mtvec; |
sensitive << i_mode; |
sensitive << i_break_mode; |
sensitive << i_unsup_exception; |
sensitive << i_ext_irq; |
sensitive << i_dport_npc_write; |
sensitive << i_dport_npc; |
sensitive << i_rdata1; |
sensitive << i_rdata2; |
sensitive << i_csr_rdata; |
sensitive << r.d_valid; |
sensitive << r.pc; |
sensitive << r.npc; |
sensitive << r.hazard_depth; |
sensitive << r.hazard_addr0; |
sensitive << r.hazard_addr1; |
sensitive << r.instr; |
sensitive << r.res_val; |
sensitive << r.memop_load; |
sensitive << r.memop_store; |
sensitive << w_hazard_detected; |
sensitive << r.memop_addr; |
sensitive << r.multi_res_addr; |
sensitive << r.multi_pc; |
sensitive << r.multi_npc; |
sensitive << r.multi_instr; |
sensitive << r.multi_ena[Multi_MUL]; |
sensitive << r.multi_ena[Multi_DIV]; |
sensitive << r.multi_res_addr; |
sensitive << r.multi_rv32; |
sensitive << r.multi_unsigned; |
sensitive << r.multi_residual_high; |
sensitive << r.multiclock_ena; |
sensitive << r.multi_a1; |
sensitive << r.multi_a2; |
sensitive << r.hazard_addr0; |
sensitive << r.hazard_addr1; |
sensitive << r.hazard_depth; |
sensitive << r.ext_irq_pulser; |
sensitive << r.trap_ena; |
sensitive << r.breakpoint; |
sensitive << r.trap_code; |
sensitive << r.trap_pc; |
sensitive << r.call; |
sensitive << r.ret; |
sensitive << w_hazard_detected; |
sensitive << wb_arith_res.arr[Multi_MUL]; |
sensitive << wb_arith_res.arr[Multi_DIV]; |
sensitive << w_arith_valid[Multi_MUL]; |
sensitive << w_arith_valid[Multi_DIV]; |
sensitive << w_arith_busy[Multi_MUL]; |
sensitive << w_arith_busy[Multi_DIV]; |
sensitive << wb_shifter_a1; |
sensitive << wb_shifter_a2; |
sensitive << wb_sll; |
sensitive << wb_sllw; |
sensitive << wb_srl; |
191,6 → 221,7
sc_uint<2> wb_memop_size; |
sc_uint<BUS_ADDR_WIDTH> wb_memop_addr; |
sc_bv<Instr_Total> wv; |
int opcode_len; |
|
bool w_pc_valid; |
bool w_d_acceptable; |
337,27 → 368,32
|
// Relative Branch on some condition: |
w_pc_branch = 0; |
if ((wv[Instr_BEQ] & (wb_sub64 == 0)) |
|| (wv[Instr_BGE] & (wb_sub64[63] == 0)) |
|| (wv[Instr_BGEU] & (w_gr_equal)) |
|| (wv[Instr_BLT] & (wb_sub64[63] == 1)) |
|| (wv[Instr_BLTU] & (w_less)) |
|| (wv[Instr_BNE] & (wb_sub64 != 0))) { |
if ((wv[Instr_BEQ].to_bool() & (wb_sub64 == 0)) |
|| (wv[Instr_BGE].to_bool() & (wb_sub64[63] == 0)) |
|| (wv[Instr_BGEU].to_bool() & (w_gr_equal)) |
|| (wv[Instr_BLT].to_bool() & (wb_sub64[63] == 1)) |
|| (wv[Instr_BLTU].to_bool() & (w_less)) |
|| (wv[Instr_BNE].to_bool() & (wb_sub64 != 0))) { |
w_pc_branch = 1; |
} |
|
opcode_len = 4; |
if (i_compressed.read()) { |
opcode_len = 2; |
} |
|
if (w_pc_branch) { |
wb_npc = i_d_pc.read() + wb_off(BUS_ADDR_WIDTH-1, 0); |
} else if (wv[Instr_JAL].to_bool()) { |
wb_res = i_d_pc.read() + 4; |
wb_res = i_d_pc.read() + opcode_len; |
wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_off(BUS_ADDR_WIDTH-1, 0); |
} else if (wv[Instr_JALR].to_bool()) { |
wb_res = i_d_pc.read() + 4; |
wb_res = i_d_pc.read() + opcode_len; |
wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0); |
wb_npc[0] = 0; |
} else if ((wv[Instr_MRET] | wv[Instr_URET]).to_bool()) { |
wb_res = i_d_pc.read() + 4; |
w_xret = i_d_valid; |
wb_res = i_d_pc.read() + opcode_len; |
w_xret = i_d_valid.read() && w_pc_valid; |
w_csr_wena = 0; |
if (wv[Instr_URET].to_bool()) { |
wb_csr_addr = CSR_uepc; |
367,7 → 403,7
wb_npc = i_csr_rdata; |
} else { |
// Instr_HRET, Instr_SRET, Instr_FENCE, Instr_FENCE_I: |
wb_npc = i_d_pc.read() + 4; |
wb_npc = i_d_pc.read() + opcode_len; |
} |
|
if (i_memop_load) { |
403,8 → 439,9
} |
|
w_exception = w_d_acceptable |
& (i_unsup_exception.read() || w_exception_load || w_exception_store |
|| w_exception_xret || wv[Instr_ECALL] || wv[Instr_EBREAK]); |
& ((i_unsup_exception.read() & w_pc_valid) || w_exception_load |
|| w_exception_store || w_exception_xret |
|| wv[Instr_ECALL] || wv[Instr_EBREAK]); |
|
/** Default number of cycles per instruction = 0 (1 clock per instr) |
* If instruction is multicycle then modify this value. |
521,7 → 558,8
wb_exception_code = 0; |
if (i_ext_irq & i_ie & !r.ext_irq_pulser) { // Maskable traps (interrupts) |
v.trap_code_waiting[4] = 1; |
v.trap_code_waiting(3, 0) = INTERRUPT_MExternal; |
// INTERRUPT_MExternal - INTERRUPT_USoftware |
v.trap_code_waiting(3, 0) = 11; |
} else if (w_exception) { // Unmaskable traps (exceptions) |
wb_exception_code[4] = 0; |
if (w_exception_load) { |
/core/execute.h
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief CPU Instruction Execution stage. |
/* |
* 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_EXECUTE_H__ |
30,6 → 39,7
sc_in<sc_uint<2>> i_memop_size; // Memory transaction size |
sc_in<bool> i_unsigned_op; // Unsigned operands |
sc_in<bool> i_rv32; // 32-bits instruction |
sc_in<bool> i_compressed; // C-extension (2-bytes length) |
sc_in<sc_bv<ISA_Total>> i_isa_type; // Type of the instruction's structure (ISA spec.) |
sc_in<sc_bv<Instr_Total>> i_ivec; // One pulse per supported instruction. |
sc_in<bool> i_ie; // Interrupt enable bit |
/core/fetch.cpp
77,7 → 77,7
|
w_predict_miss = 1; |
if (i_e_npc == r.pc_z1 |
|| i_e_npc == i_predict_npc || i_e_npc == r.raddr_not_resp_yet) { |
|| i_e_npc == r.raddr_not_resp_yet) { |
w_predict_miss = 0; |
} |
|
/core/proc.cpp
71,6 → 71,7
dec0->o_memop_size(w.d.memop_size); |
dec0->o_unsigned_op(w.d.unsigned_op); |
dec0->o_rv32(w.d.rv32); |
dec0->o_compressed(w.d.compressed); |
dec0->o_isa_type(w.d.isa_type); |
dec0->o_instr_vec(w.d.instr_vec); |
dec0->o_exception(w.d.exception); |
89,6 → 90,7
exec0->i_memop_size(w.d.memop_size); |
exec0->i_unsigned_op(w.d.unsigned_op); |
exec0->i_rv32(w.d.rv32); |
exec0->i_compressed(w.d.compressed); |
exec0->i_isa_type(w.d.isa_type); |
exec0->i_ivec(w.d.instr_vec); |
exec0->i_ie(csr.ie); |
287,9 → 289,7
iregs0->generateVCD(i_vcd, o_vcd); |
} |
|
|
void Processor::comb() { |
|
w_fetch_pipeline_hold = w.e.pipeline_hold | w.m.pipeline_hold | dbg.halt; |
w_any_pipeline_hold = w.f.pipeline_hold | w.e.pipeline_hold |
| w.m.pipeline_hold | dbg.halt; |
323,10 → 323,9
int sz; |
if (w.m.valid.read()) { |
uint64_t line_cnt = dbg.executed_cnt.read() + 1; |
sz = RISCV_sprintf(tstr, sizeof(tstr), "%8" RV_PRI64 "d [%08x] %08x: ", |
sz = RISCV_sprintf(tstr, sizeof(tstr), "%8" RV_PRI64 "d [%08x]: ", |
line_cnt, |
w.m.pc.read().to_int(), |
w.m.instr.read().to_int()); |
w.m.pc.read().to_int()); |
uint64_t prev_val = iregs0->r.mem[w.w.waddr.read().to_int()].to_int64(); |
uint64_t cur_val = w.w.wdata.read().to_int64(); |
if (w.w.waddr.read() == 0 || prev_val == cur_val) { |
/core/proc.h
94,6 → 94,7
sc_signal<bool> memop_sign_ext; |
sc_signal<sc_uint<2>> memop_size; |
sc_signal<bool> rv32; // 32-bits instruction |
sc_signal<bool> compressed; // C-extension |
sc_signal<bool> unsigned_op; // Unsigned operands |
sc_signal<sc_bv<ISA_Total>> isa_type; |
sc_signal<sc_bv<Instr_Total>> instr_vec; |
/river_cfg.h
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief "River" CPU configuration parameters |
/* |
* 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_RIVER_CFG_H__ |
23,7 → 32,7
static const uint8_t MEMOP_2B = 1; |
static const uint8_t MEMOP_1B = 0; |
|
static const uint64_t RESET_VECTOR = 0x1000; |
static const uint64_t RESET_VECTOR = 0x0040; |
static const int DBG_FETCH_TRACE_SIZE = 4; |
|
/** Number of elements each 2*CFG_ADDR_WIDTH in stack trace buffer: */ |
/river_top.cpp
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief "River" CPU Top level. |
/* |
* 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 "river_top.h" |
/river_top.h
1,8 → 1,17
/** |
* @file |
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. |
* @author Sergey Khabarov - sergeykhbr@gmail.com |
* @brief "River" CPU Top level. |
/* |
* 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_RIVER_TOP_H__ |
39,7 → 48,6
sc_out<bool> o_dport_ready; // Response is ready |
sc_out<sc_uint<RISCV_ARCH>> o_dport_rdata; // Response value |
|
|
RiverTop(sc_module_name name_); |
virtual ~RiverTop(); |
|