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