Compare commits
	
		
			4 Commits
		
	
	
		
			8ff55d7b92
			...
			1672b01e62
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1672b01e62 | |||
| 00b0f101ac | |||
|   | 54f75f92ea | ||
|   | 0304aac9e5 | 
							
								
								
									
										19
									
								
								contrib/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								contrib/README.md
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										
											BIN
										
									
								
								contrib/hello.elf
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -6,13 +6,10 @@ proc getScriptDirectory {} { | |||||||
|     set scriptFolder [file dirname $dispScriptFile] |     set scriptFolder [file dirname $dispScriptFile] | ||||||
|     return $scriptFolder |     return $scriptFolder | ||||||
| } | } | ||||||
| if { $::env(SNPS_VP_PRODUCT) == "PAULTRA" } { |  | ||||||
|     set hardware /HARDWARE/HW/HW |     set hardware /HARDWARE/HW/HW | ||||||
| } else { |  | ||||||
|     set hardware /HARDWARE |  | ||||||
| } |  | ||||||
|  |  | ||||||
| set scriptDir [getScriptDirectory] | set scriptDir [getScriptDirectory] | ||||||
|  | #set top_design_name sysc::tgfs::core_complex | ||||||
| set top_design_name core_complex | set top_design_name core_complex | ||||||
| set clocks clk_i | set clocks clk_i | ||||||
| set resets rst_i | set resets rst_i | ||||||
| @@ -38,13 +35,14 @@ foreach clock ${clocks} { | |||||||
| foreach reset ${resets} { | foreach reset ${resets} { | ||||||
|     ::pct::set_block_port_protocol --set-category SYSTEM_LIBRARY:$block/${reset} SYSTEM_LIBRARY:RESET |     ::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 compile settings and look | ||||||
| set block SYSTEM_LIBRARY:${top_design_name} | 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::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 | # export the result as component | ||||||
| ::pct::export_system_library ${top_design_name}  ${top_design_name}.xml | ::pct::export_system_library ${top_design_name}  ${top_design_name}.xml | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								contrib/tgc_import_tb.tcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								contrib/tgc_import_tb.tcl
									
									
									
									
									
										Normal 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 | ||||||
| @@ -146,18 +146,17 @@ protected: | |||||||
|      |      | ||||||
|     inline void process_spawn_blocks() { |     inline void process_spawn_blocks() { | ||||||
|         if(spawn_blocks.size()==0) return; |         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);) |         for(auto it = std::begin(spawn_blocks); it!=std::end(spawn_blocks);) | ||||||
|              if(*it){ |              if(*it){ | ||||||
|                  (*it)(); |                  (*it)(); | ||||||
|                  ++it; |                  ++it; | ||||||
|              } else |              } else | ||||||
|                  spawn_blocks.erase(it); |                  spawn_blocks.erase(it); | ||||||
|         std::swap(super::ex_info.branch_taken, super::ex_info.hw_branch_taken); |  | ||||||
|     } |     } | ||||||
| <%functions.each{ it.eachLine { %> | <%functions.each{ it.eachLine { %> | ||||||
|     ${it}<%}%> |     ${it}<%}%> | ||||||
| <%}%> | <%}%> | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     /**************************************************************************** |     /**************************************************************************** | ||||||
|      * start opcode definitions |      * 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' |                     (instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0' | ||||||
|             auto inst_id = decode_inst_id(instr); |             auto inst_id = decode_inst_id(instr); | ||||||
|             // pre execution stuff |             // pre execution stuff | ||||||
|  |             this->core.last_branch = 0; | ||||||
|             if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id)); |             if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id)); | ||||||
|             switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %> |             switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %> | ||||||
|             case arch::traits<ARCH>::opcode_e::${instr.name}: { |             case arch::traits<ARCH>::opcode_e::${instr.name}: { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2021 MINRES Technologies GmbH |  * Copyright (C) 2019 - 2023 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 | ||||||
| @@ -316,7 +316,9 @@ protected: | |||||||
|  |  | ||||||
|         uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; } |         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; |         riscv_hart_m_p<BASE, FEAT> &arch; | ||||||
|     }; |     }; | ||||||
| @@ -420,6 +422,15 @@ protected: | |||||||
|     feature_config cfg; |     feature_config cfg; | ||||||
|     unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16}; |     unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16}; | ||||||
|     inline bool debug_mode_active() {return this->reg.PRIV&0x4;} |     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> | 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_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; | ||||||
|         csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; |         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) { | 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); |                         auto idx = std::distance(std::begin(memfn_range), it); | ||||||
|                         res = memfn_read[idx](phys_addr, length, data); |                         res = memfn_read[idx](phys_addr, length, data); | ||||||
|                     } else |                     } else | ||||||
|                         res = read_mem( phys_addr, length, data); |                         res = hart_mem_rd_delegate( phys_addr, length, data); | ||||||
|                 } else { |                 } else { | ||||||
|                     res = read_mem( phys_addr, length, data); |                     res = hart_mem_rd_delegate( phys_addr, length, data); | ||||||
|                 } |                 } | ||||||
|                 if (unlikely(res != iss::Ok)){ |                 if (unlikely(res != iss::Ok)){ | ||||||
|                     this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault |                     this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2017, 2018, 2021 MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023 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 | ||||||
| @@ -340,7 +340,9 @@ protected: | |||||||
|  |  | ||||||
|         uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; } |         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; |         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; |     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; |     auto cycle_val = this->icount + cycle_offset; | ||||||
|     if (addr == mcycle) { |     if (addr == mcycle) { | ||||||
|         val = static_cast<reg_t>(cycle_val); |         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; |     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 (sizeof(typename traits<BASE>::reg_t) != 4) { | ||||||
|         if (addr == mcycleh) |         if (addr == mcycleh) | ||||||
|             return iss::Err; |             return iss::Err; | ||||||
| @@ -870,7 +872,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_cycle(unsigned | |||||||
|     return iss::Ok; |     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)) { |     if ((addr&0xff) == (minstret&0xff)) { | ||||||
|         val = static_cast<reg_t>(this->reg.instret); |         val = static_cast<reg_t>(this->reg.instret); | ||||||
|     } else if ((addr&0xff) == (minstreth&0xff)) { |     } 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; |     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 (sizeof(typename traits<BASE>::reg_t) != 4) { | ||||||
|         if ((addr&0xff) == (minstreth&0xff)) |         if ((addr&0xff) == (minstreth&0xff)) | ||||||
|             return iss::Err; |             return iss::Err; | ||||||
| @@ -896,7 +898,7 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_instret(unsigne | |||||||
|     return iss::Ok; |     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; |     uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052; | ||||||
|     if (addr == time) { |     if (addr == time) { | ||||||
|         val = static_cast<reg_t>(time_val); |         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; |     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; |     val = csr[addr] & ~2; | ||||||
|     return iss::Ok; |     return iss::Ok; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2021 MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023 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 | ||||||
| @@ -340,7 +340,9 @@ protected: | |||||||
|  |  | ||||||
|         uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; } |         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; |         riscv_hart_mu_p<BASE, FEAT> &arch; | ||||||
|     }; |     }; | ||||||
| @@ -447,6 +449,16 @@ protected: | |||||||
|     feature_config cfg; |     feature_config cfg; | ||||||
|     unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16}; |     unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16}; | ||||||
|     inline bool debug_mode_active() {return this->reg.PRIV&0x4;} |     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> | 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_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; | ||||||
|         csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; |         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) { | 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); |                         auto idx = std::distance(std::begin(memfn_range), it); | ||||||
|                         res = memfn_read[idx](phys_addr, length, data); |                         res = memfn_read[idx](phys_addr, length, data); | ||||||
|                     } else |                     } else | ||||||
|                         res = read_mem( phys_addr, length, data); |                         res = hart_mem_rd_delegate( phys_addr, length, data); | ||||||
|                 } else { |                 } else { | ||||||
|                     res = read_mem( phys_addr, length, data); |                     res = hart_mem_rd_delegate( phys_addr, length, data); | ||||||
|                 } |                 } | ||||||
|                 if (unlikely(res != iss::Ok)){ |                 if (unlikely(res != iss::Ok)){ | ||||||
|                     this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault |                     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); |                         auto idx = std::distance(std::begin(memfn_range), it); | ||||||
|                         res = memfn_write[idx]( phys_addr, length, data); |                         res = memfn_write[idx]( phys_addr, length, data); | ||||||
|                     } else |                     } else | ||||||
|                         res = write_mem( phys_addr, length, data); |                         res = hart_mem_wr_delegate( phys_addr, length, data); | ||||||
|                 } else { |                 } else { | ||||||
|                     res = write_mem( phys_addr, length, data); |                     res = hart_mem_wr_delegate( phys_addr, length, data); | ||||||
|                 } |                 } | ||||||
|                 if (unlikely(res != iss::Ok)) { |                 if (unlikely(res != iss::Ok)) { | ||||||
|                     this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) |                     this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) | ||||||
|   | |||||||
							
								
								
									
										172
									
								
								src/iss/arch/wt_cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								src/iss/arch/wt_cache.h
									
									
									
									
									
										Normal 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 */ | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2017, MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023, 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 | ||||||
| @@ -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"); |     assert(instr_if && "No instrumentation interface available but callback executed"); | ||||||
|     auto entry = delays[instr_info.instr_id]; |     auto entry = delays[instr_info.instr_id]; | ||||||
|     bool taken = exc_info.branch_taken; |     bool taken = instr_if->is_branch_taken(); | ||||||
|     if (exc_info.branch_taken && (entry.taken > 1)) |     if (taken && (entry.taken > 1)) | ||||||
|         instr_if->set_curr_instr_cycles(entry.taken); |         instr_if->update_last_instr_cycles(entry.taken); | ||||||
|     else if (entry.not_taken > 1) |     else if (entry.not_taken > 1) | ||||||
|         instr_if->set_curr_instr_cycles(entry.not_taken); |         instr_if->update_last_instr_cycles(entry.not_taken); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2017, 2018, MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023, 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 | ||||||
| @@ -78,7 +78,7 @@ public: | |||||||
|  |  | ||||||
|     sync_type get_sync() override { return POST_SYNC; }; |     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: | private: | ||||||
|     iss::instrumentation_if *instr_if; |     iss::instrumentation_if *instr_if; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2017, MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023 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 | ||||||
| @@ -90,6 +90,6 @@ bool iss::plugin::instruction_count::registration(const char* const version, vm_ | |||||||
| 	return true; | 	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]++; | 	rep_counts[instr_info.instr_id]++; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2017, 2018, MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023, 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 | ||||||
| @@ -69,7 +69,7 @@ public: | |||||||
|  |  | ||||||
|     sync_type get_sync() override { return POST_SYNC; }; |     sync_type get_sync() override { return POST_SYNC; }; | ||||||
|  |  | ||||||
|     void callback(instr_info_t, exec_info const&) override; |     void callback(instr_info_t) override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     Json::Value root; |     Json::Value root; | ||||||
|   | |||||||
| @@ -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/arch_if.h> | ||||||
| #include <iss/plugin/pctrace.h> | #include <iss/plugin/pctrace.h> | ||||||
| #include <util/logging.h> | #include <util/logging.h> | ||||||
| @@ -152,22 +186,22 @@ bool pctrace::registration(const char *const version, vm_if& vm) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| void pctrace::callback(instr_info_t iinfo, const exec_info& einfo) { | void pctrace::callback(instr_info_t iinfo) { | ||||||
|     auto delay = 0; |     auto delay = 0; | ||||||
|     size_t id = iinfo.instr_id; |     size_t id = iinfo.instr_id; | ||||||
|     auto entry = delays[id]; |     auto entry = delays[id]; | ||||||
|     auto instr = instr_if->get_instr_word(); |     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) |     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; |     bool compressed = (instr&0x3)!=0x3; | ||||||
|     if (einfo.branch_taken) { |     if (taken) { | ||||||
|         delay = entry.taken; |         delay = entry.taken; | ||||||
|         if(entry.taken > 1) |         if(entry.taken > 1) | ||||||
|             instr_if->set_curr_instr_cycles(entry.taken); |             instr_if->update_last_instr_cycles(entry.taken); | ||||||
|     } else { |     } else { | ||||||
|         delay = entry.not_taken; |         delay = entry.not_taken; | ||||||
|         if (entry.not_taken > 1) |         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 | #ifndef WITH_LZ4 | ||||||
|     output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n"; |     output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n"; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|  * Copyright (C) 2017, 2018, MINRES Technologies GmbH |  * Copyright (C) 2017 - 2023, 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 | ||||||
| @@ -83,7 +83,7 @@ public: | |||||||
|  |  | ||||||
|     sync_type get_sync() override { return POST_SYNC; }; |     sync_type get_sync() override { return POST_SYNC; }; | ||||||
|  |  | ||||||
|     void callback(instr_info_t, exec_info const&) override; |     void callback(instr_info_t) override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     iss::instrumentation_if *instr_if  {nullptr}; |     iss::instrumentation_if *instr_if  {nullptr}; | ||||||
|   | |||||||
| @@ -140,16 +140,15 @@ protected: | |||||||
|      |      | ||||||
|     inline void process_spawn_blocks() { |     inline void process_spawn_blocks() { | ||||||
|         if(spawn_blocks.size()==0) return; |         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);) |         for(auto it = std::begin(spawn_blocks); it!=std::end(spawn_blocks);) | ||||||
|              if(*it){ |              if(*it){ | ||||||
|                  (*it)(); |                  (*it)(); | ||||||
|                  ++it; |                  ++it; | ||||||
|              } else |              } else | ||||||
|                  spawn_blocks.erase(it); |                  spawn_blocks.erase(it); | ||||||
|         std::swap(super::ex_info.branch_taken, super::ex_info.hw_branch_taken); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     /**************************************************************************** |     /**************************************************************************** | ||||||
|      * start opcode definitions |      * 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' |                     (instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0' | ||||||
|             auto inst_id = decode_inst_id(instr); |             auto inst_id = decode_inst_id(instr); | ||||||
|             // pre execution stuff |             // pre execution stuff | ||||||
|  |             this->core.last_branch = 0; | ||||||
|             if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id)); |             if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id)); | ||||||
|             switch(inst_id){ |             switch(inst_id){ | ||||||
|             case arch::traits<ARCH>::opcode_e::LUI: { |             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; |                                             *(X+rd) = *PC +  4; | ||||||
|                                         } |                                         } | ||||||
|                                         *NEXT_PC = *PC + (int32_t)sext<21>(imm); |                                         *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; |                                             *(X+rd) = *PC +  4; | ||||||
|                                         } |                                         } | ||||||
|                                         *NEXT_PC = new_pc & ~ 0x1; |                                         *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 { |                                         else { | ||||||
|                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                             *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 { |                                         else { | ||||||
|                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                             *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 { |                                         else { | ||||||
|                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                             *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 { |                                         else { | ||||||
|                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                             *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 { |                                         else { | ||||||
|                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                             *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 { |                                         else { | ||||||
|                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                             *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; |                     *(X+1) = *PC +  2; | ||||||
|                     *NEXT_PC = *PC + (int16_t)sext<12>(imm); |                     *NEXT_PC = *PC + (int16_t)sext<12>(imm); | ||||||
|                     super::ex_info.branch_taken=true; |                     this->core.last_branch = 1; | ||||||
|                 } |                 } | ||||||
|                 TRAP_CJAL:break; |                 TRAP_CJAL:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @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 |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 *NEXT_PC = *PC + (int16_t)sext<12>(imm); |                                 *NEXT_PC = *PC + (int16_t)sext<12>(imm); | ||||||
|                                 super::ex_info.branch_taken=true; |                                 this->core.last_branch = 1; | ||||||
|                             } |                             } | ||||||
|                 TRAP_CJ:break; |                 TRAP_CJ:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @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) { |                                 if(*(X+rs1 +  8) ==  0) { | ||||||
|                                     *NEXT_PC = *PC + (int16_t)sext<9>(imm); |                                     *NEXT_PC = *PC + (int16_t)sext<9>(imm); | ||||||
|                                     super::ex_info.branch_taken=true; |                                     this->core.last_branch = 1; | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_CBEQZ:break; |                 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) { |                                 if(*(X+rs1 +  8) !=  0) { | ||||||
|                                     *NEXT_PC = *PC + (int16_t)sext<9>(imm); |                                     *NEXT_PC = *PC + (int16_t)sext<9>(imm); | ||||||
|                                     super::ex_info.branch_taken=true; |                                     this->core.last_branch = 1; | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_CBNEZ:break; |                 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) { |                                 if(rs1 && rs1 < traits::RFS) { | ||||||
|                                     *NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1; |                                     *NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1; | ||||||
|                                     super::ex_info.branch_taken=true; |                                     this->core.last_branch = 1; | ||||||
|                                 } |                                 } | ||||||
|                                 else { |                                 else { | ||||||
|                                     raise(0, 2); |                                     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); |                                     uint32_t new_pc = *(X+rs1); | ||||||
|                                     *(X+1) = *PC +  2; |                                     *(X+1) = *PC +  2; | ||||||
|                                     *NEXT_PC = new_pc & ~ 0x1; |                                     *NEXT_PC = new_pc & ~ 0x1; | ||||||
|                                     super::ex_info.branch_taken=true; |                                     this->core.last_branch = 1; | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_CJALR:break; |                 TRAP_CJALR:break; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user