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] | ||||
|     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
									
								
							
							
						
						
									
										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() { | ||||
|         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}: { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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
									
								
							
							
						
						
									
										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. | ||||
|  * | ||||
|  * 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); | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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]++; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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"; | ||||
|   | ||||
| @@ -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}; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user