Line 1... |
Line 1... |
/**
|
/*
|
* @file
|
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
*
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* @brief SystemC CPU wrapper. To interact with the SoC simulator.
|
* 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 "api_core.h"
|
#include "api_core.h"
|
#include "rtl_wrapper.h"
|
#include "rtl_wrapper.h"
|
#if 1
|
|
#include "iservice.h"
|
#include "iservice.h"
|
|
#include <riscv-isa.h>
|
#include "coreservices/iserial.h"
|
#include "coreservices/iserial.h"
|
#endif
|
#include "coreservices/isocinfo.h"
|
|
|
//#define SIMULATE_WAIT_STATES
|
//#define SIMULATE_WAIT_STATES
|
|
|
namespace debugger {
|
namespace debugger {
|
|
|
Line 35... |
Line 44... |
sensitive << r.wait_state_cnt;
|
sensitive << r.wait_state_cnt;
|
|
|
SC_METHOD(clk_negedge_proc);
|
SC_METHOD(clk_negedge_proc);
|
sensitive << o_clk.negedge_event();
|
sensitive << o_clk.negedge_event();
|
|
|
w_nrst = 0;
|
w_nrst = 1;//0;
|
v.nrst = 0;
|
v.nrst = 1;//0;
|
v.interrupt = false;
|
v.interrupt = false;
|
w_interrupt = 0;
|
w_interrupt = 0;
|
v.resp_mem_data = 0;
|
v.resp_mem_data = 0;
|
v.resp_mem_data_valid = false;
|
v.resp_mem_data_valid = false;
|
RISCV_event_create(&dport_.valid, "dport_valid");
|
RISCV_event_create(&dport_.valid, "dport_valid");
|
Line 65... |
Line 74... |
// todo: instead sc_clock
|
// todo: instead sc_clock
|
}
|
}
|
|
|
void RtlWrapper::comb() {
|
void RtlWrapper::comb() {
|
|
|
o_nrst = r.nrst.read()[1];
|
o_nrst = r.nrst.read()[1].to_bool();
|
o_resp_mem_data_valid = r.resp_mem_data_valid;
|
o_resp_mem_data_valid = r.resp_mem_data_valid;
|
o_resp_mem_data = r.resp_mem_data;
|
o_resp_mem_data = r.resp_mem_data;
|
o_interrupt = r.interrupt;
|
o_interrupt = r.interrupt;
|
#ifdef SIMULATE_WAIT_STATES
|
#ifdef SIMULATE_WAIT_STATES
|
if (r.wait_state_cnt.read() == 1) {
|
if (r.wait_state_cnt.read() == 1) {
|
Line 103... |
Line 112... |
step_queue_.pushPreQueued();
|
step_queue_.pushPreQueued();
|
uint64_t step_cnt = i_time.read();
|
uint64_t step_cnt = i_time.read();
|
while ((cb = step_queue_.getNext(step_cnt)) != 0) {
|
while ((cb = step_queue_.getNext(step_cnt)) != 0) {
|
static_cast<IClockListener *>(cb)->stepCallback(step_cnt);
|
static_cast<IClockListener *>(cb)->stepCallback(step_cnt);
|
}
|
}
|
if (generate_ref_ && step_cnt != step_cnt_z) {
|
|
char msg[16];
|
|
int msg_len = 0;
|
|
IService *uart = NULL;
|
|
switch (step_cnt) {
|
|
case 22077:
|
|
uart = static_cast<IService *>(RISCV_get_service("uart0"));
|
|
msg[0] = 'h';
|
|
msg_len = 1;
|
|
break;
|
|
case 22500:
|
|
uart = static_cast<IService *>(RISCV_get_service("uart0"));
|
|
msg[0] = 'e';
|
|
msg[1] = 'l';
|
|
msg_len = 2;
|
|
break;
|
|
case 24347:
|
|
uart = static_cast<IService *>(RISCV_get_service("uart0"));
|
|
msg[0] = 'p';
|
|
msg[1] = '\r';
|
|
msg[2] = '\n';
|
|
msg_len = 3;
|
|
break;
|
|
default:;
|
|
}
|
|
if (uart) {
|
|
ISerial *iserial = static_cast<ISerial *>(
|
|
uart->getInterface(IFACE_SERIAL));
|
|
iserial->writeData(msg, msg_len);
|
|
}
|
|
}
|
|
step_cnt_z = i_time.read();
|
|
|
|
/** */
|
/** */
|
v.interrupt = w_interrupt;
|
v.interrupt = w_interrupt;
|
v.nrst = (r.nrst.read() << 1) | w_nrst;
|
v.nrst = (r.nrst.read() << 1) | w_nrst;
|
v.wait_state_cnt = r.wait_state_cnt.read() + 1;
|
v.wait_state_cnt = r.wait_state_cnt.read() + 1;
|
Line 181... |
Line 158... |
if (RISCV_event_is_set(&dport_.valid)) {
|
if (RISCV_event_is_set(&dport_.valid)) {
|
RISCV_event_clear(&dport_.valid);
|
RISCV_event_clear(&dport_.valid);
|
v.dport_valid = 1;
|
v.dport_valid = 1;
|
v.dport_write = dport_.trans->write;
|
v.dport_write = dport_.trans->write;
|
v.dport_region = dport_.trans->region;
|
v.dport_region = dport_.trans->region;
|
v.dport_addr = dport_.trans->addr;
|
v.dport_addr = dport_.trans->addr >> 3;
|
v.dport_wdata = dport_.trans->wdata;
|
v.dport_wdata = dport_.trans->wdata;
|
}
|
}
|
dport_.idx_missmatch = 0;
|
dport_.idx_missmatch = 0;
|
if (i_dport_ready.read()) {
|
if (i_dport_ready.read()) {
|
dport_.trans->rdata = i_dport_rdata.read().to_uint64();
|
dport_.trans->rdata = i_dport_rdata.read().to_uint64();
|
Line 237... |
Line 214... |
}
|
}
|
}
|
}
|
|
|
void RtlWrapper::raiseSignal(int idx) {
|
void RtlWrapper::raiseSignal(int idx) {
|
switch (idx) {
|
switch (idx) {
|
case CPU_SIGNAL_RESET:
|
case SIGNAL_HardReset:
|
w_nrst = 0;
|
w_nrst = 0;
|
break;
|
break;
|
case CPU_SIGNAL_EXT_IRQ:
|
case INTERRUPT_MExternal:
|
w_interrupt = true;
|
w_interrupt = true;
|
break;
|
break;
|
default:;
|
default:;
|
}
|
}
|
}
|
}
|
|
|
void RtlWrapper::lowerSignal(int idx) {
|
void RtlWrapper::lowerSignal(int idx) {
|
switch (idx) {
|
switch (idx) {
|
case CPU_SIGNAL_RESET:
|
case SIGNAL_HardReset:
|
w_nrst = 1;
|
w_nrst = 1;
|
break;
|
break;
|
case CPU_SIGNAL_EXT_IRQ:
|
case INTERRUPT_MExternal:
|
w_interrupt = false;
|
w_interrupt = false;
|
break;
|
break;
|
default:;
|
default:;
|
}
|
}
|
}
|
}
|