Implemented basic HiFive1-like platform with PLL,tracing etc.
This commit is contained in:
parent
b28595445c
commit
a899d30556
2
dbt-core
2
dbt-core
|
@ -1 +1 @@
|
||||||
Subproject commit 34abe11e782335ae02dd74a3e47ae8bb366abc25
|
Subproject commit 31263d4aaa6a7f01914c2decead091dc968f30d3
|
|
@ -16,14 +16,17 @@ namespace sysc {
|
||||||
|
|
||||||
class system: sc_core::sc_module {
|
class system: sc_core::sc_module {
|
||||||
public:
|
public:
|
||||||
|
SC_HAS_PROCESS(system);
|
||||||
|
|
||||||
system(sc_core::sc_module_name nm);
|
system(sc_core::sc_module_name nm);
|
||||||
virtual ~system();
|
virtual ~system();
|
||||||
|
|
||||||
sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio;
|
||||||
|
sc_core::sc_signal<bool> s_rst_n;
|
||||||
sysc::platform i_platform;
|
sysc::platform i_platform;
|
||||||
sysc::terminal i_terminal;
|
sysc::terminal i_terminal;
|
||||||
|
void gen_por();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,13 +47,17 @@ class aon : public sc_core::sc_module, public scc::tlm_target<> {
|
||||||
public:
|
public:
|
||||||
SC_HAS_PROCESS(aon);
|
SC_HAS_PROCESS(aon);
|
||||||
sc_core::sc_in<sc_core::sc_time> clk_i;
|
sc_core::sc_in<sc_core::sc_time> clk_i;
|
||||||
sc_core::sc_in<bool> rst_i;
|
sc_core::sc_in<bool> erst_n_i;
|
||||||
|
sc_core::sc_out<sc_core::sc_time> lfclkc_o;
|
||||||
|
sc_core::sc_out<bool> rst_o;
|
||||||
aon(sc_core::sc_module_name nm);
|
aon(sc_core::sc_module_name nm);
|
||||||
virtual ~aon() override; // need to keep it in source file because of fwd declaration of aon_regs
|
virtual ~aon() override; // need to keep it in source file because of fwd declaration of aon_regs
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void start_of_simulation() override;
|
||||||
void clock_cb();
|
void clock_cb();
|
||||||
void reset_cb();
|
void reset_cb();
|
||||||
|
void reset_internal_cb();
|
||||||
sc_core::sc_time clk;
|
sc_core::sc_time clk;
|
||||||
std::unique_ptr<aon_regs> regs;
|
std::unique_ptr<aon_regs> regs;
|
||||||
};
|
};
|
||||||
|
|
|
@ -134,6 +134,7 @@ protected:
|
||||||
void start_of_simulation();
|
void start_of_simulation();
|
||||||
void run();
|
void run();
|
||||||
void clk_cb();
|
void clk_cb();
|
||||||
|
void rst_cb();
|
||||||
void sw_irq_cb();
|
void sw_irq_cb();
|
||||||
void timer_irq_cb();
|
void timer_irq_cb();
|
||||||
void global_irq_cb();
|
void global_irq_cb();
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm)
|
inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm)
|
||||||
: sc_core::sc_module(nm)
|
: sc_core::sc_module(nm)
|
||||||
, NAMED(hfrosccfg, r_hfrosccfg, 0, *this)
|
, NAMED(hfrosccfg, r_hfrosccfg, 0, *this)
|
||||||
, NAMED(hfxosccfg, r_hfxosccfg, 0, *this)
|
, NAMED(hfxosccfg, r_hfxosccfg, 0x40000000, *this)
|
||||||
, NAMED(pllcfg, r_pllcfg, 0, *this)
|
, NAMED(pllcfg, r_pllcfg, 0, *this)
|
||||||
, NAMED(plloutdiv, r_plloutdiv, 0, *this)
|
, NAMED(plloutdiv, r_plloutdiv, 0, *this)
|
||||||
, NAMED(coreclkcfg, r_coreclkcfg, 0, *this)
|
, NAMED(coreclkcfg, r_coreclkcfg, 0, *this)
|
||||||
|
|
|
@ -77,8 +77,13 @@ protected:
|
||||||
void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp);
|
void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp);
|
||||||
void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay);
|
void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay);
|
||||||
sc_core::sc_time clk;
|
sc_core::sc_time clk;
|
||||||
|
std::array<bool, 32> last_iof0, last_iof1;
|
||||||
std::unique_ptr<gpio_regs> regs;
|
std::unique_ptr<gpio_regs> regs;
|
||||||
std::shared_ptr<sysc::WsHandler> handler;
|
std::shared_ptr<sysc::WsHandler> handler;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tlm::tlm_phase write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_t i, sc_dt::sc_logic val);
|
||||||
|
void enable_outputs(uint32_t new_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace sysc */
|
} /* namespace sysc */
|
||||||
|
|
|
@ -63,6 +63,8 @@ public:
|
||||||
sc_core::sc_vector<tlm::tlm_signal_initiator_socket<sc_dt::sc_logic>> pins_o;
|
sc_core::sc_vector<tlm::tlm_signal_initiator_socket<sc_dt::sc_logic>> pins_o;
|
||||||
sc_core::sc_vector<tlm::tlm_signal_target_socket<sc_dt::sc_logic>> pins_i;
|
sc_core::sc_vector<tlm::tlm_signal_target_socket<sc_dt::sc_logic>> pins_i;
|
||||||
|
|
||||||
|
sc_core::sc_in<bool> erst_n;
|
||||||
|
|
||||||
platform(sc_core::sc_module_name nm);
|
platform(sc_core::sc_module_name nm);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -46,18 +46,21 @@ class prci_regs;
|
||||||
class prci : public sc_core::sc_module, public scc::tlm_target<> {
|
class prci : public sc_core::sc_module, public scc::tlm_target<> {
|
||||||
public:
|
public:
|
||||||
SC_HAS_PROCESS(prci);
|
SC_HAS_PROCESS(prci);
|
||||||
sc_core::sc_in<sc_core::sc_time> clk_i;
|
sc_core::sc_port<sc_core::sc_signal_in_if<sc_core::sc_time>,1,SC_ZERO_OR_MORE_BOUND> hfxosc_i;
|
||||||
sc_core::sc_in<bool> rst_i;
|
sc_core::sc_in<bool> rst_i;
|
||||||
|
sc_core::sc_out<sc_core::sc_time> hfclk_o;
|
||||||
prci(sc_core::sc_module_name nm);
|
prci(sc_core::sc_module_name nm);
|
||||||
virtual ~prci() override; // need to keep it in source file because of fwd declaration of prci_regs
|
virtual ~prci() override; // need to keep it in source file because of fwd declaration of prci_regs
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void clock_cb();
|
void hfxosc_cb();
|
||||||
void reset_cb();
|
void reset_cb();
|
||||||
void hfrosc_en_cb();
|
void hfrosc_en_cb();
|
||||||
sc_core::sc_time clk;
|
void hfxosc_en_cb();
|
||||||
|
void update_hfclk();
|
||||||
|
sc_core::sc_time hfxosc_clk, hfrosc_clk, pll_clk, hfclk;
|
||||||
std::unique_ptr<prci_regs> regs;
|
std::unique_ptr<prci_regs> regs;
|
||||||
sc_core::sc_event hfrosc_en_evt;
|
sc_core::sc_event hfrosc_en_evt, hfxosc_en_evt;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace sysc */
|
} /* namespace sysc */
|
||||||
|
|
|
@ -3,17 +3,17 @@ FILE(GLOB RiscVSCHeaders *.h */*.h)
|
||||||
FILE(GLOB RiscvSCSources sysc/*.cpp)
|
FILE(GLOB RiscvSCSources sysc/*.cpp)
|
||||||
|
|
||||||
set(LIB_HEADERS ${RiscVSCHeaders} )
|
set(LIB_HEADERS ${RiscVSCHeaders} )
|
||||||
set(LIB_SOURCES ${RiscvSCSources}
|
set(LIB_SOURCES ${RiscvSCSources} )
|
||||||
)
|
|
||||||
|
|
||||||
set(APP_HEADERS )
|
set(APP_HEADERS )
|
||||||
|
set(APP_SOURCES sc_main.cpp)
|
||||||
set(APP_SOURCES sc_main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Define two variables in order not to repeat ourselves.
|
# Define two variables in order not to repeat ourselves.
|
||||||
set(LIBRARY_NAME risc-v.sc)
|
set(LIBRARY_NAME risc-v.sc)
|
||||||
|
|
||||||
|
## the following setting needs to be consistent with the library
|
||||||
|
#add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS)
|
||||||
|
|
||||||
# Define the library
|
# Define the library
|
||||||
add_library(${LIBRARY_NAME} ${LIB_SOURCES})
|
add_library(${LIBRARY_NAME} ${LIB_SOURCES})
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,16 @@ const size_t SUCCESS = 0;
|
||||||
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
|
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
#include "sysc/kernel/sc_externs.h"
|
||||||
|
int
|
||||||
|
main( int argc, char* argv[]){
|
||||||
|
#ifdef _POSIX_SOURCE
|
||||||
|
putenv(const_cast<char*>("SC_SIGNAL_WRITE_CHECK=DISABLE"));
|
||||||
|
putenv(const_cast<char*>("SC_VCD_SCOPES=ENABLE"));
|
||||||
|
#endif
|
||||||
|
return sc_core::sc_elab_and_sim( argc, argv );
|
||||||
|
}
|
||||||
|
|
||||||
int sc_main(int argc, char *argv[]) {
|
int sc_main(int argc, char *argv[]) {
|
||||||
// sc_report_handler::set_handler(my_report_handler);
|
// sc_report_handler::set_handler(my_report_handler);
|
||||||
scc::Logger<>::reporting_level() = logging::ERROR;
|
scc::Logger<>::reporting_level() = logging::ERROR;
|
||||||
|
@ -159,11 +169,15 @@ int sc_main(int argc, char *argv[]) {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// run simulation
|
// run simulation
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
if(vm.count("max_time")){
|
try {
|
||||||
sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
|
if(vm.count("max_time")){
|
||||||
sc_core::sc_start(max_time);
|
sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
|
||||||
} else
|
sc_core::sc_start(max_time);
|
||||||
sc_core::sc_start();
|
} else
|
||||||
|
sc_core::sc_start();
|
||||||
|
} catch(sc_core::sc_report& rep){
|
||||||
|
CLOG(FATAL, SystemC)<<"IWEF"[rep.get_severity()]<<"("<<rep.get_id()<<") "<<rep.get_msg_type()<<": "<<rep.get_msg()<<std::endl;
|
||||||
|
}
|
||||||
if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
|
if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,19 @@ aon::aon(sc_core::sc_module_name nm)
|
||||||
: sc_core::sc_module(nm)
|
: sc_core::sc_module(nm)
|
||||||
, tlm_target<>(clk)
|
, tlm_target<>(clk)
|
||||||
, NAMED(clk_i)
|
, NAMED(clk_i)
|
||||||
, NAMED(rst_i)
|
, NAMED(erst_n_i)
|
||||||
|
, NAMED(lfclkc_o)
|
||||||
|
, NAMED(rst_o)
|
||||||
, NAMEDD(aon_regs, regs) {
|
, NAMEDD(aon_regs, regs) {
|
||||||
regs->registerResources(*this);
|
regs->registerResources(*this);
|
||||||
SC_METHOD(clock_cb);
|
SC_METHOD(clock_cb);
|
||||||
sensitive << clk_i;
|
sensitive << clk_i;
|
||||||
SC_METHOD(reset_cb);
|
SC_METHOD(reset_cb);
|
||||||
sensitive << rst_i;
|
sensitive << erst_n_i;
|
||||||
dont_initialize();
|
}
|
||||||
|
|
||||||
|
void aon::start_of_simulation() {
|
||||||
|
rst_o=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aon::clock_cb() {
|
void aon::clock_cb() {
|
||||||
|
@ -62,10 +67,17 @@ void aon::clock_cb() {
|
||||||
aon::~aon() {}
|
aon::~aon() {}
|
||||||
|
|
||||||
void aon::reset_cb() {
|
void aon::reset_cb() {
|
||||||
if (rst_i.read())
|
if (!erst_n_i.read()){
|
||||||
regs->reset_start();
|
regs->reset_start();
|
||||||
else
|
rst_o=true;
|
||||||
|
} else {
|
||||||
regs->reset_stop();
|
regs->reset_stop();
|
||||||
|
rst_o=false;
|
||||||
|
}
|
||||||
|
lfclkc_o.write(sc_core::sc_time(1/32768., sc_core::SC_SEC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void aon::reset_internal_cb() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace sysc */
|
} /* namespace sysc */
|
||||||
|
|
|
@ -101,6 +101,12 @@ public:
|
||||||
|
|
||||||
uint32_t get_mode(){ return this->reg.machine_state; }
|
uint32_t get_mode(){ return this->reg.machine_state; }
|
||||||
|
|
||||||
|
inline
|
||||||
|
void set_interrupt_execution(bool v){ this->interrupt_sim=v;}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool get_interrupt_execution(){ return this->interrupt_sim;}
|
||||||
|
|
||||||
base_type::hart_state<base_type::reg_t>& get_state() { return this->state; }
|
base_type::hart_state<base_type::reg_t>& get_state() { return this->state; }
|
||||||
|
|
||||||
void notify_phase(exec_phase p) override {
|
void notify_phase(exec_phase p) override {
|
||||||
|
@ -241,6 +247,8 @@ core_complex::core_complex(sc_core::sc_module_name name)
|
||||||
SC_THREAD(run);
|
SC_THREAD(run);
|
||||||
SC_METHOD(clk_cb);
|
SC_METHOD(clk_cb);
|
||||||
sensitive << clk_i;
|
sensitive << clk_i;
|
||||||
|
SC_METHOD(rst_cb);
|
||||||
|
sensitive << rst_i;
|
||||||
SC_METHOD(sw_irq_cb);
|
SC_METHOD(sw_irq_cb);
|
||||||
sensitive<<sw_irq_i;
|
sensitive<<sw_irq_i;
|
||||||
SC_METHOD(timer_irq_cb);
|
SC_METHOD(timer_irq_cb);
|
||||||
|
@ -299,6 +307,12 @@ void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
|
||||||
|
|
||||||
void core_complex::clk_cb() {
|
void core_complex::clk_cb() {
|
||||||
curr_clk = clk_i.read();
|
curr_clk = clk_i.read();
|
||||||
|
if(curr_clk==SC_ZERO_TIME) cpu->set_interrupt_execution(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void core_complex::rst_cb() {
|
||||||
|
if(rst_i.read())
|
||||||
|
cpu->set_interrupt_execution(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_complex::sw_irq_cb(){
|
void core_complex::sw_irq_cb(){
|
||||||
|
@ -314,13 +328,19 @@ void core_complex::global_irq_cb(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_complex::run() {
|
void core_complex::run() {
|
||||||
wait(sc_core::SC_ZERO_TIME);
|
wait(SC_ZERO_TIME); // separate from elaboration phase
|
||||||
cpu->reset(reset_address.get_value());
|
do{
|
||||||
try {
|
if(rst_i.read()){
|
||||||
vm->start(-1);
|
cpu->reset(reset_address.get_value());
|
||||||
} catch (simulation_stopped &e) {
|
wait(rst_i.negedge_event());
|
||||||
}
|
}
|
||||||
sc_core::sc_stop();
|
while(clk_i.read()==SC_ZERO_TIME){
|
||||||
|
wait(clk_i.value_changed_event());
|
||||||
|
}
|
||||||
|
cpu->set_interrupt_execution(false);
|
||||||
|
vm->start();
|
||||||
|
} while(cpu->get_interrupt_execution());
|
||||||
|
sc_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch) {
|
bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch) {
|
||||||
|
|
|
@ -73,6 +73,7 @@ gpio::gpio(sc_core::sc_module_name nm)
|
||||||
}
|
}
|
||||||
auto iof0_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
|
auto iof0_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
|
||||||
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
|
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
|
||||||
|
last_iof0[tag]=gp.get_value();
|
||||||
this->iof_input(tag, 0, gp, delay);
|
this->iof_input(tag, 0, gp, delay);
|
||||||
return tlm::TLM_COMPLETED;
|
return tlm::TLM_COMPLETED;
|
||||||
};
|
};
|
||||||
|
@ -83,6 +84,7 @@ gpio::gpio(sc_core::sc_module_name nm)
|
||||||
}
|
}
|
||||||
auto iof1_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
|
auto iof1_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
|
||||||
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
|
tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
|
||||||
|
last_iof1[tag]=gp.get_value();
|
||||||
this->iof_input(tag, 1, gp, delay);
|
this->iof_input(tag, 1, gp, delay);
|
||||||
return tlm::TLM_COMPLETED;
|
return tlm::TLM_COMPLETED;
|
||||||
};
|
};
|
||||||
|
@ -99,6 +101,13 @@ gpio::gpio(sc_core::sc_module_name nm)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
regs->iof_en.set_write_cb([this](scc::sc_register<uint32_t> ®, uint32_t data) -> bool {
|
||||||
|
if (!this->regs->in_reset()) {
|
||||||
|
enable_outputs(data);
|
||||||
|
reg.put(data);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,21 +132,51 @@ void gpio::clock_cb() {
|
||||||
this->clk = clk_i.read();
|
this->clk = clk_i.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlm::tlm_phase gpio::write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_t i, sc_dt::sc_logic val) {
|
||||||
|
sc_core::sc_time delay{SC_ZERO_TIME};
|
||||||
|
tlm::tlm_phase phase{ tlm::BEGIN_REQ };
|
||||||
|
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
||||||
|
gp.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||||
|
gp.set_value(val);
|
||||||
|
pins_o.at(i)->nb_transport_fw(gp, phase, delay);
|
||||||
|
return phase;
|
||||||
|
}
|
||||||
|
|
||||||
void gpio::update_pins() {
|
void gpio::update_pins() {
|
||||||
sc_core::sc_inout_rv<32>::data_type out_val;
|
sc_core::sc_inout_rv<32>::data_type out_val;
|
||||||
tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
|
tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
|
||||||
for(size_t i=0, mask = 1; i<32; ++i, mask<<=1){
|
for(size_t i=0, mask = 1; i<32; ++i, mask<<=1){
|
||||||
if((regs->iof_en&mask == 0) || (iof0_i[i].size()==0 && iof1_i[i].size()==0)){
|
if((regs->iof_en&mask == 0) || (iof0_i[i].size()==0 && iof1_i[i].size()==0)){
|
||||||
sc_core::sc_time delay{SC_ZERO_TIME};
|
auto val = regs->r_output_en&mask?
|
||||||
tlm::tlm_phase phase{tlm::BEGIN_REQ};
|
regs->r_port&mask?
|
||||||
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
sc_dt::Log_1:
|
||||||
gp.set_response_status(tlm::TLM_OK_RESPONSE);
|
sc_dt::Log_0:
|
||||||
gp.set_value(regs->r_output_en&mask?regs->r_port&mask?sc_dt::Log_1:sc_dt::Log_0:sc_dt::Log_Z);
|
sc_dt::Log_Z;
|
||||||
pins_o.at(i)->nb_transport_fw(gp, phase, delay);
|
tlm::tlm_phase phase = write_output(gp, i, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gpio::enable_outputs(uint32_t new_data) {
|
||||||
|
auto changed_bits = regs->r_iof_en^new_data;
|
||||||
|
tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
|
||||||
|
for(size_t i=0, mask=1; i<32; ++i, mask<<=1){
|
||||||
|
if(changed_bits&mask){
|
||||||
|
if(new_data&mask){
|
||||||
|
if((regs->r_iof_sel&mask)==0 && iof0_i[i].size()>0){
|
||||||
|
tlm::tlm_phase phase = write_output(gp, i, last_iof0[i]?sc_dt::Log_1:sc_dt::Log_0);
|
||||||
|
} else if((regs->r_iof_sel&mask)==1 && iof1_i[i].size()>0)
|
||||||
|
tlm::tlm_phase phase = write_output(gp, i, last_iof1[i]?sc_dt::Log_1:sc_dt::Log_0);
|
||||||
|
} else {
|
||||||
|
auto val = regs->r_output_en&mask?
|
||||||
|
regs->r_port&mask?sc_dt::Log_1:sc_dt::Log_0:
|
||||||
|
sc_dt::Log_Z;
|
||||||
|
tlm::tlm_phase phase = write_output(gp, i, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, sc_core::sc_time& delay) {
|
void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, sc_core::sc_time& delay) {
|
||||||
if(delay>SC_ZERO_TIME){
|
if(delay>SC_ZERO_TIME){
|
||||||
wait(delay);
|
wait(delay);
|
||||||
|
@ -187,7 +226,8 @@ void gpio::iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& g
|
||||||
tlm::tlm_phase phase{tlm::BEGIN_REQ};
|
tlm::tlm_phase phase{tlm::BEGIN_REQ};
|
||||||
tlm::tlm_signal_gp<sc_logic> new_gp;
|
tlm::tlm_signal_gp<sc_logic> new_gp;
|
||||||
new_gp.set_command(tlm::TLM_WRITE_COMMAND);
|
new_gp.set_command(tlm::TLM_WRITE_COMMAND);
|
||||||
new_gp.set_value(gp.get_value()?sc_dt::Log_1:sc_dt::Log_0);
|
auto val = gp.get_value();
|
||||||
|
new_gp.set_value(val?sc_dt::Log_1:sc_dt::Log_0);
|
||||||
new_gp.copy_extensions_from(gp);
|
new_gp.copy_extensions_from(gp);
|
||||||
socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum
|
socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ platform::platform(sc_core::sc_module_name nm)
|
||||||
: sc_core::sc_module(nm)
|
: sc_core::sc_module(nm)
|
||||||
, NAMED(pins_o, 32)
|
, NAMED(pins_o, 32)
|
||||||
, NAMED(pins_i, 32)
|
, NAMED(pins_i, 32)
|
||||||
|
, NAMED(erst_n)
|
||||||
, NAMED(i_core_complex)
|
, NAMED(i_core_complex)
|
||||||
, NAMED(i_router, 12, 1)
|
, NAMED(i_router, 12, 1)
|
||||||
, NAMED(i_uart0)
|
, NAMED(i_uart0)
|
||||||
|
@ -85,7 +86,8 @@ platform::platform(sc_core::sc_module_name nm)
|
||||||
i_gpio0.clk_i(s_tlclk);
|
i_gpio0.clk_i(s_tlclk);
|
||||||
i_plic.clk_i(s_tlclk);
|
i_plic.clk_i(s_tlclk);
|
||||||
i_aon.clk_i(s_tlclk);
|
i_aon.clk_i(s_tlclk);
|
||||||
i_prci.clk_i(s_tlclk);
|
i_aon.lfclkc_o(s_lfclk);
|
||||||
|
i_prci.hfclk_o(s_tlclk); // clock driver
|
||||||
i_clint.tlclk_i(s_tlclk);
|
i_clint.tlclk_i(s_tlclk);
|
||||||
i_clint.lfclk_i(s_lfclk);
|
i_clint.lfclk_i(s_lfclk);
|
||||||
i_core_complex.clk_i(s_tlclk);
|
i_core_complex.clk_i(s_tlclk);
|
||||||
|
@ -97,11 +99,13 @@ platform::platform(sc_core::sc_module_name nm)
|
||||||
i_qspi2.rst_i(s_rst);
|
i_qspi2.rst_i(s_rst);
|
||||||
i_gpio0.rst_i(s_rst);
|
i_gpio0.rst_i(s_rst);
|
||||||
i_plic.rst_i(s_rst);
|
i_plic.rst_i(s_rst);
|
||||||
i_aon.rst_i(s_rst);
|
i_aon.rst_o(s_rst);
|
||||||
i_prci.rst_i(s_rst);
|
i_prci.rst_i(s_rst);
|
||||||
i_clint.rst_i(s_rst);
|
i_clint.rst_i(s_rst);
|
||||||
i_core_complex.rst_i(s_rst);
|
i_core_complex.rst_i(s_rst);
|
||||||
|
|
||||||
|
i_aon.erst_n_i(erst_n);
|
||||||
|
|
||||||
i_clint.mtime_int_o(s_mtime_int);
|
i_clint.mtime_int_o(s_mtime_int);
|
||||||
i_clint.msip_int_o(s_msie_int);
|
i_clint.msip_int_o(s_msie_int);
|
||||||
|
|
||||||
|
@ -124,17 +128,7 @@ platform::platform(sc_core::sc_module_name nm)
|
||||||
i_uart1.rx_i(s_dummy_sck_o[0]);
|
i_uart1.rx_i(s_dummy_sck_o[0]);
|
||||||
i_uart1.irq_o(s_dummy[0]);
|
i_uart1.irq_o(s_dummy[0]);
|
||||||
|
|
||||||
SC_THREAD(gen_reset);
|
|
||||||
|
|
||||||
for(auto& sock:s_dummy_sck_i) sock.error_if_no_callback=false;
|
for(auto& sock:s_dummy_sck_i) sock.error_if_no_callback=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform::gen_reset() {
|
|
||||||
s_tlclk = 10_ns;
|
|
||||||
s_lfclk = 30517_ns;
|
|
||||||
s_rst = true;
|
|
||||||
wait(10_ns);
|
|
||||||
s_rst = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace sysc */
|
} /* namespace sysc */
|
||||||
|
|
|
@ -43,24 +43,35 @@ namespace sysc {
|
||||||
|
|
||||||
prci::prci(sc_core::sc_module_name nm)
|
prci::prci(sc_core::sc_module_name nm)
|
||||||
: sc_core::sc_module(nm)
|
: sc_core::sc_module(nm)
|
||||||
, tlm_target<>(clk)
|
, tlm_target<>(hfclk)
|
||||||
, NAMED(clk_i)
|
|
||||||
, NAMED(rst_i)
|
, NAMED(rst_i)
|
||||||
|
, NAMED(hfclk_o)
|
||||||
, NAMEDD(prci_regs, regs) {
|
, NAMEDD(prci_regs, regs) {
|
||||||
regs->registerResources(*this);
|
regs->registerResources(*this);
|
||||||
SC_METHOD(clock_cb);
|
|
||||||
sensitive << clk_i;
|
|
||||||
SC_METHOD(reset_cb);
|
SC_METHOD(reset_cb);
|
||||||
sensitive << rst_i;
|
sensitive << rst_i;
|
||||||
dont_initialize();
|
dont_initialize();
|
||||||
|
SC_METHOD(hfxosc_cb);
|
||||||
|
sensitive << hfxosc_i;
|
||||||
SC_METHOD(hfrosc_en_cb);
|
SC_METHOD(hfrosc_en_cb);
|
||||||
sensitive << hfrosc_en_evt;
|
sensitive << hfrosc_en_evt;
|
||||||
dont_initialize();
|
dont_initialize();
|
||||||
|
|
||||||
|
regs->hfxosccfg.set_write_cb([this](scc::sc_register<uint32_t> ®, uint32_t data) -> bool {
|
||||||
|
reg.put(data);
|
||||||
|
if (this->regs->r_hfxosccfg.hfxoscen==1) { // check rosc_en
|
||||||
|
this->hfxosc_en_evt.notify(1, sc_core::SC_US);
|
||||||
|
} else {
|
||||||
|
this->hfxosc_en_evt.notify(SC_ZERO_TIME);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
regs->hfrosccfg.set_write_cb([this](scc::sc_register<uint32_t> ®, uint32_t data) -> bool {
|
regs->hfrosccfg.set_write_cb([this](scc::sc_register<uint32_t> ®, uint32_t data) -> bool {
|
||||||
reg.put(data);
|
reg.put(data);
|
||||||
if (this->regs->r_hfrosccfg & (1 << 30)) { // check rosc_en
|
if (this->regs->r_hfrosccfg.hfroscen==1) { // check rosc_en
|
||||||
this->hfrosc_en_evt.notify(1, sc_core::SC_US);
|
this->hfrosc_en_evt.notify(1, sc_core::SC_US);
|
||||||
|
} else {
|
||||||
|
this->hfrosc_en_evt.notify(SC_ZERO_TIME);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -70,13 +81,15 @@ prci::prci(sc_core::sc_module_name nm)
|
||||||
if (pllcfg.pllbypass == 0 && pllcfg.pllq != 0) { // set pll_lock if pll is selected
|
if (pllcfg.pllbypass == 0 && pllcfg.pllq != 0) { // set pll_lock if pll is selected
|
||||||
pllcfg.plllock = 1;
|
pllcfg.plllock = 1;
|
||||||
}
|
}
|
||||||
|
update_hfclk();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
regs->plloutdiv.set_write_cb([this](scc::sc_register<uint32_t> ®, uint32_t data) -> bool {
|
||||||
|
reg.put(data);
|
||||||
void prci::clock_cb() {
|
update_hfclk();
|
||||||
this->clk = clk_i.read();
|
return true;
|
||||||
|
});
|
||||||
|
hfxosc_clk=62.5_ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
prci::~prci() {}
|
prci::~prci() {}
|
||||||
|
@ -84,12 +97,49 @@ prci::~prci() {}
|
||||||
void prci::reset_cb() {
|
void prci::reset_cb() {
|
||||||
if (rst_i.read())
|
if (rst_i.read())
|
||||||
regs->reset_start();
|
regs->reset_start();
|
||||||
else
|
else {
|
||||||
regs->reset_stop();
|
regs->reset_stop();
|
||||||
|
this->hfxosc_en_evt.notify(1, sc_core::SC_US);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prci::hfxosc_cb() {
|
||||||
|
this->regs->r_hfxosccfg.hfxoscrdy=0;
|
||||||
|
this->hfxosc_en_evt.notify(1, sc_core::SC_US);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void prci::hfxosc_en_cb() {
|
||||||
|
update_hfclk();
|
||||||
|
if(regs->r_hfxosccfg.hfxoscen==1)// set rosc_rdy
|
||||||
|
regs->r_hfxosccfg.hfxoscrdy =1;
|
||||||
|
else
|
||||||
|
regs->r_hfxosccfg.hfxoscrdy =0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void prci::hfrosc_en_cb() {
|
void prci::hfrosc_en_cb() {
|
||||||
regs->r_hfrosccfg |= (1 << 31); // set rosc_rdy
|
update_hfclk();
|
||||||
|
auto& hfrosccfg=regs->r_hfrosccfg;
|
||||||
|
if(regs->r_hfrosccfg.hfroscen==1) {// set rosc_rdy
|
||||||
|
regs->r_hfrosccfg.hfroscrdy =1;
|
||||||
|
} else {
|
||||||
|
regs->r_hfrosccfg.hfroscrdy =0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prci::update_hfclk() {
|
||||||
|
auto& hfrosccfg=regs->r_hfrosccfg;
|
||||||
|
auto& pllcfg=regs->r_pllcfg;
|
||||||
|
auto& plldiv=regs->r_plloutdiv;
|
||||||
|
hfrosc_clk = sc_core::sc_time(((hfrosccfg.hfroscdiv+1)*1.0)/(1125000.0*(hfrosccfg.hfrosctrim+1)), sc_core::SC_SEC);
|
||||||
|
auto pll_ref = pllcfg.pllrefsel==1?hfxosc_clk:hfrosc_clk;
|
||||||
|
auto r = pllcfg.pllr+1;
|
||||||
|
auto f = 2*(pllcfg.pllf+1);
|
||||||
|
auto q = 1<<pllcfg.pllq;
|
||||||
|
auto pll_out = pllcfg.pllbypass==1 || pllcfg.plllock==0?pll_ref:((pll_ref*r)/f)*q;
|
||||||
|
auto pll_res = plldiv&0x100?pll_out:2*pll_out*((plldiv&0x3f)+1);
|
||||||
|
hfclk = pllcfg.pllsel?pll_res:hfrosc_clk;
|
||||||
|
hfclk_o.write(hfclk);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace sysc */
|
} /* namespace sysc */
|
||||||
|
|
|
@ -12,19 +12,29 @@ using namespace sysc;
|
||||||
system::system(sc_core::sc_module_name nm)
|
system::system(sc_core::sc_module_name nm)
|
||||||
: sc_module(nm)
|
: sc_module(nm)
|
||||||
, NAMED(s_gpio, 32)
|
, NAMED(s_gpio, 32)
|
||||||
|
, NAMED(s_rst_n)
|
||||||
, NAMED(i_platform)
|
, NAMED(i_platform)
|
||||||
, NAMED(i_terminal)
|
, NAMED(i_terminal)
|
||||||
{
|
{
|
||||||
for(auto i=0U; i<s_gpio.size(); ++i){
|
// connect platform
|
||||||
|
i_platform.erst_n(s_rst_n);
|
||||||
|
|
||||||
|
for(auto i=0U; i<s_gpio.size(); ++i){
|
||||||
s_gpio[i].in(i_platform.pins_o[i]);
|
s_gpio[i].in(i_platform.pins_o[i]);
|
||||||
i_platform.pins_i[i](s_gpio[i].out);
|
i_platform.pins_i[i](s_gpio[i].out);
|
||||||
}
|
}
|
||||||
// i_platform.pins_i(i_platform.pins_o);
|
// connect other units
|
||||||
|
s_gpio[17].out(i_terminal.rx_i);
|
||||||
s_gpio[17].out(i_terminal.rx_i);
|
i_terminal.tx_o(s_gpio[16].in);
|
||||||
i_terminal.tx_o(s_gpio[16].in);
|
SC_THREAD(gen_por);
|
||||||
}
|
}
|
||||||
|
|
||||||
system::~system() {
|
system::~system() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sysc::system::gen_por() {
|
||||||
|
// single shot
|
||||||
|
s_rst_n = false;
|
||||||
|
wait(10_ns);
|
||||||
|
s_rst_n = true;
|
||||||
|
}
|
||||||
|
|
|
@ -134,54 +134,40 @@ void uart::reset_cb() {
|
||||||
|
|
||||||
void uart::transmit_data() {
|
void uart::transmit_data() {
|
||||||
uint8_t txdata;
|
uint8_t txdata;
|
||||||
sc_core::sc_time delay(SC_ZERO_TIME);
|
sysc::tlm_signal_uart_extension ext;
|
||||||
tlm::tlm_phase phase(tlm::BEGIN_REQ);
|
tlm::tlm_phase phase(tlm::BEGIN_REQ);
|
||||||
tlm::tlm_signal_gp<> gp;
|
tlm::tlm_signal_gp<> gp;
|
||||||
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
sc_core::sc_time delay(SC_ZERO_TIME);
|
||||||
gp.set_value(true);
|
sc_core::sc_time bit_duration(SC_ZERO_TIME);
|
||||||
tx_o->nb_transport_fw(gp, phase, delay);
|
|
||||||
|
gp.set_extension(&ext);
|
||||||
|
ext.tx.data_bits=8;
|
||||||
|
ext.tx.parity=false;
|
||||||
|
|
||||||
|
auto set_bit = [&](bool val){
|
||||||
|
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
||||||
|
gp.set_value(val);
|
||||||
|
tlm::tlm_phase phase(tlm::BEGIN_REQ);
|
||||||
|
tx_o->nb_transport_fw(gp, phase, delay);
|
||||||
|
if(delay<bit_duration) wait(bit_duration-delay);
|
||||||
|
};
|
||||||
|
wait(delay);
|
||||||
while(true){
|
while(true){
|
||||||
|
set_bit(true);
|
||||||
wait(tx_fifo.data_written_event());
|
wait(tx_fifo.data_written_event());
|
||||||
while(tx_fifo.nb_read(txdata)){
|
while(tx_fifo.nb_read(txdata)){
|
||||||
regs->r_txdata.full=tx_fifo.num_free()==0;
|
regs->r_txdata.full=tx_fifo.num_free()==0;
|
||||||
regs->r_ip.txwm=regs->r_txctrl.txcnt<=(7-tx_fifo.num_free())?1:0;
|
regs->r_ip.txwm=regs->r_txctrl.txcnt<=(7-tx_fifo.num_free())?1:0;
|
||||||
auto bit_duration = (regs->r_div.div+1)*clk;
|
bit_duration = (regs->r_div.div+1)*clk;
|
||||||
sysc::tlm_signal_uart_extension ext;
|
|
||||||
ext.start_time = sc_core::sc_time_stamp();
|
ext.start_time = sc_core::sc_time_stamp();
|
||||||
ext.tx.data_bits=8;
|
|
||||||
ext.tx.parity=false;
|
|
||||||
ext.tx.stop_bits=1+regs->r_txctrl.nstop;
|
ext.tx.stop_bits=1+regs->r_txctrl.nstop;
|
||||||
ext.tx.baud_rate=static_cast<unsigned>(1/bit_duration.to_seconds());
|
ext.tx.baud_rate=static_cast<unsigned>(1/bit_duration.to_seconds());
|
||||||
ext.tx.data=txdata;
|
ext.tx.data=txdata;
|
||||||
delay=SC_ZERO_TIME;
|
set_bit(false); // start bit
|
||||||
auto start = sc_time_stamp();
|
for(int i = 8; i>0; --i)
|
||||||
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
set_bit(txdata&(1<<(i-1))); // 8 data bits, MSB first
|
||||||
gp.set_value(false);
|
set_bit(true); // stop bit 1
|
||||||
gp.set_extension(&ext);
|
if(regs->r_txctrl.nstop) set_bit(true); // stop bit 2
|
||||||
phase=tlm::BEGIN_REQ;
|
|
||||||
tx_o->nb_transport_fw(gp, phase, delay);
|
|
||||||
auto duration = bit_duration*(1+8+1+ext.tx.stop_bits);//start+data+parity+stop
|
|
||||||
auto diff=start+duration-sc_time_stamp();
|
|
||||||
if(diff>SC_ZERO_TIME) wait(diff);
|
|
||||||
delay=SC_ZERO_TIME;
|
|
||||||
gp.set_command(tlm::TLM_WRITE_COMMAND);
|
|
||||||
gp.set_value(true);
|
|
||||||
phase=tlm::BEGIN_REQ;
|
|
||||||
tx_o->nb_transport_fw(gp, phase, delay);
|
|
||||||
|
|
||||||
// if(txdata != '\r') queue.push_back(txdata);
|
|
||||||
// if (queue.size() >> 0 && (txdata == '\n' || txdata == 0)) {
|
|
||||||
// std::string msg(queue.begin(), queue.end()-1);
|
|
||||||
// LOG(INFO) << this->name() << " transmit: '" << msg << "'";
|
|
||||||
// sc_core::sc_time now = sc_core::sc_time_stamp();
|
|
||||||
// if(handler)
|
|
||||||
// sc_comm_singleton::inst().execute([this, msg, now](){
|
|
||||||
// std::stringstream os;
|
|
||||||
// os << "{\"time\":\"" << now << "\",\"message\":\""<<msg<<"\"}";
|
|
||||||
// this->handler->send(os.str());
|
|
||||||
// });
|
|
||||||
// queue.clear();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,7 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
|
bool interrupt_sim=false;
|
||||||
<%
|
<%
|
||||||
def fcsr = allRegs.find {it.name=='FCSR'}
|
def fcsr = allRegs.find {it.name=='FCSR'}
|
||||||
if(fcsr != null) {%>
|
if(fcsr != null) {%>
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2017, MINRES Technologies GmbH
|
// Copyright (C) 2017,2018 MINRES Technologies GmbH
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// modification, are permitted provided that the following conditions are met:
|
||||||
//
|
//
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
// this list of conditions and the following disclaimer.
|
||||||
//
|
//
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
// and/or other materials provided with the distribution.
|
||||||
//
|
//
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
// may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
// without specific prior written permission.
|
||||||
//
|
//
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
|
|
@ -179,6 +179,8 @@ struct rv32gc: public arch_if {
|
||||||
|
|
||||||
uint64_t get_icount() { return reg.icount;}
|
uint64_t get_icount() { return reg.icount;}
|
||||||
|
|
||||||
|
bool should_stop(){return false;}
|
||||||
|
|
||||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
if(addr.space != traits<rv32gc>::MEM ||
|
if(addr.space != traits<rv32gc>::MEM ||
|
||||||
addr.type == iss::address_type::PHYSICAL ||
|
addr.type == iss::address_type::PHYSICAL ||
|
||||||
|
|
|
@ -144,8 +144,12 @@ struct rv32imac: public arch_if {
|
||||||
/// deprecated
|
/// deprecated
|
||||||
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||||
|
|
||||||
|
inline
|
||||||
uint64_t get_icount() { return reg.icount;}
|
uint64_t get_icount() { return reg.icount;}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool should_stop() { return interrupt_sim;}
|
||||||
|
|
||||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
if(addr.space != traits<rv32imac>::MEM ||
|
if(addr.space != traits<rv32imac>::MEM ||
|
||||||
addr.type == iss::address_type::PHYSICAL ||
|
addr.type == iss::address_type::PHYSICAL ||
|
||||||
|
@ -204,6 +208,7 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
|
bool interrupt_sim=false;
|
||||||
|
|
||||||
uint32_t get_fcsr(){return 0;}
|
uint32_t get_fcsr(){return 0;}
|
||||||
void set_fcsr(uint32_t val){}
|
void set_fcsr(uint32_t val){}
|
||||||
|
|
|
@ -146,6 +146,8 @@ struct rv64ia: public arch_if {
|
||||||
|
|
||||||
uint64_t get_icount() { return reg.icount;}
|
uint64_t get_icount() { return reg.icount;}
|
||||||
|
|
||||||
|
bool should_stop(){return false;}
|
||||||
|
|
||||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
if(addr.space != traits<rv64ia>::MEM ||
|
if(addr.space != traits<rv64ia>::MEM ||
|
||||||
addr.type == iss::address_type::PHYSICAL ||
|
addr.type == iss::address_type::PHYSICAL ||
|
||||||
|
|
|
@ -62,6 +62,7 @@ void rv32gc::reset(uint64_t address) {
|
||||||
reg.NEXT_PC=reg.PC;
|
reg.NEXT_PC=reg.PC;
|
||||||
reg.trap_state=0;
|
reg.trap_state=0;
|
||||||
reg.machine_state=0x0;
|
reg.machine_state=0x0;
|
||||||
|
reg.icount=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* rv32gc::get_regs_base_ptr(){
|
uint8_t* rv32gc::get_regs_base_ptr(){
|
||||||
|
|
|
@ -63,6 +63,7 @@ void rv64ia::reset(uint64_t address) {
|
||||||
reg.NEXT_PC = reg.PC;
|
reg.NEXT_PC = reg.PC;
|
||||||
reg.trap_state = 0;
|
reg.trap_state = 0;
|
||||||
reg.machine_state = 0x3;
|
reg.machine_state = 0x3;
|
||||||
|
reg.icount=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(®); }
|
uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(®); }
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 019a04132a8beb7fcab24d504e3347ca0771ea5f
|
Subproject commit 57853f5df2ee573c35ef598a8a259696ae6059c0
|
Loading…
Reference in New Issue