4 Commits

16 changed files with 383 additions and 62 deletions

19
contrib/README.md Normal file
View File

@ -0,0 +1,19 @@
# requires conan version 1.59
# requires decent cmake version 3.23 for instance
git clone --recursive -b develop https://git.minres.com/TGFS/TGC-ISS.git
cd TGC-ISS/
setenv COWAREHOME /scratch/rocco/workarea/tools/synopsys/T-2022.06-3
setenv SNPSLMD_LICENSE_FILE 27001@lic02.arteris.com:5285@lic-node0:5285@lic03:5285@lic-node1
source $COWAREHOME/SLS/linux/setup.csh pae
setenv SNPS_ENABLE_MEM_ON_DEMAND_IN_GENERIC_MEM 1
setenv PATH $COWAREHOME/common/bin/:${PATH}
setenv LD_LIBRARY_PATH /scratch/rocco/workarea/tools/gcc-9.3.0-install/lib64/
setenv CC /scratch/rocco/workarea/tools/synopsys/T-2022.06-3/SLS/linux/common/bin//gcc
setenv CXX /scratch/rocco/workarea/tools/synopsys/T-2022.06-3/SLS/linux/common/bin//g++
cmake -S . -B build/Debug-PA -DCMAKE_BUILD_TYPE=Debug -DUSE_CWR_SYSTEMC=ON -DBUILD_SHARED_LIBS=ON -DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=/scratch/rocco/partners/minres/TGC-ISS/install
cd build/Debug-PA/
make -j 16 install
cd ../../dbt-rise-tgc/contrib
setenv TGFS_INSTALL_ROOT /scratch/rocco/partners/minres/TGC-ISS/install/
# import the TGC core itself
pct tgc_import.tcl

BIN
contrib/hello.elf Executable file

Binary file not shown.

View File

@ -6,13 +6,10 @@ proc getScriptDirectory {} {
set scriptFolder [file dirname $dispScriptFile]
return $scriptFolder
}
if { $::env(SNPS_VP_PRODUCT) == "PAULTRA" } {
set hardware /HARDWARE/HW/HW
} else {
set hardware /HARDWARE
}
set scriptDir [getScriptDirectory]
#set top_design_name sysc::tgfs::core_complex
set top_design_name core_complex
set clocks clk_i
set resets rst_i
@ -38,13 +35,14 @@ foreach clock ${clocks} {
foreach reset ${resets} {
::pct::set_block_port_protocol --set-category SYSTEM_LIBRARY:$block/${reset} SYSTEM_LIBRARY:RESET
}
::pct::set_encap_port_array_size SYSTEM_LIBRARY:$block/local_irq_i 16
#::pct::set_encap_port_array_size SYSTEM_LIBRARY:$block/local_irq_i 16
# Set compile settings and look
set block SYSTEM_LIBRARY:${top_design_name}
::pct::set_encap_build_script $block/${top_design_name} $scriptDir/build.tcl
::pct::set_encap_build_script $block/sysc::tgfs::${top_design_name} $scriptDir/build.tcl
::pct::set_background_color_rgb $block 255 255 255 255
::pct::create_instance SYSTEM_LIBRARY:${top_design_name} ${hardware} ${model_prefix}${top_design_name}${model_postfix} ${top_design_name}
::pct::create_instance SYSTEM_LIBRARY:${top_design_name} ${hardware} ${model_prefix}${top_design_name}${model_postfix} sysc::tgfs::${top_design_name} sysc::tgfs::${top_design_name}()
::pct::set_bounds i_${top_design_name} 200 300 100 400
# export the result as component
::pct::export_system_library ${top_design_name} ${top_design_name}.xml

61
contrib/tgc_import_tb.tcl Normal file
View File

@ -0,0 +1,61 @@
source tgc_import.tcl
set hardware /HARDWARE/HW/HW
set FW_name ${scriptDir}/hello.elf
puts "instantiate testbench elements"
::paultra::add_hw_instance GenericIPlib:Memory_Generic -inst_name i_Memory_Generic
::pct::set_bounds i_Memory_Generic 1000 300 100 100
::paultra::add_hw_instance Bus:Bus -inst_name i_Bus
::BLWizard::generateFramework i_Bus SBLTLM2FT * {} \
{ common_configuration:BackBone:/advanced/num_resources_per_target:1 }
::pct::set_bounds i_Bus 700 300 100 400
::pct::create_connection C_init i_core_complex/initiator i_Bus/i_core_complex_initiator
::pct::set_location_on_owner i_Bus/i_core_complex_initiator 10
::pct::create_connection C_targ i_Bus/i_Memory_Generic_MEM i_Memory_Generic/MEM
puts "instantiating clock manager"
set clock "Clk"
::hw::create_hw_instance "" GenericIPlib:ClockGenerator ${clock}_clock
::pct::set_bounds ${clock}_clock 100 100 100 100
::pct::set_param_value $hardware/${clock}_clock {Constructor Arguments} period 1000
::pct::set_param_value $hardware/${clock}_clock {Constructor Arguments} period_unit sc_core::SC_PS
puts "instantiating reset manager"
set reset "Rst"
::hw::create_hw_instance "" GenericIPlib:ResetGenerator ${reset}_reset
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} start_time 1000
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} start_time_unit sc_core::SC_PS
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} duration 10000
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} duration_unit sc_core::SC_PS
# ::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} active_level true
::pct::set_bounds ${reset}_reset 300 100 100 100
puts "connecting reset/clock"
::pct::create_connection C_clk . Clk_clock/CLK i_core_complex/clk_i
::pct::add_ports_to_connection C_clk i_Bus/Clk
::pct::create_connection C_rst . Rst_reset/RST i_core_complex/rst_i
::pct::add_ports_to_connection C_rst i_Bus/Rst
puts "setting parameters for DBT-RISE-TGC/Bus and memory components"
::pct::set_param_value $hardware/i_core_complex {Scml Properties} elf_file ${FW_name}
::pct::set_address i_core_complex/initiator:i_Memory_Generic/MEM 0x0
#::pct::set_main_configuration Default {{#include <scc/report.h>} {::scc::init_logging(::scc::LogConfig().logLevel(::scc::log::INFO).coloredOutput(false).logAsync(false));} {} {} {}}
#::pct::set_main_configuration Debug {{#include <scc/report.h>} {::scc::init_logging(::scc::LogConfig().logLevel(::scc::log::DEBUG).coloredOutput(false).logAsync(false));} {} {} {}}
#::pct::create_simulation_build_config Debug
#::pct::set_simulation_build_project_setting Debug "Main Configuration" Default
# add build settings and save design for next steps
#::pct::set_simulation_build_project_setting "Debug" "Linker Flags" "-Wl,-z,muldefs $::env(VERILATOR_ROOT)/include/verilated.cpp $::env(VERILATOR_ROOT)/include/verilated_vcd_sc.cpp $::env(VERILATOR_ROOT)/include/verilated_vcd_c.cpp"
#::pct::set_simulation_build_project_setting "Debug" "Include Paths" $::env(VERILATOR_ROOT)/include/
#::simulation::set_simulation_property Simulation [list run_for_duration:200ns results_dir:results/test_0 "TLM Port Trace:true"]
#::simulation::run_simulation Simulation
#::pct::set_simulation_build_project_setting Debug {Export Type} {STATIC NETLIST}
#::pct::set_simulation_build_project_setting Debug {Encapsulated Netlist} false
#::pct::export_system "export"
#::cd "export"
#::scsh::open-project
#::scsh::build
#::scsh::elab sim
::pct::save_system testbench.xml

View File

@ -146,18 +146,17 @@ protected:
inline void process_spawn_blocks() {
if(spawn_blocks.size()==0) return;
std::swap(super::ex_info.branch_taken, super::ex_info.hw_branch_taken);
for(auto it = std::begin(spawn_blocks); it!=std::end(spawn_blocks);)
if(*it){
(*it)();
++it;
} else
spawn_blocks.erase(it);
std::swap(super::ex_info.branch_taken, super::ex_info.hw_branch_taken);
}
<%functions.each{ it.eachLine { %>
${it}<%}%>
<%}%>
private:
/****************************************************************************
* start opcode definitions
@ -263,6 +262,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
auto inst_id = decode_inst_id(instr);
// pre execution stuff
this->core.last_branch = 0;
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
case arch::traits<ARCH>::opcode_e::${instr.name}: {

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2021 MINRES Technologies GmbH
* Copyright (C) 2019 - 2023 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -316,7 +316,9 @@ protected:
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
void set_curr_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
bool is_branch_taken() override { return arch.last_branch; };
riscv_hart_m_p<BASE, FEAT> &arch;
};
@ -420,6 +422,15 @@ protected:
feature_config cfg;
unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16};
inline bool debug_mode_active() {return this->reg.PRIV&0x4;}
std::pair<std::function<mem_read_f>, std::function<mem_write_f>>
replace_mem_access(std::function<mem_read_f> rd, std::function<mem_write_f> wr){
std::pair<std::function<mem_read_f>, std::function<mem_write_f>> ret{hart_mem_rd_delegate, hart_mem_wr_delegate};
hart_mem_rd_delegate = rd;
hart_mem_wr_delegate = wr;
return ret;
}
std::function<mem_read_f> hart_mem_rd_delegate;
std::function<mem_write_f> hart_mem_wr_delegate;
};
template <typename BASE, features_e FEAT>
@ -541,6 +552,12 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr;
csr_rd_cb[dcsr] = &this_class::read_dcsr_reg;
}
hart_mem_rd_delegate = [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status {
return this->read_mem(a, l, d);
};
hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status {
return this->write_mem(a, l, d);
};
}
template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT>::load_file(std::string name, int type) {
@ -661,9 +678,9 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
auto idx = std::distance(std::begin(memfn_range), it);
res = memfn_read[idx](phys_addr, length, data);
} else
res = read_mem( phys_addr, length, data);
res = hart_mem_rd_delegate( phys_addr, length, data);
} else {
res = read_mem( phys_addr, length, data);
res = hart_mem_rd_delegate( phys_addr, length, data);
}
if (unlikely(res != iss::Ok)){
this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, 2018, 2021 MINRES Technologies GmbH
* Copyright (C) 2017 - 2023 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -340,7 +340,9 @@ protected:
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; };
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
bool is_branch_taken() override { return arch.last_branch; };
riscv_hart_msu_vp<BASE> &arch;
};
@ -843,7 +845,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_reg(unsigned
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_cycle(unsigned addr, reg_t &val) {
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t &val) {
auto cycle_val = this->icount + cycle_offset;
if (addr == mcycle) {
val = static_cast<reg_t>(cycle_val);
@ -854,7 +856,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_cycle(unsigned a
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_cycle(unsigned addr, reg_t val) {
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_cycle(unsigned addr, reg_t val) {
if (sizeof(typename traits<BASE>::reg_t) != 4) {
if (addr == mcycleh)
return iss::Err;
@ -870,7 +872,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_cycle(unsigned
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_instret(unsigned addr, reg_t &val) {
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_instret(unsigned addr, reg_t &val) {
if ((addr&0xff) == (minstret&0xff)) {
val = static_cast<reg_t>(this->reg.instret);
} else if ((addr&0xff) == (minstreth&0xff)) {
@ -880,7 +882,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_instret(unsigned
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_instret(unsigned addr, reg_t val) {
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_instret(unsigned addr, reg_t val) {
if (sizeof(typename traits<BASE>::reg_t) != 4) {
if ((addr&0xff) == (minstreth&0xff))
return iss::Err;
@ -896,7 +898,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_instret(unsigne
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_time(unsigned addr, reg_t &val) {
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) {
uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052;
if (addr == time) {
val = static_cast<reg_t>(time_val);
@ -907,7 +909,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_time(unsigned ad
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_tvec(unsigned addr, reg_t &val) {
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_tvec(unsigned addr, reg_t &val) {
val = csr[addr] & ~2;
return iss::Ok;
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2021 MINRES Technologies GmbH
* Copyright (C) 2017 - 2023 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -340,7 +340,9 @@ protected:
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
void set_curr_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
bool is_branch_taken() override { return arch.last_branch; };
riscv_hart_mu_p<BASE, FEAT> &arch;
};
@ -447,6 +449,16 @@ protected:
feature_config cfg;
unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16};
inline bool debug_mode_active() {return this->reg.PRIV&0x4;}
std::pair<std::function<mem_read_f>, std::function<mem_write_f>>
replace_mem_access(std::function<mem_read_f> rd, std::function<mem_write_f> wr){
std::pair<std::function<mem_read_f>, std::function<mem_write_f>> ret{hart_mem_rd_delegate, hart_mem_wr_delegate};
hart_mem_rd_delegate = rd;
hart_mem_wr_delegate = wr;
return ret;
}
std::function<mem_read_f> hart_mem_rd_delegate;
std::function<mem_write_f> hart_mem_wr_delegate;
};
template <typename BASE, features_e FEAT>
@ -610,6 +622,12 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr;
csr_rd_cb[dcsr] = &this_class::read_dcsr_reg;
}
hart_mem_rd_delegate = [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status {
return this->read_mem(a, l, d);
};
hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status {
return this->write_mem(a, l, d);
};
}
template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_mu_p<BASE, FEAT>::load_file(std::string name, int type) {
@ -827,9 +845,9 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
auto idx = std::distance(std::begin(memfn_range), it);
res = memfn_read[idx](phys_addr, length, data);
} else
res = read_mem( phys_addr, length, data);
res = hart_mem_rd_delegate( phys_addr, length, data);
} else {
res = read_mem( phys_addr, length, data);
res = hart_mem_rd_delegate( phys_addr, length, data);
}
if (unlikely(res != iss::Ok)){
this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
@ -928,9 +946,9 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
auto idx = std::distance(std::begin(memfn_range), it);
res = memfn_write[idx]( phys_addr, length, data);
} else
res = write_mem( phys_addr, length, data);
res = hart_mem_wr_delegate( phys_addr, length, data);
} else {
res = write_mem( phys_addr, length, data);
res = hart_mem_wr_delegate( phys_addr, length, data);
}
if (unlikely(res != iss::Ok)) {
this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)

172
src/iss/arch/wt_cache.h Normal file
View File

@ -0,0 +1,172 @@
/*******************************************************************************
* Copyright (C) 2023 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 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
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* eyck@minres.com - initial implementation
******************************************************************************/
#ifndef _RISCV_HART_M_P_WT_CACHE_H
#define _RISCV_HART_M_P_WT_CACHE_H
#include <iss/vm_types.h>
#include <util/ities.h>
#include <vector>
#include <map>
#include <memory>
namespace iss {
namespace arch {
namespace cache {
enum class state { INVALID, VALID};
struct line {
uint64_t tag_addr{0};
state st{state::INVALID};
std::vector<uint8_t> data;
line(unsigned line_sz): data(line_sz) {}
};
struct set {
std::vector<line> ways;
set(unsigned ways_count, line const& l): ways(ways_count, l) {}
};
struct cache {
std::vector<set> sets;
cache(unsigned size, unsigned line_sz, unsigned ways) {
line const ref_line{line_sz};
set const ref_set{ways, ref_line};
sets.resize(size/(ways*line_sz), ref_set);
}
};
struct wt_policy {
bool is_cacheline_hit(cache& c );
};
}
// write thru, allocate on read, direct mapped or set-associative with round-robin replacement policy
template <typename BASE> class wt_cache : public BASE {
public:
using base_class = BASE;
using this_class = wt_cache<BASE>;
using reg_t = typename BASE::reg_t;
using mem_read_f = typename BASE::mem_read_f;
using mem_write_f = typename BASE::mem_write_f;
using phys_addr_t = typename BASE::phys_addr_t;
wt_cache();
virtual ~wt_cache() = default;
unsigned size{4096};
unsigned line_sz{32};
unsigned ways{1};
uint64_t io_address{0xf0000000};
uint64_t io_addr_mask{0xf0000000};
protected:
iss::status read_cache(phys_addr_t addr, unsigned, uint8_t *const);
iss::status write_cache(phys_addr_t addr, unsigned, uint8_t const *const);
std::function<mem_read_f> cache_mem_rd_delegate;
std::function<mem_write_f> cache_mem_wr_delegate;
std::unique_ptr<cache::cache> dcache_ptr;
std::unique_ptr<cache::cache> icache_ptr;
size_t get_way_select() {
return 0;
}
};
template<typename BASE>
inline wt_cache<BASE>::wt_cache() {
auto cb = base_class::replace_mem_access(
[this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return read_cache(a, l,d);},
[this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return write_cache(a, l,d);});
cache_mem_rd_delegate = cb.first;
cache_mem_wr_delegate = cb.second;
}
template<typename BASE>
iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
if(!icache_ptr) {
icache_ptr.reset(new cache::cache(size, line_sz, ways));
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
}
if((a.val&io_addr_mask) != io_address) {
auto set_addr=(a.val&(size-1))>>util::ilog2(line_sz*ways);
auto tag_addr=a.val>>util::ilog2(line_sz);
auto& set = (a.access==access_type::FETCH?icache_ptr:dcache_ptr)->sets[set_addr];
for(auto& cl: set.ways) {
if(cl.st==cache::state::VALID && cl.tag_addr==tag_addr) {
auto start_addr = a.val&(line_sz-1);
for(auto i = 0U; i<l; ++i)
d[i] = cl.data[start_addr+i];
return iss::Ok;
}
}
auto& cl = set.ways[get_way_select()];
phys_addr_t cl_addr{a};
cl_addr.val=tag_addr<<util::ilog2(line_sz);
cache_mem_rd_delegate(cl_addr, line_sz, cl.data.data());
cl.tag_addr=tag_addr;
cl.st=cache::state::VALID;
auto start_addr = a.val&(line_sz-1);
for(auto i = 0U; i<l; ++i)
d[i] = cl.data[start_addr+i];
return iss::Ok;
} else
return cache_mem_rd_delegate(a, l, d);
}
template<typename BASE>
iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
if(!dcache_ptr)
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
auto res = cache_mem_wr_delegate(a, l, d);
if(res == iss::Ok && ((a.val&io_addr_mask) != io_address)) {
auto set_addr=(a.val&(size-1))>>util::ilog2(line_sz*ways);
auto tag_addr=a.val>>util::ilog2(line_sz);
auto& set = dcache_ptr->sets[set_addr];
for(auto& cl: set.ways) {
if(cl.st==cache::state::VALID && cl.tag_addr==tag_addr) {
auto start_addr = a.val&(line_sz-1);
for(auto i = 0U; i<l; ++i)
cl.data[start_addr+1] = d[i];
break;
}
}
}
return res;
}
} // namespace arch
} // namespace iss
#endif /* _RISCV_HART_M_P_H */

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -107,12 +107,12 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
}
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const& exc_info) {
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
assert(instr_if && "No instrumentation interface available but callback executed");
auto entry = delays[instr_info.instr_id];
bool taken = exc_info.branch_taken;
if (exc_info.branch_taken && (entry.taken > 1))
instr_if->set_curr_instr_cycles(entry.taken);
bool taken = instr_if->is_branch_taken();
if (taken && (entry.taken > 1))
instr_if->update_last_instr_cycles(entry.taken);
else if (entry.not_taken > 1)
instr_if->set_curr_instr_cycles(entry.not_taken);
instr_if->update_last_instr_cycles(entry.not_taken);
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, 2018, MINRES Technologies GmbH
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -78,7 +78,7 @@ public:
sync_type get_sync() override { return POST_SYNC; };
void callback(instr_info_t instr_info, exec_info const&) override;
void callback(instr_info_t instr_info) override;
private:
iss::instrumentation_if *instr_if;

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, MINRES Technologies GmbH
* Copyright (C) 2017 - 2023 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -90,6 +90,6 @@ bool iss::plugin::instruction_count::registration(const char* const version, vm_
return true;
}
void iss::plugin::instruction_count::callback(instr_info_t instr_info, exec_info const&) {
void iss::plugin::instruction_count::callback(instr_info_t instr_info) {
rep_counts[instr_info.instr_id]++;
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, 2018, MINRES Technologies GmbH
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -69,7 +69,7 @@ public:
sync_type get_sync() override { return POST_SYNC; };
void callback(instr_info_t, exec_info const&) override;
void callback(instr_info_t) override;
private:
Json::Value root;

View File

@ -1,3 +1,37 @@
/*******************************************************************************
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 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
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* alex.com - initial implementation
******************************************************************************/
#include <iss/arch_if.h>
#include <iss/plugin/pctrace.h>
#include <util/logging.h>
@ -152,22 +186,22 @@ bool pctrace::registration(const char *const version, vm_if& vm) {
return true;
}
void pctrace::callback(instr_info_t iinfo, const exec_info& einfo) {
void pctrace::callback(instr_info_t iinfo) {
auto delay = 0;
size_t id = iinfo.instr_id;
auto entry = delays[id];
auto instr = instr_if->get_instr_word();
auto call = id==65 || id ==86 || ((id==2 || id==3) && bit_sub<7,5>(instr)!=0) ;//not taking care of tail calls (jalr with loading x6)
bool taken = einfo.branch_taken;
bool taken = instr_if->is_branch_taken();
bool compressed = (instr&0x3)!=0x3;
if (einfo.branch_taken) {
if (taken) {
delay = entry.taken;
if(entry.taken > 1)
instr_if->set_curr_instr_cycles(entry.taken);
instr_if->update_last_instr_cycles(entry.taken);
} else {
delay = entry.not_taken;
if (entry.not_taken > 1)
instr_if->set_curr_instr_cycles(entry.not_taken);
instr_if->update_last_instr_cycles(entry.not_taken);
}
#ifndef WITH_LZ4
output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n";

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2017, 2018, MINRES Technologies GmbH
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -83,7 +83,7 @@ public:
sync_type get_sync() override { return POST_SYNC; };
void callback(instr_info_t, exec_info const&) override;
void callback(instr_info_t) override;
private:
iss::instrumentation_if *instr_if {nullptr};

View File

@ -140,16 +140,15 @@ protected:
inline void process_spawn_blocks() {
if(spawn_blocks.size()==0) return;
std::swap(super::ex_info.branch_taken, super::ex_info.hw_branch_taken);
for(auto it = std::begin(spawn_blocks); it!=std::end(spawn_blocks);)
if(*it){
(*it)();
++it;
} else
spawn_blocks.erase(it);
std::swap(super::ex_info.branch_taken, super::ex_info.hw_branch_taken);
}
private:
/****************************************************************************
* start opcode definitions
@ -341,6 +340,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
auto inst_id = decode_inst_id(instr);
// pre execution stuff
this->core.last_branch = 0;
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
switch(inst_id){
case arch::traits<ARCH>::opcode_e::LUI: {
@ -422,7 +422,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*(X+rd) = *PC + 4;
}
*NEXT_PC = *PC + (int32_t)sext<21>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -457,7 +457,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*(X+rd) = *PC + 4;
}
*NEXT_PC = new_pc & ~ 0x1;
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -489,7 +489,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -522,7 +522,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -555,7 +555,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -588,7 +588,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -621,7 +621,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -654,7 +654,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
*NEXT_PC = *PC + (int16_t)sext<13>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
}
@ -2097,7 +2097,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
{
*(X+1) = *PC + 2;
*NEXT_PC = *PC + (int16_t)sext<12>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
TRAP_CJAL:break;
}// @suppress("No break at end of case")
@ -2342,7 +2342,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction
{
*NEXT_PC = *PC + (int16_t)sext<12>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
TRAP_CJ:break;
}// @suppress("No break at end of case")
@ -2363,7 +2363,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
{
if(*(X+rs1 + 8) == 0) {
*NEXT_PC = *PC + (int16_t)sext<9>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
TRAP_CBEQZ:break;
@ -2385,7 +2385,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
{
if(*(X+rs1 + 8) != 0) {
*NEXT_PC = *PC + (int16_t)sext<9>(imm);
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
TRAP_CBNEZ:break;
@ -2485,7 +2485,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
{
if(rs1 && rs1 < traits::RFS) {
*NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1;
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
else {
raise(0, 2);
@ -2553,7 +2553,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
uint32_t new_pc = *(X+rs1);
*(X+1) = *PC + 2;
*NEXT_PC = new_pc & ~ 0x1;
super::ex_info.branch_taken=true;
this->core.last_branch = 1;
}
}
TRAP_CJALR:break;