diff options
Diffstat (limited to 'VexRiscv/src/test/cpp/regression')
19 files changed, 7250 insertions, 0 deletions
diff --git a/VexRiscv/src/test/cpp/regression/.gitignore b/VexRiscv/src/test/cpp/regression/.gitignore new file mode 100644 index 0000000..576890f --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/.gitignore @@ -0,0 +1,3 @@ +*.regTraceRef +/freertos.gtkw +*.cproject diff --git a/VexRiscv/src/test/cpp/regression/atomic.gtkw b/VexRiscv/src/test/cpp/regression/atomic.gtkw new file mode 100644 index 0000000..26e6575 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/atomic.gtkw @@ -0,0 +1,52 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Thu Jan 4 16:18:18 2018 +[*] +[dumpfile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/atomic.vcd" +[dumpfile_mtime] "Thu Jan 4 16:18:11 2018" +[dumpfile_size] 19545269 +[savefile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/atomic.gtkw" +[timestart] 1478 +[size] 1784 950 +[pos] -1 -1 +*-7.000000 1726 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 289 +[signals_width] 559 +[sst_expanded] 1 +[sst_vpaned_height] 191 +@22 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0] +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0] +@28 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid +TOP.VexRiscv.dataCache_1.stageB_atomic_entriesHit +@22 +TOP.VexRiscv.dataCache_1.stageB_atomic_entries_0_address[31:0] +@28 +TOP.VexRiscv.dataCache_1.stageB_atomic_entries_0_size[1:0] +TOP.VexRiscv.dataCache_1.stageB_atomic_entries_0_valid +@22 +TOP.VexRiscv.dataCache_1.stageB_atomic_entries_1_address[31:0] +@28 +TOP.VexRiscv.dataCache_1.stageB_atomic_entries_1_size[1:0] +TOP.VexRiscv.dataCache_1.stageB_atomic_entries_1_valid +@29 +[color] 1 +TOP.VexRiscv.writeBack_arbitration_isFiring +[color] 1 +TOP.VexRiscv.writeBack_arbitration_isValid +@23 +[color] 1 +TOP.VexRiscv.writeBack_PC[31:0] +@28 +TOP.VexRiscv.CsrPlugin_mstatus_MIE +TOP.VexRiscv.CsrPlugin_mstatus_MPIE +TOP.VexRiscv.CsrPlugin_mstatus_MPP[1:0] +@24 +TOP.VexRiscv.RegFilePlugin_regFile(28)[31:0] +@22 +TOP.VexRiscv.CsrPlugin_mepc[31:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/branch.gtkw b/VexRiscv/src/test/cpp/regression/branch.gtkw new file mode 100644 index 0000000..9bd2437 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/branch.gtkw @@ -0,0 +1,31 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Mon Mar 20 10:40:36 2017 +[*] +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dhrystoneO3M.vcd" +[dumpfile_mtime] "Mon Mar 20 10:40:36 2017" +[dumpfile_size] 1149914709 +[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/branch.gtkw" +[timestart] 68 +[size] 1776 953 +[pos] -775 -1 +*-4.000000 87 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[sst_width] 432 +[signals_width] 520 +[sst_expanded] 1 +[sst_vpaned_height] 279 +@28 +TOP.VexRiscv.execute_input_HISTORY_LINE_history[1:0] +TOP.VexRiscv.fetch_HISTORY_LINE_history[1:0] +TOP.VexRiscv.memory_input_HISTORY_LINE_history[1:0] +TOP.VexRiscv.decode_arbitration_isValid +TOP.VexRiscv.decode_arbitration_isFiring +@22 +TOP.VexRiscv.decode_input_PC[31:0] +@28 +TOP.VexRiscv.decode_input_HISTORY_LINE_history[1:0] +@29 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/dcache.gtkw b/VexRiscv/src/test/cpp/regression/dcache.gtkw new file mode 100644 index 0000000..388eb87 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/dcache.gtkw @@ -0,0 +1,85 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Sun Apr 23 13:26:26 2017 +[*] +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-sw.vcd" +[dumpfile_mtime] "Sun Apr 23 13:04:48 2017" +[dumpfile_size] 389364 +[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dcache.gtkw" +[timestart] 569 +[size] 1776 953 +[pos] -1 -353 +*-3.252876 591 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 387 +[signals_width] 376 +[sst_expanded] 1 +[sst_vpaned_height] 253 +@800200 +-execute +@28 +TOP.VexRiscv.dataCache_1.io_cpu_execute_isValid +@22 +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_address[31:0] +@28 +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_all +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_bypass +@22 +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_data[31:0] +@28 +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_kind[1:0] +@22 +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_mask[3:0] +@28 +TOP.VexRiscv.dataCache_1.io_cpu_execute_args_wr +TOP.VexRiscv.dataCache_1.io_cpu_execute_isStuck +@1000200 +-execute +@28 +TOP.VexRiscv.dataCache_1.io_cpu_memory_isStuck +@800200 +-writeBack +@22 +TOP.VexRiscv.dataCache_1.io_cpu_writeBack_data[31:0] +@28 +TOP.VexRiscv.dataCache_1.io_cpu_writeBack_haltIt +TOP.VexRiscv.dataCache_1.io_cpu_writeBack_isStuck +TOP.VexRiscv.dataCache_1.io_cpu_writeBack_isValid +@1000200 +-writeBack +@22 +TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_address[31:0] +TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_data[31:0] +TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_mask[3:0] +@28 +TOP.VexRiscv.dataCache_1.io_mem_cmd_payload_wr +TOP.VexRiscv.dataCache_1.io_mem_cmd_ready +TOP.VexRiscv.dataCache_1.io_mem_cmd_valid +@22 +TOP.VexRiscv.dataCache_1.io_mem_rsp_payload_data[31:0] +@28 +TOP.VexRiscv.dataCache_1.io_mem_rsp_valid +TOP.VexRiscv.dataCache_1.dataWriteCmd_payload_address[2:0] +@22 +TOP.VexRiscv.dataCache_1.dataWriteCmd_payload_data[31:0] +TOP.VexRiscv.dataCache_1.dataWriteCmd_payload_mask[3:0] +@28 +TOP.VexRiscv.dataCache_1.dataWriteCmd_valid +TOP.VexRiscv.dataCache_1.clk +TOP.VexRiscv.dataCache_1.way_dataReadRspTwoEnable +@22 +TOP.VexRiscv.dataCache_1.way_dataReadRspTwo[31:0] +@28 +TOP.VexRiscv.dataCache_1.way_tagReadRspTwoEnable +@22 +TOP.VexRiscv.dataCache_1.way_tagReadRspTwo_address[26:0] +@28 +TOP.VexRiscv.dataCache_1.way_tagReadRspTwo_dirty +TOP.VexRiscv.dataCache_1.way_tagReadRspTwo_used +@29 +TOP.VexRiscv.dataCache_1.way_dataReadRspOneAddress[2:0] +@22 +TOP.VexRiscv.dataCache_1.way_dataReadRspOne[31:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/debug.gtkw b/VexRiscv/src/test/cpp/regression/debug.gtkw new file mode 100644 index 0000000..d22d878 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/debug.gtkw @@ -0,0 +1,96 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Thu Feb 1 00:52:25 2018 +[*] +[dumpfile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/rv32ui-p-lui.vcd" +[dumpfile_mtime] "Thu Feb 1 00:52:17 2018" +[dumpfile_size] 183735 +[savefile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/debug.gtkw" +[timestart] 0 +[size] 1784 950 +[pos] -1 -1 +*-3.000000 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 409 +[signals_width] 540 +[sst_expanded] 1 +[sst_vpaned_height] 271 +@22 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[31:0] +@28 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid +@22 +TOP.VexRiscv.prefetch_PC[31:0] +@28 +TOP.VexRiscv.debug_bus_cmd_valid +TOP.VexRiscv.reset +TOP.VexRiscv.clk +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_samplePcNext +@22 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pcBeforeJumps[31:0] +@28 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid +TOP.VexRiscv.fetch_BranchPlugin_hit +TOP.VexRiscv.execute_BRANCH_DO +@22 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pcReg[31:0] +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pc[31:0] +@28 +TOP.VexRiscv.prefetch_arbitration_isValid +TOP.VexRiscv.fetch_arbitration_isValid +TOP.VexRiscv.decode_arbitration_isValid +TOP.VexRiscv.execute_arbitration_isValid +TOP.VexRiscv.memory_arbitration_isValid +TOP.VexRiscv.writeBack_arbitration_isValid +TOP.VexRiscv.CsrPlugin_interrupt +TOP.VexRiscv.CsrPlugin_exception +TOP.VexRiscv.decode_arbitration_isStuck +TOP.VexRiscv.decode_arbitration_isStuckByOthers +TOP.VexRiscv.execute_arbitration_isStuck +TOP.VexRiscv.execute_arbitration_isStuckByOthers +TOP.VexRiscv.fetch_arbitration_isStuck +TOP.VexRiscv.fetch_arbitration_isStuckByOthers +TOP.VexRiscv.memory_arbitration_isStuck +TOP.VexRiscv.memory_arbitration_isStuckByOthers +TOP.VexRiscv.prefetch_arbitration_isStuck +TOP.VexRiscv.prefetch_arbitration_isStuckByOthers +TOP.VexRiscv.writeBack_arbitration_isStuck +TOP.VexRiscv.writeBack_arbitration_isStuckByOthers +TOP.VexRiscv.iBus_cmd_valid +TOP.VexRiscv.iBus_cmd_ready +@22 +TOP.VexRiscv.iBus_cmd_payload_pc[31:0] +@28 +TOP.VexRiscv.iBus_rsp_error +@22 +TOP.VexRiscv.iBus_rsp_inst[31:0] +@28 +TOP.VexRiscv.iBus_rsp_ready +TOP.VexRiscv.debug_bus_cmd_valid +@22 +TOP.VexRiscv.BranchPlugin_counter[8:0] +@28 +TOP.VexRiscv.decode_IS_EBREAK +TOP.VexRiscv.execute_IS_EBREAK +TOP.VexRiscv.CsrPlugin_pipelineLiberator_done +TOP.VexRiscv.CsrPlugin_pipelineLiberator_enable +TOP.VexRiscv.DebugPlugin_haltIt +@22 +TOP.VexRiscv.writeBack_INSTRUCTION[31:0] +@29 +TOP.VexRiscv.DebugPlugin_stepIt +@22 +TOP.VexRiscv.debug_bus_cmd_payload_address[7:0] +TOP.VexRiscv.debug_bus_cmd_payload_data[31:0] +@28 +TOP.VexRiscv.debug_bus_cmd_payload_wr +TOP.VexRiscv.debug_bus_cmd_ready +TOP.VexRiscv.debug_bus_cmd_valid +@22 +TOP.VexRiscv.debug_bus_rsp_data[31:0] +@28 +TOP.VexRiscv.debug_resetOut +TOP.VexRiscv.debugReset +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/default.gtkw b/VexRiscv/src/test/cpp/regression/default.gtkw new file mode 100644 index 0000000..cea3b75 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/default.gtkw @@ -0,0 +1,100 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Sat Mar 25 13:21:38 2017 +[*] +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/machineCsr.vcd" +[dumpfile_mtime] "Sat Mar 25 13:21:31 2017" +[dumpfile_size] 2048473 +[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/default.gtkw" +[timestart] 0 +[size] 1776 953 +[pos] -1 -1 +*-9.770813 718 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 294 +[signals_width] 597 +[sst_expanded] 1 +[sst_vpaned_height] 593 +@28 +TOP.VexRiscv.writeBack_arbitration_isValid +@22 +TOP.VexRiscv.writeBack_PC[31:0] +TOP.VexRiscv.writeBack_INSTRUCTION[31:0] +TOP.VexRiscv.RegFilePlugin_regFile(10)[31:0] +TOP.VexRiscv.RegFilePlugin_regFile(11)[31:0] +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pcBeforeJumps[31:0] +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pc[31:0] +TOP.VexRiscv.MachineCsr_mepc[31:0] +@28 +TOP.VexRiscv.timerInterrupt +TOP.VexRiscv.execute_arbitration_isValid +@22 +TOP.VexRiscv.execute_PC[31:0] +@28 +TOP.VexRiscv.MachineCsr_mie_MEIE +TOP.VexRiscv.MachineCsr_mie_MSIE +TOP.VexRiscv.MachineCsr_mie_MTIE +TOP.VexRiscv.MachineCsr_mstatus_MIE +TOP.VexRiscv.MachineCsr_mip_MEIP +TOP.VexRiscv.MachineCsr_mip_MSIP +TOP.VexRiscv.MachineCsr_mip_MTIP +TOP.VexRiscv.MachineCsr_interrupt +TOP.VexRiscv.MachineCsr_writeBackWfi +TOP.VexRiscv.writeBack_arbitration_isValid +TOP.VexRiscv.writeBack_ENV_CTRL[2:0] +TOP.VexRiscv.execute_EXCEPTION +TOP.VexRiscv.memory_EXCEPTION +TOP.VexRiscv.writeBack_EXCEPTION +TOP.VexRiscv.prefetch_arbitration_isValid +TOP.VexRiscv.fetch_arbitration_isValid +TOP.VexRiscv.decode_arbitration_isValid +TOP.VexRiscv.execute_arbitration_isValid +TOP.VexRiscv.memory_arbitration_isValid +TOP.VexRiscv.writeBack_arbitration_isValid +TOP.VexRiscv.prefetch_arbitration_removeIt +TOP.VexRiscv.fetch_arbitration_removeIt +@29 +TOP.VexRiscv.decode_arbitration_removeIt +@28 +TOP.VexRiscv.execute_arbitration_removeIt +TOP.VexRiscv.memory_arbitration_removeIt +TOP.VexRiscv.writeBack_arbitration_removeIt +TOP.VexRiscv.prefetch_arbitration_isStuck +TOP.VexRiscv.fetch_arbitration_isStuck +TOP.VexRiscv.decode_arbitration_isStuck +TOP.VexRiscv.execute_arbitration_isStuck +TOP.VexRiscv.memory_arbitration_isStuck +TOP.VexRiscv.writeBack_arbitration_isStuck +@22 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[31:0] +@28 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid +@22 +TOP.VexRiscv.MachineCsr_mepc[31:0] +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pcReg[31:0] +TOP.VexRiscv.prefetch_PC_CALC_WITHOUT_JUMP[31:0] +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_pc[31:0] +TOP.VexRiscv.prefetch_PC[31:0] +TOP.VexRiscv.fetch_PC[31:0] +TOP.VexRiscv.decode_PC[31:0] +TOP.VexRiscv.execute_PC[31:0] +TOP.VexRiscv.memory_PC[31:0] +TOP.VexRiscv.writeBack_PC[31:0] +@28 +TOP.VexRiscv.prefetch_arbitration_isStuckByOthers +TOP.VexRiscv.fetch_arbitration_isStuckByOthers +TOP.VexRiscv.decode_arbitration_isStuckByOthers +TOP.VexRiscv.execute_arbitration_isStuckByOthers +TOP.VexRiscv.memory_arbitration_isStuckByOthers +TOP.VexRiscv.writeBack_arbitration_isStuckByOthers +TOP.VexRiscv.prefetch_arbitration_haltIt +TOP.VexRiscv.fetch_arbitration_haltIt +TOP.VexRiscv.decode_arbitration_haltIt +TOP.VexRiscv.execute_arbitration_haltIt +TOP.VexRiscv.memory_arbitration_haltIt +TOP.VexRiscv.writeBack_arbitration_haltIt +TOP.VexRiscv.MachineCsr_mie_MTIE +TOP.VexRiscv.MachineCsr_mip_MTIP +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/dhrystoneO3.logRef b/VexRiscv/src/test/cpp/regression/dhrystoneO3.logRef new file mode 100644 index 0000000..1bdf354 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/dhrystoneO3.logRef @@ -0,0 +1,57 @@ + +Dhrystone Benchmark, Version 2.1 (Language: C) + +Program compiled without 'register' attribute + +Please give the number of runs through the benchmark: +Execution starts, 200 runs through Dhrystone +Execution ends + +Final values of the variables used in the benchmark: + +Int_Glob: 5 + should be: 5 +Bool_Glob: 1 + should be: 1 +Ch_1_Glob: A + should be: A +Ch_2_Glob: B + should be: B +Arr_1_Glob[8]: 7 + should be: 7 +Arr_2_Glob[8][7]: 210 + should be: Number_Of_Runs + 10 +Ptr_Glob-> + Ptr_Comp: -2147458812 + should be: (implementation-dependent) + Discr: 0 + should be: 0 + Enum_Comp: 2 + should be: 2 + Int_Comp: 17 + should be: 17 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Next_Ptr_Glob-> + Ptr_Comp: -2147458812 + should be: (implementation-dependent), same as above + Discr: 0 + should be: 0 + Enum_Comp: 1 + should be: 1 + Int_Comp: 18 + should be: 18 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Int_1_Loc: 5 + should be: 5 +Int_2_Loc: 13 + should be: 13 +Int_3_Loc: 7 + should be: 7 +Enum_Loc: 1 + should be: 1 +Str_1_Loc: DHRYSTONE PROGRAM, 1'ST STRING + should be: DHRYSTONE PROGRAM, 1'ST STRING +Str_2_Loc: DHRYSTONE PROGRAM, 2'ND STRING + should be: DHRYSTONE PROGRAM, 2'ND STRING diff --git a/VexRiscv/src/test/cpp/regression/dhrystoneO3C.logRef b/VexRiscv/src/test/cpp/regression/dhrystoneO3C.logRef new file mode 100644 index 0000000..9985a89 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/dhrystoneO3C.logRef @@ -0,0 +1,57 @@ + +Dhrystone Benchmark, Version 2.1 (Language: C) + +Program compiled without 'register' attribute + +Please give the number of runs through the benchmark: +Execution starts, 200 runs through Dhrystone +Execution ends + +Final values of the variables used in the benchmark: + +Int_Glob: 5 + should be: 5 +Bool_Glob: 1 + should be: 1 +Ch_1_Glob: A + should be: A +Ch_2_Glob: B + should be: B +Arr_1_Glob[8]: 7 + should be: 7 +Arr_2_Glob[8][7]: 210 + should be: Number_Of_Runs + 10 +Ptr_Glob-> + Ptr_Comp: -2147459900 + should be: (implementation-dependent) + Discr: 0 + should be: 0 + Enum_Comp: 2 + should be: 2 + Int_Comp: 17 + should be: 17 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Next_Ptr_Glob-> + Ptr_Comp: -2147459900 + should be: (implementation-dependent), same as above + Discr: 0 + should be: 0 + Enum_Comp: 1 + should be: 1 + Int_Comp: 18 + should be: 18 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Int_1_Loc: 5 + should be: 5 +Int_2_Loc: 13 + should be: 13 +Int_3_Loc: 7 + should be: 7 +Enum_Loc: 1 + should be: 1 +Str_1_Loc: DHRYSTONE PROGRAM, 1'ST STRING + should be: DHRYSTONE PROGRAM, 1'ST STRING +Str_2_Loc: DHRYSTONE PROGRAM, 2'ND STRING + should be: DHRYSTONE PROGRAM, 2'ND STRING diff --git a/VexRiscv/src/test/cpp/regression/dhrystoneO3M.logRef b/VexRiscv/src/test/cpp/regression/dhrystoneO3M.logRef new file mode 100644 index 0000000..1c6f8d1 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/dhrystoneO3M.logRef @@ -0,0 +1,57 @@ + +Dhrystone Benchmark, Version 2.1 (Language: C) + +Program compiled without 'register' attribute + +Please give the number of runs through the benchmark: +Execution starts, 200 runs through Dhrystone +Execution ends + +Final values of the variables used in the benchmark: + +Int_Glob: 5 + should be: 5 +Bool_Glob: 1 + should be: 1 +Ch_1_Glob: A + should be: A +Ch_2_Glob: B + should be: B +Arr_1_Glob[8]: 7 + should be: 7 +Arr_2_Glob[8][7]: 210 + should be: Number_Of_Runs + 10 +Ptr_Glob-> + Ptr_Comp: -2147459860 + should be: (implementation-dependent) + Discr: 0 + should be: 0 + Enum_Comp: 2 + should be: 2 + Int_Comp: 17 + should be: 17 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Next_Ptr_Glob-> + Ptr_Comp: -2147459860 + should be: (implementation-dependent), same as above + Discr: 0 + should be: 0 + Enum_Comp: 1 + should be: 1 + Int_Comp: 18 + should be: 18 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Int_1_Loc: 5 + should be: 5 +Int_2_Loc: 13 + should be: 13 +Int_3_Loc: 7 + should be: 7 +Enum_Loc: 1 + should be: 1 +Str_1_Loc: DHRYSTONE PROGRAM, 1'ST STRING + should be: DHRYSTONE PROGRAM, 1'ST STRING +Str_2_Loc: DHRYSTONE PROGRAM, 2'ND STRING + should be: DHRYSTONE PROGRAM, 2'ND STRING diff --git a/VexRiscv/src/test/cpp/regression/dhrystoneO3MC.logRef b/VexRiscv/src/test/cpp/regression/dhrystoneO3MC.logRef new file mode 100644 index 0000000..a584b67 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/dhrystoneO3MC.logRef @@ -0,0 +1,57 @@ + +Dhrystone Benchmark, Version 2.1 (Language: C) + +Program compiled without 'register' attribute + +Please give the number of runs through the benchmark: +Execution starts, 200 runs through Dhrystone +Execution ends + +Final values of the variables used in the benchmark: + +Int_Glob: 5 + should be: 5 +Bool_Glob: 1 + should be: 1 +Ch_1_Glob: A + should be: A +Ch_2_Glob: B + should be: B +Arr_1_Glob[8]: 7 + should be: 7 +Arr_2_Glob[8][7]: 210 + should be: Number_Of_Runs + 10 +Ptr_Glob-> + Ptr_Comp: -2147460916 + should be: (implementation-dependent) + Discr: 0 + should be: 0 + Enum_Comp: 2 + should be: 2 + Int_Comp: 17 + should be: 17 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Next_Ptr_Glob-> + Ptr_Comp: -2147460916 + should be: (implementation-dependent), same as above + Discr: 0 + should be: 0 + Enum_Comp: 1 + should be: 1 + Int_Comp: 18 + should be: 18 + Str_Comp: DHRYSTONE PROGRAM, SOME STRING + should be: DHRYSTONE PROGRAM, SOME STRING +Int_1_Loc: 5 + should be: 5 +Int_2_Loc: 13 + should be: 13 +Int_3_Loc: 7 + should be: 7 +Enum_Loc: 1 + should be: 1 +Str_1_Loc: DHRYSTONE PROGRAM, 1'ST STRING + should be: DHRYSTONE PROGRAM, 1'ST STRING +Str_2_Loc: DHRYSTONE PROGRAM, 2'ND STRING + should be: DHRYSTONE PROGRAM, 2'ND STRING diff --git a/VexRiscv/src/test/cpp/regression/encoding.h b/VexRiscv/src/test/cpp/regression/encoding.h new file mode 100644 index 0000000..c109ce1 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/encoding.h @@ -0,0 +1,1471 @@ +// See LICENSE for license details. + +#ifndef RISCV_CSR_ENCODING_H +#define RISCV_CSR_ENCODING_H + +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_HPP 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_SUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_TVM 0x00100000 +#define MSTATUS_TW 0x00200000 +#define MSTATUS_TSR 0x00400000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS_UXL 0x0000000300000000 +#define MSTATUS_SXL 0x0000000C00000000 +#define MSTATUS64_SD 0x8000000000000000 + +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_SUM 0x00040000 +#define SSTATUS_MXR 0x00080000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS_UXL 0x0000000300000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1<<29) +#define DCSR_FULLRESET (1<<28) +#define DCSR_EBREAKM (1<<15) +#define DCSR_EBREAKH (1<<14) +#define DCSR_EBREAKS (1<<13) +#define DCSR_EBREAKU (1<<12) +#define DCSR_STOPCYCLE (1<<10) +#define DCSR_STOPTIME (1<<9) +#define DCSR_CAUSE (7<<6) +#define DCSR_DEBUGINT (1<<5) +#define DCSR_HALT (1<<3) +#define DCSR_STEP (1<<2) +#define DCSR_PRV (3<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define MCONTROL_SELECT (1<<19) +#define MCONTROL_TIMING (1<<18) +#define MCONTROL_ACTION (0x3f<<12) +#define MCONTROL_CHAIN (1<<11) +#define MCONTROL_MATCH (0xf<<7) +#define MCONTROL_M (1<<6) +#define MCONTROL_H (1<<5) +#define MCONTROL_S (1<<4) +#define MCONTROL_U (1<<3) +#define MCONTROL_EXECUTE (1<<2) +#define MCONTROL_STORE (1<<1) +#define MCONTROL_LOAD (1<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define SATP32_MODE 0x80000000 +#define SATP32_ASID 0x7FC00000 +#define SATP32_PPN 0x003FFFFF +#define SATP64_MODE 0xF000000000000000 +#define SATP64_ASID 0x0FFFF00000000000 +#define SATP64_PPN 0x00000FFFFFFFFFFF + +#define SATP_MODE_OFF 0 +#define SATP_MODE_SV32 1 +#define SATP_MODE_SV39 8 +#define SATP_MODE_SV48 9 +#define SATP_MODE_SV57 10 +#define SATP_MODE_SV64 11 + +#define PMP_R 0x01 +#define PMP_W 0x02 +#define PMP_X 0x04 +#define PMP_A 0x18 +#define PMP_L 0x80 +#define PMP_SHIFT 2 + +#define PMP_TOR 0x08 +#define PMP_NA4 0x10 +#define PMP_NAPOT 0x18 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +#define DEFAULT_RSTVEC 0x00001000 +#define CLINT_BASE 0x02000000 +#define CLINT_SIZE 0x000c0000 +#define EXT_IO_BASE 0x40000000 +#define DRAM_BASE 0x80000000 + +// page table entry (PTE) fields +#define PTE_V 0x001 // Valid +#define PTE_R 0x002 // Read +#define PTE_W 0x004 // Write +#define PTE_X 0x008 // Execute +#define PTE_U 0x010 // User +#define PTE_G 0x020 // Global +#define PTE_A 0x040 // Accessed +#define PTE_D 0x080 // Dirty +#define PTE_SOFT 0x300 // Reserved for Software + +#define PTE_PPN_SHIFT 10 + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#ifdef __riscv + +#if __riscv_xlen == 64 +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +# define SATP_MODE SATP64_MODE +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +# define SATP_MODE SATP32_MODE +#endif +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#ifndef __ASSEMBLER__ + +#ifdef __GNUC__ + +#define read_csr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define write_csr(reg, val) ({ \ + asm volatile ("csrw " #reg ", %0" :: "rK"(val)); }) + +#define swap_csr(reg, val) ({ unsigned long __tmp; \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \ + __tmp; }) + +#define set_csr(reg, bit) ({ unsigned long __tmp; \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \ + __tmp; }) + +#define clear_csr(reg, bit) ({ unsigned long __tmp; \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \ + __tmp; }) + +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) + +#endif + +#endif + +#endif + +#endif +/* Automatically generated by parse-opcodes. */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_JALR 0x67 +#define MASK_JALR 0x707f +#define MATCH_JAL 0x6f +#define MASK_JAL 0x7f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_ADD 0x33 +#define MASK_ADD 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_ECALL 0x73 +#define MASK_ECALL 0xffffffff +#define MATCH_EBREAK 0x100073 +#define MASK_EBREAK 0xffffffff +#define MATCH_URET 0x200073 +#define MASK_URET 0xffffffff +#define MATCH_SRET 0x10200073 +#define MASK_SRET 0xffffffff +#define MATCH_MRET 0x30200073 +#define MASK_MRET 0xffffffff +#define MATCH_DRET 0x7b200073 +#define MASK_DRET 0xffffffff +#define MATCH_SFENCE_VMA 0x12000073 +#define MASK_SFENCE_VMA 0xfe007fff +#define MATCH_WFI 0x10500073 +#define MASK_WFI 0xffffffff +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FSGNJ_S 0x20000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_FSGNJN_S 0x20001053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_FSGNJX_S 0x20002053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FMIN_S 0x28000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_FMAX_S 0x28001053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_FSQRT_S 0x58000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_FSGNJ_D 0x22000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_FSGNJN_D 0x22001053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FSGNJX_D 0x22002053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_FMIN_D 0x2a000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_FMAX_D 0x2a001053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_FCVT_S_D 0x40100053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_FCVT_D_S 0x42000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FSQRT_D 0x5a000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_FADD_Q 0x6000053 +#define MASK_FADD_Q 0xfe00007f +#define MATCH_FSUB_Q 0xe000053 +#define MASK_FSUB_Q 0xfe00007f +#define MATCH_FMUL_Q 0x16000053 +#define MASK_FMUL_Q 0xfe00007f +#define MATCH_FDIV_Q 0x1e000053 +#define MASK_FDIV_Q 0xfe00007f +#define MATCH_FSGNJ_Q 0x26000053 +#define MASK_FSGNJ_Q 0xfe00707f +#define MATCH_FSGNJN_Q 0x26001053 +#define MASK_FSGNJN_Q 0xfe00707f +#define MATCH_FSGNJX_Q 0x26002053 +#define MASK_FSGNJX_Q 0xfe00707f +#define MATCH_FMIN_Q 0x2e000053 +#define MASK_FMIN_Q 0xfe00707f +#define MATCH_FMAX_Q 0x2e001053 +#define MASK_FMAX_Q 0xfe00707f +#define MATCH_FCVT_S_Q 0x40300053 +#define MASK_FCVT_S_Q 0xfff0007f +#define MATCH_FCVT_Q_S 0x46000053 +#define MASK_FCVT_Q_S 0xfff0007f +#define MATCH_FCVT_D_Q 0x42300053 +#define MASK_FCVT_D_Q 0xfff0007f +#define MATCH_FCVT_Q_D 0x46100053 +#define MASK_FCVT_Q_D 0xfff0007f +#define MATCH_FSQRT_Q 0x5e000053 +#define MASK_FSQRT_Q 0xfff0007f +#define MATCH_FLE_S 0xa0000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FLT_S 0xa0001053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_FEQ_S 0xa0002053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FLE_D 0xa2000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FLT_D 0xa2001053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_FEQ_D 0xa2002053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_FLE_Q 0xa6000053 +#define MASK_FLE_Q 0xfe00707f +#define MATCH_FLT_Q 0xa6001053 +#define MASK_FLT_Q 0xfe00707f +#define MATCH_FEQ_Q 0xa6002053 +#define MASK_FEQ_Q 0xfe00707f +#define MATCH_FCVT_W_S 0xc0000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_FCVT_WU_S 0xc0100053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_FCVT_L_S 0xc0200053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_FCVT_LU_S 0xc0300053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_FMV_X_W 0xe0000053 +#define MASK_FMV_X_W 0xfff0707f +#define MATCH_FCLASS_S 0xe0001053 +#define MASK_FCLASS_S 0xfff0707f +#define MATCH_FCVT_W_D 0xc2000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_FCVT_WU_D 0xc2100053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_FCVT_L_D 0xc2200053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_LU_D 0xc2300053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_FCLASS_D 0xe2001053 +#define MASK_FCLASS_D 0xfff0707f +#define MATCH_FCVT_W_Q 0xc6000053 +#define MASK_FCVT_W_Q 0xfff0007f +#define MATCH_FCVT_WU_Q 0xc6100053 +#define MASK_FCVT_WU_Q 0xfff0007f +#define MATCH_FCVT_L_Q 0xc6200053 +#define MASK_FCVT_L_Q 0xfff0007f +#define MATCH_FCVT_LU_Q 0xc6300053 +#define MASK_FCVT_LU_Q 0xfff0007f +#define MATCH_FMV_X_Q 0xe6000053 +#define MASK_FMV_X_Q 0xfff0707f +#define MATCH_FCLASS_Q 0xe6001053 +#define MASK_FCLASS_Q 0xfff0707f +#define MATCH_FCVT_S_W 0xd0000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_FCVT_S_WU 0xd0100053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_FCVT_S_L 0xd0200053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_FCVT_S_LU 0xd0300053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_FMV_W_X 0xf0000053 +#define MASK_FMV_W_X 0xfff0707f +#define MATCH_FCVT_D_W 0xd2000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_FCVT_D_WU 0xd2100053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_FCVT_D_L 0xd2200053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_FCVT_D_LU 0xd2300053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_FCVT_Q_W 0xd6000053 +#define MASK_FCVT_Q_W 0xfff0007f +#define MATCH_FCVT_Q_WU 0xd6100053 +#define MASK_FCVT_Q_WU 0xfff0007f +#define MATCH_FCVT_Q_L 0xd6200053 +#define MASK_FCVT_Q_L 0xfff0007f +#define MATCH_FCVT_Q_LU 0xd6300053 +#define MASK_FCVT_Q_LU 0xfff0007f +#define MATCH_FMV_Q_X 0xf6000053 +#define MASK_FMV_Q_X 0xfff0707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FLQ 0x4007 +#define MASK_FLQ 0x707f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_FSQ 0x4027 +#define MASK_FSQ 0x707f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_FMADD_Q 0x6000043 +#define MASK_FMADD_Q 0x600007f +#define MATCH_FMSUB_Q 0x6000047 +#define MASK_FMSUB_Q 0x600007f +#define MATCH_FNMSUB_Q 0x600004b +#define MASK_FNMSUB_Q 0x600007f +#define MATCH_FNMADD_Q 0x600004f +#define MASK_FNMADD_Q 0x600007f +#define MATCH_C_NOP 0x1 +#define MASK_C_NOP 0xffff +#define MATCH_C_ADDI16SP 0x6101 +#define MASK_C_ADDI16SP 0xef83 +#define MATCH_C_JR 0x8002 +#define MASK_C_JR 0xf07f +#define MATCH_C_JALR 0x9002 +#define MASK_C_JALR 0xf07f +#define MATCH_C_EBREAK 0x9002 +#define MASK_C_EBREAK 0xffff +#define MATCH_C_LD 0x6000 +#define MASK_C_LD 0xe003 +#define MATCH_C_SD 0xe000 +#define MASK_C_SD 0xe003 +#define MATCH_C_ADDIW 0x2001 +#define MASK_C_ADDIW 0xe003 +#define MATCH_C_LDSP 0x6002 +#define MASK_C_LDSP 0xe003 +#define MATCH_C_SDSP 0xe002 +#define MASK_C_SDSP 0xe003 +#define MATCH_C_ADDI4SPN 0x0 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_FLD 0x2000 +#define MASK_C_FLD 0xe003 +#define MATCH_C_LW 0x4000 +#define MASK_C_LW 0xe003 +#define MATCH_C_FLW 0x6000 +#define MASK_C_FLW 0xe003 +#define MATCH_C_FSD 0xa000 +#define MASK_C_FSD 0xe003 +#define MATCH_C_SW 0xc000 +#define MASK_C_SW 0xe003 +#define MATCH_C_FSW 0xe000 +#define MASK_C_FSW 0xe003 +#define MATCH_C_ADDI 0x1 +#define MASK_C_ADDI 0xe003 +#define MATCH_C_JAL 0x2001 +#define MASK_C_JAL 0xe003 +#define MATCH_C_LI 0x4001 +#define MASK_C_LI 0xe003 +#define MATCH_C_LUI 0x6001 +#define MASK_C_LUI 0xe003 +#define MATCH_C_SRLI 0x8001 +#define MASK_C_SRLI 0xec03 +#define MATCH_C_SRAI 0x8401 +#define MASK_C_SRAI 0xec03 +#define MATCH_C_ANDI 0x8801 +#define MASK_C_ANDI 0xec03 +#define MATCH_C_SUB 0x8c01 +#define MASK_C_SUB 0xfc63 +#define MATCH_C_XOR 0x8c21 +#define MASK_C_XOR 0xfc63 +#define MATCH_C_OR 0x8c41 +#define MASK_C_OR 0xfc63 +#define MATCH_C_AND 0x8c61 +#define MASK_C_AND 0xfc63 +#define MATCH_C_SUBW 0x9c01 +#define MASK_C_SUBW 0xfc63 +#define MATCH_C_ADDW 0x9c21 +#define MASK_C_ADDW 0xfc63 +#define MATCH_C_J 0xa001 +#define MASK_C_J 0xe003 +#define MATCH_C_BEQZ 0xc001 +#define MASK_C_BEQZ 0xe003 +#define MATCH_C_BNEZ 0xe001 +#define MASK_C_BNEZ 0xe003 +#define MATCH_C_SLLI 0x2 +#define MASK_C_SLLI 0xe003 +#define MATCH_C_FLDSP 0x2002 +#define MASK_C_FLDSP 0xe003 +#define MATCH_C_LWSP 0x4002 +#define MASK_C_LWSP 0xe003 +#define MATCH_C_FLWSP 0x6002 +#define MASK_C_FLWSP 0xe003 +#define MATCH_C_MV 0x8002 +#define MASK_C_MV 0xf003 +#define MATCH_C_ADD 0x9002 +#define MASK_C_ADD 0xf003 +#define MATCH_C_FSDSP 0xa002 +#define MASK_C_FSDSP 0xe003 +#define MATCH_C_SWSP 0xc002 +#define MASK_C_SWSP 0xe003 +#define MATCH_C_FSWSP 0xe002 +#define MASK_C_FSWSP 0xe003 +#define MATCH_CUSTOM0 0xb +#define MASK_CUSTOM0 0x707f +#define MATCH_CUSTOM0_RS1 0x200b +#define MASK_CUSTOM0_RS1 0x707f +#define MATCH_CUSTOM0_RS1_RS2 0x300b +#define MASK_CUSTOM0_RS1_RS2 0x707f +#define MATCH_CUSTOM0_RD 0x400b +#define MASK_CUSTOM0_RD 0x707f +#define MATCH_CUSTOM0_RD_RS1 0x600b +#define MASK_CUSTOM0_RD_RS1 0x707f +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b +#define MASK_CUSTOM0_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM1 0x2b +#define MASK_CUSTOM1 0x707f +#define MATCH_CUSTOM1_RS1 0x202b +#define MASK_CUSTOM1_RS1 0x707f +#define MATCH_CUSTOM1_RS1_RS2 0x302b +#define MASK_CUSTOM1_RS1_RS2 0x707f +#define MATCH_CUSTOM1_RD 0x402b +#define MASK_CUSTOM1_RD 0x707f +#define MATCH_CUSTOM1_RD_RS1 0x602b +#define MASK_CUSTOM1_RD_RS1 0x707f +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b +#define MASK_CUSTOM1_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM2 0x5b +#define MASK_CUSTOM2 0x707f +#define MATCH_CUSTOM2_RS1 0x205b +#define MASK_CUSTOM2_RS1 0x707f +#define MATCH_CUSTOM2_RS1_RS2 0x305b +#define MASK_CUSTOM2_RS1_RS2 0x707f +#define MATCH_CUSTOM2_RD 0x405b +#define MASK_CUSTOM2_RD 0x707f +#define MATCH_CUSTOM2_RD_RS1 0x605b +#define MASK_CUSTOM2_RD_RS1 0x707f +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b +#define MASK_CUSTOM2_RD_RS1_RS2 0x707f +#define MATCH_CUSTOM3 0x7b +#define MASK_CUSTOM3 0x707f +#define MATCH_CUSTOM3_RS1 0x207b +#define MASK_CUSTOM3_RS1 0x707f +#define MATCH_CUSTOM3_RS1_RS2 0x307b +#define MASK_CUSTOM3_RS1_RS2 0x707f +#define MATCH_CUSTOM3_RD 0x407b +#define MASK_CUSTOM3_RD 0x707f +#define MATCH_CUSTOM3_RD_RS1 0x607b +#define MASK_CUSTOM3_RD_RS1 0x707f +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b +#define MASK_CUSTOM3_RD_RS1_RS2 0x707f +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_SSTATUS 0x100 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 +#define CSR_SATP 0x180 +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MIP 0x344 +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2 +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FETCH_ACCESS 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_LOAD_ACCESS 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_STORE_ACCESS 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#define CAUSE_FETCH_PAGE_FAULT 0xc +#define CAUSE_LOAD_PAGE_FAULT 0xd +#define CAUSE_STORE_PAGE_FAULT 0xf +#endif +#ifdef DECLARE_INSN +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) +DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) +DECLARE_INSN(uret, MATCH_URET, MASK_URET) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) +DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) +DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA) +DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q) +DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q) +DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q) +DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q) +DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q) +DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q) +DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q) +DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q) +DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q) +DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q) +DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S) +DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q) +DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D) +DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q) +DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q) +DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) +DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q) +DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q) +DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q) +DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q) +DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q) +DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W) +DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU) +DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) +DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) +DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q) +DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q) +DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q) +DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q) +DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) +DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) +DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) +DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) +DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) +DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +#endif +#ifdef DECLARE_CSR +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) +DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) +DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) +DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) +DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) +DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) +DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) +DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) +DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) +DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) +DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) +DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) +DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) +DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) +DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) +DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) +DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) +DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) +DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) +DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) +DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) +DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) +DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) +DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) +DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) +DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) +DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) +DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) +DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(sie, CSR_SIE) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(scounteren, CSR_SCOUNTEREN) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(stval, CSR_STVAL) +DECLARE_CSR(sip, CSR_SIP) +DECLARE_CSR(satp, CSR_SATP) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(misa, CSR_MISA) +DECLARE_CSR(medeleg, CSR_MEDELEG) +DECLARE_CSR(mideleg, CSR_MIDELEG) +DECLARE_CSR(mie, CSR_MIE) +DECLARE_CSR(mtvec, CSR_MTVEC) +DECLARE_CSR(mcounteren, CSR_MCOUNTEREN) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mtval, CSR_MTVAL) +DECLARE_CSR(mip, CSR_MIP) +DECLARE_CSR(pmpcfg0, CSR_PMPCFG0) +DECLARE_CSR(pmpcfg1, CSR_PMPCFG1) +DECLARE_CSR(pmpcfg2, CSR_PMPCFG2) +DECLARE_CSR(pmpcfg3, CSR_PMPCFG3) +DECLARE_CSR(pmpaddr0, CSR_PMPADDR0) +DECLARE_CSR(pmpaddr1, CSR_PMPADDR1) +DECLARE_CSR(pmpaddr2, CSR_PMPADDR2) +DECLARE_CSR(pmpaddr3, CSR_PMPADDR3) +DECLARE_CSR(pmpaddr4, CSR_PMPADDR4) +DECLARE_CSR(pmpaddr5, CSR_PMPADDR5) +DECLARE_CSR(pmpaddr6, CSR_PMPADDR6) +DECLARE_CSR(pmpaddr7, CSR_PMPADDR7) +DECLARE_CSR(pmpaddr8, CSR_PMPADDR8) +DECLARE_CSR(pmpaddr9, CSR_PMPADDR9) +DECLARE_CSR(pmpaddr10, CSR_PMPADDR10) +DECLARE_CSR(pmpaddr11, CSR_PMPADDR11) +DECLARE_CSR(pmpaddr12, CSR_PMPADDR12) +DECLARE_CSR(pmpaddr13, CSR_PMPADDR13) +DECLARE_CSR(pmpaddr14, CSR_PMPADDR14) +DECLARE_CSR(pmpaddr15, CSR_PMPADDR15) +DECLARE_CSR(tselect, CSR_TSELECT) +DECLARE_CSR(tdata1, CSR_TDATA1) +DECLARE_CSR(tdata2, CSR_TDATA2) +DECLARE_CSR(tdata3, CSR_TDATA3) +DECLARE_CSR(dcsr, CSR_DCSR) +DECLARE_CSR(dpc, CSR_DPC) +DECLARE_CSR(dscratch, CSR_DSCRATCH) +DECLARE_CSR(mcycle, CSR_MCYCLE) +DECLARE_CSR(minstret, CSR_MINSTRET) +DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) +DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) +DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) +DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) +DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) +DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) +DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) +DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) +DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) +DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) +DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) +DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) +DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) +DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) +DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) +DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) +DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) +DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) +DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) +DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) +DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) +DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) +DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) +DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) +DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) +DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) +DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) +DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) +DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) +DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) +DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) +DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) +DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) +DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) +DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) +DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) +DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) +DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) +DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) +DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) +DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) +DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) +DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) +DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) +DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) +DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) +DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) +DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) +DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) +DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) +DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) +DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) +DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) +DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) +DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) +DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) +DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) +DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) +DECLARE_CSR(mvendorid, CSR_MVENDORID) +DECLARE_CSR(marchid, CSR_MARCHID) +DECLARE_CSR(mimpid, CSR_MIMPID) +DECLARE_CSR(mhartid, CSR_MHARTID) +DECLARE_CSR(cycleh, CSR_CYCLEH) +DECLARE_CSR(timeh, CSR_TIMEH) +DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) +DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) +DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) +DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) +DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) +DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) +DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) +DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) +DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) +DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) +DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) +DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) +DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) +DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) +DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) +DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) +DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) +DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) +DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) +DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) +DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) +DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) +DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) +DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) +DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) +DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) +DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) +DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) +DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) +DECLARE_CSR(mcycleh, CSR_MCYCLEH) +DECLARE_CSR(minstreth, CSR_MINSTRETH) +DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) +DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) +DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) +DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) +DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) +DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) +DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) +DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) +DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) +DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) +DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) +DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) +DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) +DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) +DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) +DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) +DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) +DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) +DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) +DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) +DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) +DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) +DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) +DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) +DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) +DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) +DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) +DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) +DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +#endif +#ifdef DECLARE_CAUSE +DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) +DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS) +DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) +DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) +DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) +DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS) +DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) +DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS) +DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) +DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) +DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) +DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) +DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT) +DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT) +DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT) +#endif diff --git a/VexRiscv/src/test/cpp/regression/fail.gtkw b/VexRiscv/src/test/cpp/regression/fail.gtkw new file mode 100644 index 0000000..d0fff46 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/fail.gtkw @@ -0,0 +1,29 @@ +[*] +[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI +[*] Thu Apr 25 14:41:35 2019 +[*] +[dumpfile] "/home/miaou/pro/VexRiscv/src/test/cpp/regression/C.SLLI.vcd" +[dumpfile_mtime] "Thu Apr 25 14:39:03 2019" +[dumpfile_size] 295925 +[savefile] "/home/miaou/pro/VexRiscv/src/test/cpp/regression/fail.gtkw" +[timestart] 0 +[size] 1920 1030 +[pos] -458 -215 +*-2.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[sst_width] 196 +[signals_width] 366 +[sst_expanded] 1 +[sst_vpaned_height] 299 +@28 +TOP.VexRiscv.lastStageIsValid +TOP.VexRiscv.lastStageIsFiring +@22 +TOP.VexRiscv.lastStageInstruction[31:0] +TOP.VexRiscv.lastStagePc[31:0] +TOP.VexRiscv.lastStageRegFileWrite_payload_address[4:0] +TOP.VexRiscv.lastStageRegFileWrite_payload_data[31:0] +@28 +TOP.VexRiscv.lastStageRegFileWrite_valid +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/icache.gtkw b/VexRiscv/src/test/cpp/regression/icache.gtkw new file mode 100644 index 0000000..5a7020f --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/icache.gtkw @@ -0,0 +1,67 @@ +[*] +[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI +[*] Wed Apr 11 18:53:23 2018 +[*] +[dumpfile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/rv32ui-p-lui.vcd" +[dumpfile_mtime] "Wed Apr 11 18:52:18 2018" +[dumpfile_size] 325049 +[savefile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/icache.gtkw" +[timestart] 1006 +[size] 1784 950 +[pos] -383 -155 +*-5.000000 1046 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 370 +[signals_width] 349 +[sst_expanded] 1 +[sst_vpaned_height] 271 +@28 +TOP.VexRiscv.decode_arbitration_isValid +TOP.VexRiscv.decode_arbitration_redoIt +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_haltIt +@22 +TOP.VexRiscv.iBus_cmd_payload_address[31:0] +@28 +TOP.VexRiscv.iBus_cmd_payload_size[2:0] +TOP.VexRiscv.iBus_cmd_ready +@29 +TOP.VexRiscv.iBus_cmd_valid +@22 +TOP.VexRiscv.iBus_rsp_payload_data[31:0] +@28 +TOP.VexRiscv.iBus_rsp_payload_error +TOP.VexRiscv.iBus_rsp_valid +[color] 2 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_isValid +[color] 2 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_haltIt +@22 +[color] 2 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_prefetch_pc[31:0] +@28 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_isValid +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_isStuck +@22 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_data[31:0] +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_fetch_pc[31:0] +@28 +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_isValid +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_cacheMiss +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_error +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_illegalAccess +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_isStuck +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_isUser +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_mmuMiss +@22 +[color] 6 +TOP.VexRiscv.IBusCachedPlugin_cache.io_cpu_decode_pc[31:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/main.cpp b/VexRiscv/src/test/cpp/regression/main.cpp new file mode 100644 index 0000000..3d61c9a --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/main.cpp @@ -0,0 +1,4514 @@ +#include "VVexRiscv.h" +#include "VVexRiscv_VexRiscv.h" +#ifdef REF +#include "VVexRiscv_RiscvCore.h" +#endif +#include "verilated.h" +#include "verilated_fst_c.h" +#include <stdio.h> +#include <iostream> +#include <stdlib.h> +#include <stdint.h> +#include <cstring> +#include <string.h> +#include <iostream> +#include <fstream> +#include <vector> +#include <mutex> +#include <iomanip> +#include <queue> +#include <time.h> +#include "encoding.h" + +#define VL_RANDOM_I_WIDTH(w) (VL_RANDOM_I() & (1l << w)-1l) + +using namespace std; + +struct timespec timer_get(){ + struct timespec start_time; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); + return start_time; +} + +class Memory{ +public: + uint8_t* mem[1 << 12]; + + Memory(){ + for(uint32_t i = 0;i < (1 << 12);i++) mem[i] = NULL; + } + ~Memory(){ + for(uint32_t i = 0;i < (1 << 12);i++) if(mem[i]) delete [] mem[i]; + } + + uint8_t* get(uint32_t address){ + if(mem[address >> 20] == NULL) { + uint8_t* ptr = new uint8_t[1024*1024]; + for(uint32_t i = 0;i < 1024*1024;i+=4) { + ptr[i + 0] = 0xFF; + ptr[i + 1] = 0xFF; + ptr[i + 2] = 0xFF; + ptr[i + 3] = 0xFF; + } + mem[address >> 20] = ptr; + } + return &mem[address >> 20][address & 0xFFFFF]; + } + + void read(uint32_t address,uint32_t length, uint8_t *data){ + for(int i = 0;i < length;i++){ + data[i] = (*this)[address + i]; + } + } + + void write(uint32_t address,uint32_t length, uint8_t *data){ + for(int i = 0;i < length;i++){ + (*this)[address + i] = data[i]; + } + } + + uint8_t& operator [](uint32_t address) { + return *get(address); + } + + /*T operator [](uint32_t address) const { + return get(address); + }*/ +}; + +//uint8_t memory[1024 * 1024]; + +uint32_t hti(char c) { + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return c - '0'; +} + +uint32_t hToI(char *c, uint32_t size) { + uint32_t value = 0; + for (uint32_t i = 0; i < size; i++) { + value += hti(c[i]) << ((size - i - 1) * 4); + } + return value; +} + +void loadHexImpl(string path,Memory* mem) { + FILE *fp = fopen(&path[0], "r"); + if(fp == 0){ + cout << path << " not found" << endl; + } + //Preload 0x0 <-> 0x80000000 jumps + ((uint32_t*)mem->get(0))[0] = 0x800000b7; + ((uint32_t*)mem->get(0))[1] = 0x000080e7; + ((uint32_t*)mem->get(0x80000000))[0] = 0x00000097; + + fseek(fp, 0, SEEK_END); + uint32_t size = ftell(fp); + fseek(fp, 0, SEEK_SET); + char* content = new char[size]; + fread(content, 1, size, fp); + fclose(fp); + + int offset = 0; + char* line = content; + while (1) { + if (line[0] == ':') { + uint32_t byteCount = hToI(line + 1, 2); + uint32_t nextAddr = hToI(line + 3, 4) + offset; + uint32_t key = hToI(line + 7, 2); +// printf("%d %d %d\n", byteCount, nextAddr,key); + switch (key) { + case 0: + for (uint32_t i = 0; i < byteCount; i++) { + *(mem->get(nextAddr + i)) = hToI(line + 9 + i * 2, 2); + //printf("%x %x %c%c\n",nextAddr + i,hToI(line + 9 + i*2,2),line[9 + i * 2],line[9 + i * 2+1]); + } + break; + case 2: +// cout << offset << endl; + offset = hToI(line + 9, 4) << 4; + break; + case 4: +// cout << offset << endl; + offset = hToI(line + 9, 4) << 16; + break; + default: +// cout << "??? " << key << endl; + break; + } + } + + while (*line != '\n' && size != 0) { + line++; + size--; + } + if (size <= 1) + break; + line++; + size--; + } + + delete [] content; +} + +void loadBinImpl(string path,Memory* mem, uint32_t offset) { + FILE *fp = fopen(&path[0], "r"); + if(fp == 0){ + cout << path << " not found" << endl; + } + + fseek(fp, 0, SEEK_END); + uint32_t size = ftell(fp); + fseek(fp, 0, SEEK_SET); + char* content = new char[size]; + fread(content, 1, size, fp); + fclose(fp); + + for(int byteId = 0; byteId < size;byteId++){ + *(mem->get(offset + byteId)) = content[byteId]; + } + + delete [] content; +} + + + +#define TEXTIFY(A) #A + +void breakMe(){ + int a = 0; +} +#define assertEq(x,ref) if(x != ref) {\ + printf("\n*** %s is %d but should be %d ***\n\n",TEXTIFY(x),x,ref);\ + breakMe();\ + throw std::exception();\ +} + +class success : public std::exception { }; + + + + +#define MVENDORID 0xF11 // MRO Vendor ID. +#define MARCHID 0xF12 // MRO Architecture ID. +#define MIMPID 0xF13 // MRO Implementation ID. +#define MHARTID 0xF14 // MRO Hardware thread ID.Machine Trap Setup +#define MSTATUS 0x300 // MRW Machine status register. +#define MISA 0x301 // MRW ISA and extensions +#define MEDELEG 0x302 // MRW Machine exception delegation register. +#define MIDELEG 0x303 // MRW Machine interrupt delegation register. +#define MIE 0x304 // MRW Machine interrupt-enable register. +#define MTVEC 0x305 // MRW Machine trap-handler base address. Machine Trap Handling +#define MSCRATCH 0x340 // MRW Scratch register for machine trap handlers. +#define MEPC 0x341 // MRW Machine exception program counter. +#define MCAUSE 0x342 // MRW Machine trap cause. +#define MBADADDR 0x343 // MRW Machine bad address. +#define MIP 0x344 // MRW Machine interrupt pending. +#define MBASE 0x380 // MRW Base register. +#define MBOUND 0x381 // MRW Bound register. +#define MIBASE 0x382 // MRW Instruction base register. +#define MIBOUND 0x383 // MRW Instruction bound register. +#define MDBASE 0x384 // MRW Data base register. +#define MDBOUND 0x385 // MRW Data bound register. +#define MCYCLE 0xB00 // MRW Machine cycle counter. +#define MINSTRET 0xB02 // MRW Machine instructions-retired counter. +#define MCYCLEH 0xB80 // MRW Upper 32 bits of mcycle, RV32I only. +#define MINSTRETH 0xB82 // MRW Upper 32 bits of minstret, RV32I only. + + +#define SSTATUS 0x100 +#define SIE 0x104 +#define STVEC 0x105 +#define SCOUNTEREN 0x106 +#define SSCRATCH 0x140 +#define SEPC 0x141 +#define SCAUSE 0x142 +#define STVAL 0x143 +#define SIP 0x144 +#define SATP 0x180 + +#define UTIME 0xC01 // rdtime +#define UTIMEH 0xC81 + +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_SPP 0x00000100 + +#ifdef SUPERVISOR +#define MSTATUS_READ_MASK 0xFFFFFFFF +#else +#define MSTATUS_READ_MASK 0x7888 +#endif + +#ifdef RVF +#define STATUS_FS_MASK 0x6000 +#else +#define STATUS_FS_MASK 0x0000 +#endif + +#define FFLAGS 0x1 +#define FRM 0x2 +#define FCSR 0x3 + +#define u32 uint32_t +#define u64 uint64_t + +class FpuRsp{ +public: + u32 flags; + u64 value; +}; + +class FpuCommit{ +public: + u64 value; +}; + +class FpuCompletion{ +public: + u32 flags; +}; + + +bool fpuCommitLut[32] = {true,true,true,true,true,true,false,false,true,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,true,false}; +bool fpuRspLut[32] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,true,false,false,false,true,false,false,false}; +bool fpuRs1Lut[32] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,true,false}; +class RiscvGolden { +public: + int32_t pc, lastPc; + uint32_t lastInstruction; + int32_t regs[32]; + uint64_t stepCounter; + + uint32_t mscratch, sscratch; + uint32_t misa; + uint32_t privilege; + + uint32_t medeleg; + uint32_t mideleg; + + queue<FpuRsp> fpuRsp; + queue<FpuCommit> fpuCommit; + queue<FpuCompletion> fpuCompletion; + + union status { + uint32_t raw; + struct { + uint32_t _1a : 1; + uint32_t sie : 1; + uint32_t _1b : 1; + uint32_t mie : 1; + uint32_t _2a : 1; + uint32_t spie : 1; + uint32_t _2b : 1; + uint32_t mpie : 1; + uint32_t spp : 1; + uint32_t _3 : 2; + uint32_t mpp : 2; + uint32_t fs : 2; + uint32_t _4 : 2; + uint32_t mprv : 1; + uint32_t sum : 1; + uint32_t mxr : 1; + }; + }__attribute__((packed)) status; + + + + uint32_t ipInput; + uint32_t ipSoft; + union IpOr { + uint32_t raw; + struct { + uint32_t _1a : 1; + uint32_t ssip : 1; + uint32_t _1b : 1; + uint32_t msip : 1; + uint32_t _2a : 1; + uint32_t stip : 1; + uint32_t _2b : 1; + uint32_t mtip : 1; + uint32_t _3a : 1; + uint32_t seip : 1; + uint32_t _3b : 1; + uint32_t meip : 1; + }; + }__attribute__((packed)); + + IpOr getIp(){ + IpOr ret; + ret.raw = ipSoft | ipInput; + return ret; + } + + union mie { + uint32_t raw; + struct { + uint32_t _1a : 1; + uint32_t ssie : 1; + uint32_t _1b : 1; + uint32_t msie : 1; + uint32_t _2a : 1; + uint32_t stie : 1; + uint32_t _2b : 1; + uint32_t mtie : 1; + uint32_t _3a : 1; + uint32_t seie : 1; + uint32_t _3b : 1; + uint32_t meie : 1; + }; + }__attribute__((packed)) ie; + + union Xtvec { + uint32_t raw; + struct __attribute__((packed)) { + uint32_t _1 : 2; + uint32_t base : 30; + }; + }; + + Xtvec mtvec, stvec; + + + + union mcause { + uint32_t raw; + struct __attribute__((packed)) { + uint32_t exceptionCode : 31; + uint32_t interrupt : 1; + }; + } mcause; + + + union scause { + uint32_t raw; + struct __attribute__((packed)){ + uint32_t exceptionCode : 31; + uint32_t interrupt : 1; + }; + } scause; + + union satp { + uint32_t raw; + struct __attribute__((packed)){ + uint32_t ppn : 22; + uint32_t _x : 9; + uint32_t mode : 1; + }; + }satp; + + union Tlb { + uint32_t raw; + struct __attribute__((packed)){ + uint32_t v : 1; + uint32_t r : 1; + uint32_t w : 1; + uint32_t x : 1; + uint32_t u : 1; + uint32_t _dummy : 5; + uint32_t ppn : 22; + }; + struct __attribute__((packed)){ + uint32_t _dummyX : 10; + uint32_t ppn0 : 10; + uint32_t ppn1 : 12; + }; + }; + + union fcsr { + uint32_t raw; + struct __attribute__((packed)){ + uint32_t flags : 5; + uint32_t frm : 3; + }; + }fcsr; + + + bool lrscReserved; + uint32_t lrscReservedAddress; + u32 fpuCompletionTockens; + u32 dutRfWriteValue; + + RiscvGolden() { + pc = 0x80000000; + regs[0] = 0; + for (int i = 0; i < 32; i++) + regs[i] = 0; + + ie.raw = 0; + mtvec.raw = 0x80000020; + mcause.raw = 0; + mbadaddr = 0; + mepc = 0; + misa = 0x40041101; //TODO + status.raw = 0; + status.mpp = 3; + status.spp = 1; + #ifdef RVF + status.fs = 1; + misa |= 1 << 5; + #endif + #ifdef RVD + misa |= 1 << 3; + #endif + fcsr.flags = 0; + fcsr.frm = 0; + privilege = 3; + medeleg = 0; + mideleg = 0; + satp.mode = 0; + ipSoft = 0; + ipInput = 0; + stepCounter = 0; + sbadaddr = 42; + lrscReserved = false; + fpuCompletionTockens = 0; + } + + virtual void rfWrite(int32_t address, int32_t data) { + if (address != 0) + regs[address] = data; + } + + virtual void pcWrite(int32_t target) { + if(isPcAligned(target)){ + lastPc = pc; + pc = target; + } else { + trap(0, 0, target); + } + } + uint32_t mbadaddr, sbadaddr; + uint32_t mepc, sepc; + + virtual bool iRead(int32_t address, uint32_t *data) = 0; + virtual bool dRead(int32_t address, int32_t size, uint8_t *data) = 0; + virtual void dWrite(int32_t address, int32_t size, uint8_t *data) = 0; + + enum AccessKind {READ,WRITE,EXECUTE,READ_WRITE}; + virtual bool isMmuRegion(uint32_t v) = 0; + bool v2p(uint32_t v, uint32_t *p, AccessKind kind){ + uint32_t effectivePrivilege = status.mprv && kind != EXECUTE ? status.mpp : privilege; + if(effectivePrivilege == 3 || satp.mode == 0 || !isMmuRegion(v)){ + *p = v; + } else { + Tlb tlb; + dRead((satp.ppn << 12) | ((v >> 22) << 2), 4, (uint8_t*)&tlb.raw); + if(!tlb.v) return true; + bool superPage = true; + if(!tlb.x && !tlb.r && !tlb.w){ + dRead((tlb.ppn << 12) | (((v >> 12) & 0x3FF) << 2), 4, (uint8_t*)&tlb.raw); + if(!tlb.v) return true; + superPage = false; + } + if(!tlb.u && effectivePrivilege == 0) return true; + if( tlb.u && effectivePrivilege == 1 && !status.sum) return true; + if(superPage && tlb.ppn0 != 0) return true; + if(kind == READ || kind == READ_WRITE) if(!tlb.r && !(status.mxr && tlb.x)) return true; + if(kind == WRITE || kind == READ_WRITE) if(!tlb.w) return true; + if(kind == EXECUTE) if(!tlb.x) return true; + + *p = (tlb.ppn1 << 22) | (superPage ? v & 0x3FF000 : tlb.ppn0 << 12) | (v & 0xFFF); + } + return false; + } + + void trap(bool interrupt,int32_t cause) { + trap(interrupt, cause, false, 0); + } + void trap(bool interrupt,int32_t cause, uint32_t value) { + trap(interrupt, cause, true, value); + } + void trap(bool interrupt,int32_t cause, bool valueWrite, uint32_t value) { +#ifdef FLOW_INFO +// cout << "TRAP " << (interrupt ? "interrupt" : "exception") << " cause=" << cause << " PC=0x" << hex << pc << " val=0x" << hex << value << dec << endl; +// if(cause == 9){ +// cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl; +// } +#endif + //Check leguality of the interrupt + if(interrupt) { + bool hit = false; + for(int i = 0;i < 5;i++){ + if(pendingInterrupts[i] == 1 << cause){ + hit = true; + break; + } + } + if(!hit){ + cout << "DUT had trigger an interrupts which wasn't by the REF" << endl; + fail(); + } + } + + uint32_t deleg = interrupt ? mideleg : medeleg; + uint32_t targetPrivilege = 3; + if(deleg & (1 << cause)) targetPrivilege = 1; + targetPrivilege = max(targetPrivilege, privilege); + Xtvec xtvec = targetPrivilege == 3 ? mtvec : stvec; + + + + switch(targetPrivilege){ + case 3: + if(valueWrite) mbadaddr = value; + mcause.interrupt = interrupt; + mcause.exceptionCode = cause; + status.mpie = status.mie; + status.mie = false; + status.mpp = privilege; + mepc = pc; + break; + case 1: + if(valueWrite) sbadaddr = value; + scause.interrupt = interrupt; + scause.exceptionCode = cause; + status.spie = status.sie; + status.sie = false; + status.spp = privilege; + sepc = pc; + break; + } + + privilege = targetPrivilege; + pcWrite(xtvec.base << 2); + if(interrupt) livenessInterrupt = 0; + +// if(!interrupt) step(); //As VexRiscv instruction which trap do not reach writeback stage fire + } + + uint32_t currentInstruction; + void ilegalInstruction(){ + trap(0, 2, currentInstruction); + } + + virtual void fail() { + } + + + + virtual bool csrRead(int32_t csr, uint32_t *value){ + if(((csr >> 8) & 0x3) > privilege) return true; + switch(csr){ + case MSTATUS: *value = (status.raw | (((status.raw & 0x6000) == 0x6000) ? 0x80000000 : 0)) & MSTATUS_READ_MASK; break; + case MIP: *value = getIp().raw; break; + case MIE: *value = ie.raw; break; + case MTVEC: *value = mtvec.raw; break; + case MCAUSE: *value = mcause.raw; break; + case MBADADDR: *value = mbadaddr; break; + case MEPC: *value = mepc; break; + case MSCRATCH: *value = mscratch; break; + case MISA: *value = misa; break; + case MEDELEG: *value = medeleg; break; + case MIDELEG: *value = mideleg; break; + case MHARTID: *value = 0; break; + + case SSTATUS: *value = (status.raw | (((status.raw & 0x6000) == 0x6000) ? 0x80000000 : 0)) & (0x800C0133 | STATUS_FS_MASK); break; + case SIP: *value = getIp().raw & 0x333; break; + case SIE: *value = ie.raw & 0x333; break; + case STVEC: *value = stvec.raw; break; + case SCAUSE: *value = scause.raw; break; + case STVAL: *value = sbadaddr; break; + case SEPC: *value = sepc; break; + case SSCRATCH: *value = sscratch; break; + case SATP: *value = satp.raw; break; + + #ifdef RVF + case FCSR: *value = fcsr.raw; break; + case FRM: *value = fcsr.frm; break; + case FFLAGS: *value = fcsr.flags; break; + #endif + + #ifdef UTIME_INPUT + case UTIME: *value = dutRfWriteValue; break; + case UTIMEH: *value = dutRfWriteValue; break; + #endif + + default: return true; break; + } + return false; + } + + virtual uint32_t csrReadToWriteOverride(int32_t csr, uint32_t value){ + if(((csr >> 8) & 0x3) > privilege) return true; + switch(csr){ + case MIP: return ipSoft; break; + case SIP: return ipSoft & 0x333; break; + }; + return value; + } + + #define maskedWrite(dst, src, mask) dst=((dst) & ~(mask))|((src) & (mask)); + + virtual bool csrWrite(int32_t csr, uint32_t value){ + if(((csr >> 8) & 0x3) > privilege) return true; + switch(csr){ + case MSTATUS: status.raw = value & 0x7FFFFFFF; break; + case MIP: ipSoft = value; break; + case MIE: ie.raw = value; break; + case MTVEC: mtvec.raw = value; break; + case MCAUSE: mcause.raw = value; break; + case MBADADDR: mbadaddr = value; break; + case MEPC: mepc = value; break; + case MSCRATCH: mscratch = value; break; + case MISA: misa = value; break; + case MEDELEG: medeleg = value & (~0x8); break; + case MIDELEG: mideleg = value; break; + + case SSTATUS: maskedWrite(status.raw, value, 0xC0133 | STATUS_FS_MASK); break; + case SIP: maskedWrite(ipSoft, value,0x333); break; + case SIE: maskedWrite(ie.raw, value,0x333); break; + case STVEC: stvec.raw = value; break; + case SCAUSE: scause.raw = value; break; + case STVAL: sbadaddr = value; break; + case SEPC: sepc = value; break; + case SSCRATCH: sscratch = value; break; + case SATP: satp.raw = value; break; + + #ifdef RVF + case FCSR: fcsr.raw = value & 0x7F; break; + case FRM: fcsr.frm = value; break; + case FFLAGS: fcsr.flags = value; break; + #endif + + default: ilegalInstruction(); return true; break; + } + return false; + } + + + int livenessStep = 0; + int livenessInterrupt = 0; + uint32_t pendingInterruptsPtr = 0; + uint32_t pendingInterrupts[5] = {0,0,0,0,0}; + virtual void liveness(bool inWfi){ + uint32_t pendingInterrupt = getPendingInterrupt(); + pendingInterrupts[pendingInterruptsPtr++] = getPendingInterrupt(); + if(pendingInterruptsPtr >= 5) pendingInterruptsPtr = 0; + if(pendingInterrupt) livenessInterrupt++; else livenessInterrupt = 0; + if(!inWfi) livenessStep++; else livenessStep = 0; + + if(livenessStep > 10000){ + cout << "Liveness step failure" << endl; + fail(); + } + + if(livenessInterrupt > 1000){ + cout << "Liveness interrupt failure" << endl; + fail(); + } + } + + + uint32_t getPendingInterrupt(){ + uint32_t mEnabled = status.mie && privilege == 3 || privilege < 3; + uint32_t sEnabled = status.sie && privilege == 1 || privilege < 1; + + uint32_t masked = getIp().raw & ~mideleg & -mEnabled & ie.raw; + if (masked == 0) + masked = getIp().raw & mideleg & -sEnabled & ie.raw & 0x333; + + if (masked) { + if (masked & MIP_MEIP) + masked &= MIP_MEIP; + else if (masked & MIP_MSIP) + masked &= MIP_MSIP; + else if (masked & MIP_MTIP) + masked &= MIP_MTIP; + else if (masked & MIP_SEIP) + masked &= MIP_SEIP; + else if (masked & MIP_SSIP) + masked &= MIP_SSIP; + else if (masked & MIP_STIP) + masked &= MIP_STIP; + else + fail(); + } + + return masked; + } + + + bool isPcAligned(uint32_t pc){ +#ifdef COMPRESSED + return (pc & 1) == 0; +#else + return (pc & 3) == 0; +#endif + } + + + + virtual void step() { + stepCounter++; + livenessStep = 0; + + while(fpuCompletionTockens != 0 && !fpuCompletion.empty()){ + FpuCompletion completion = fpuCompletion.front(); fpuCompletion.pop(); + fcsr.flags |= completion.flags; + fpuCompletionTockens -= 1; + } + + + #define rd32 ((i >> 7) & 0x1F) + #define iBits(lo, len) ((i >> lo) & ((1 << len)-1)) + #define iBitsSigned(lo, len) int32_t(i) << (32-lo-len) >> (32-len) + #define iSign() iBitsSigned(31, 1) + #define i32_rs1 regs[(i >> 15) & 0x1F] + #define i32_rs2 regs[(i >> 20) & 0x1F] + #define i32_i_imm (int32_t(i) >> 20) + #define i32_s_imm (iBits(7, 5) + (iBitsSigned(25, 7) << 5)) + #define i32_shamt ((i >> 20) & 0x1F) + #define i32_sb_imm ((iBits(8, 4) << 1) + (iBits(25,6) << 5) + (iBits(7,1) << 11) + (iSign() << 12)) + #define i32_csr iBits(20, 12) + #define i32_func3 iBits(12, 3) + #define i32_func7 iBits(25, 7) + #define i16_addi4spn_imm ((iBits(6, 1) << 2) + (iBits(5, 1) << 3) + (iBits(11, 2) << 4) + (iBits(7, 4) << 6)) + #define i16_lw_imm ((iBits(6, 1) << 2) + (iBits(10, 3) << 3) + (iBits(5, 1) << 6)) + #define i16_addr2 (iBits(2,3) + 8) + #define i16_addr1 (iBits(7,3) + 8) + #define i16_rf1 regs[i16_addr1] + #define i16_rf2 regs[i16_addr2] + #define rf_sp regs[2] + #define i16_imm (iBits(2, 5) + (iBitsSigned(12, 1) << 5)) + #define i16_j_imm ((iBits(3, 3) << 1) + (iBits(11, 1) << 4) + (iBits(2, 1) << 5) + (iBits(7, 1) << 6) + (iBits(6, 1) << 7) + (iBits(9, 2) << 8) + (iBits(8, 1) << 10) + (iBitsSigned(12, 1) << 11)) + #define i16_addi16sp_imm ((iBits(6, 1) << 4) + (iBits(2, 1) << 5) + (iBits(5, 1) << 6) + (iBits(3, 2) << 7) + (iBitsSigned(12, 1) << 9)) + #define i16_zimm (iBits(2, 5)) + #define i16_b_imm ((iBits(3, 2) << 1) + (iBits(10, 2) << 3) + (iBits(2, 1) << 5) + (iBits(5, 2) << 6) + (iBitsSigned(12, 1) << 8)) + #define i16_lwsp_imm ((iBits(4, 3) << 2) + (iBits(12, 1) << 5) + (iBits(2, 2) << 6)) + #define i16_swsp_imm ((iBits(9, 4) << 2) + (iBits(7, 2) << 6)) + uint32_t i; + uint32_t u32Buf; + uint32_t pAddr; + if (pc & 2) { + if(v2p(pc - 2, &pAddr, EXECUTE)){ trap(0, 12, pc - 2); return; } + if(iRead(pAddr, &i)){ + trap(0, 1, 0); + return; + } + i >>= 16; + if ((i & 3) == 3) { + uint32_t u32Buf; + if(v2p(pc + 2, &pAddr, EXECUTE)){ trap(0, 12, pc + 2); return; } + if(iRead(pAddr, &u32Buf)){ + trap(0, 1, 0); + return; + } + i |= u32Buf << 16; + } + } else { + if(v2p(pc, &pAddr, EXECUTE)){ trap(0, 12, pc); return; } + if(iRead(pAddr, &i)){ + trap(0, 1, 0); + return; + } + } + lastInstruction = i; + currentInstruction = i; + if ((i & 0x3) == 0x3) { + //32 bit + switch (i & 0x7F) { + #ifdef RVF + case 0x43:// RVFD + case 0x47: + case 0x4B: + case 0x4F: + case 0x53: { + u32 format = iBits(25,2); + u32 opcode = iBits(27,5); + bool withCommit = fpuCommitLut[opcode]; + bool withRsp = fpuRspLut[opcode]; + bool withRs1 = fpuRs1Lut[opcode]; + if((i & 0x7F) != 0x53) { // FMADD + withCommit = true; + withRsp = false; + } + #ifdef RVD + if(format > 1) ilegalInstruction(); + #else + if(format > 0) ilegalInstruction(); + #endif + + if(withCommit){ + FpuCommit commit = fpuCommit.front(); fpuCommit.pop(); + fpuCompletionTockens += 1; +// cout << "withRs1 " << withRs1 << " " << opcode << endl; + if(withRs1 && memcmp(&i32_rs1, &commit.value, 4)){ + cout << "FPU commit missmatch DUT=" << hex << commit.value << " REF=" << i32_rs1 << dec << endl; + fail(); + return; + } + } + if(withRsp){ + auto rsp = fpuRsp.front(); fpuRsp.pop(); + fcsr.flags |= rsp.flags; + rfWrite(rd32, (u32)rsp.value); + } + status.fs = 3; + pcWrite(pc + 4); + } break; + case 0x07: { //Fpu load + uint32_t size = 1 << ((i >> 12) & 0x3); + if(size < 4) ilegalInstruction(); + #ifdef RVD + if(size > 8) ilegalInstruction(); + #else + if(format > 4) ilegalInstruction(); + #endif + auto commit = fpuCommit.front(); fpuCommit.pop(); + fpuCompletionTockens += 1; + + + uint64_t data = 0; + uint32_t address = i32_rs1 + i32_i_imm; + if(address & (size-1)){ + trap(0, 4, address); + } else { + if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } + if(dRead(pAddr, size, (uint8_t*)&data)){ + trap(0, 5, address); + } else { + if(memcmp(&data, &commit.value, size)){ + cout << "FPU load missmatch DUT=" << hex << commit.value << " REF=" << data << dec << endl; + fail(); + } else { + status.fs = 3; + pcWrite(pc + 4); + } + } + } + } break; + case 0x27: { //Fpu store + uint32_t size = 1 << ((i >> 12) & 0x3); + if(size < 4) ilegalInstruction(); + #ifdef RVD + if(size > 8) ilegalInstruction(); + #else + if(format > 4) ilegalInstruction(); + #endif + + auto rsp = fpuRsp.front(); fpuRsp.pop(); + fcsr.flags |= rsp.flags; + uint32_t address = i32_rs1 + i32_s_imm; + if(address & (size-1)){ + trap(0, 6, address); + } else { + if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; } + dWrite(pAddr, size, (uint8_t*) &rsp.value); + status.fs = 3; + pcWrite(pc + 4); + lrscReserved = false; + } + } break; + #endif + case 0x37:rfWrite(rd32, i & 0xFFFFF000);pcWrite(pc + 4);break; // LUI + case 0x17:rfWrite(rd32, (i & 0xFFFFF000) + pc);pcWrite(pc + 4);break; //AUIPC + case 0x6F:rfWrite(rd32, pc + 4);pcWrite(pc + (iBits(21, 10) << 1) + (iBits(20, 1) << 11) + (iBits(12, 8) << 12) + (iSign() << 20));break; //JAL + case 0x67:{ + uint32_t target = (i32_rs1 + i32_i_imm) & ~1; + if(isPcAligned(target)) rfWrite(rd32, pc + 4); + pcWrite(target); + } break; //JALR + case 0x63: + switch ((i >> 12) & 0x7) { + case 0x0:if (i32_rs1 == i32_rs2)pcWrite(pc + i32_sb_imm);else pcWrite(pc + 4);break; + case 0x1:if (i32_rs1 != i32_rs2)pcWrite(pc + i32_sb_imm);else pcWrite(pc + 4);break; + case 0x4:if (i32_rs1 < i32_rs2)pcWrite(pc + i32_sb_imm); else pcWrite(pc + 4);break; + case 0x5:if (i32_rs1 >= i32_rs2)pcWrite(pc + i32_sb_imm);else pcWrite(pc + 4);break; + case 0x6:if (uint32_t(i32_rs1) < uint32_t(i32_rs2)) pcWrite(pc + i32_sb_imm); else pcWrite(pc + 4);break; + case 0x7:if (uint32_t(i32_rs1) >= uint32_t(i32_rs2))pcWrite(pc + i32_sb_imm); else pcWrite(pc + 4);break; + } + break; + case 0x03:{ //LOADS + uint32_t data; + uint32_t address = i32_rs1 + i32_i_imm; + uint32_t size = 1 << ((i >> 12) & 0x3); + if(address & (size-1)){ + trap(0, 4, address); + } else { + if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } + if(dRead(pAddr, size, (uint8_t*)&data)){ + trap(0, 5, address); + } else { + switch ((i >> 12) & 0x7) { + case 0x0:rfWrite(rd32, int8_t(data));pcWrite(pc + 4);break; + case 0x1:rfWrite(rd32, int16_t(data));pcWrite(pc + 4);break; + case 0x2:rfWrite(rd32, int32_t(data));pcWrite(pc + 4);break; + case 0x4:rfWrite(rd32, uint8_t(data));pcWrite(pc + 4);break; + case 0x5:rfWrite(rd32, uint16_t(data));pcWrite(pc + 4);break; + } + } + } + }break; + case 0x23: { //STORE + uint32_t address = i32_rs1 + i32_s_imm; + uint32_t size = 1 << ((i >> 12) & 0x3); + if(address & (size-1)){ + trap(0, 6, address); + } else { + if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; } + dWrite(pAddr, size, (uint8_t*)&i32_rs2); + pcWrite(pc + 4); + lrscReserved = false; + } + }break; + case 0x13: //ALUi + switch ((i >> 12) & 0x7) { + case 0x0:rfWrite(rd32, i32_rs1 + i32_i_imm);pcWrite(pc + 4);break; + case 0x1: + switch ((i >> 25) & 0x7F) { + case 0x00:rfWrite(rd32, i32_rs1 << i32_shamt);pcWrite(pc + 4);break; + } + break; + case 0x2:rfWrite(rd32, i32_rs1 < i32_i_imm);pcWrite(pc + 4);break; + case 0x3:rfWrite(rd32, uint32_t(i32_rs1) < uint32_t(i32_i_imm));pcWrite(pc + 4);break; + case 0x4:rfWrite(rd32, i32_rs1 ^ i32_i_imm);pcWrite(pc + 4);break; + case 0x5: + switch ((i >> 25) & 0x7F) { + case 0x00:rfWrite(rd32, uint32_t(i32_rs1) >> i32_shamt);pcWrite(pc + 4);break; + case 0x20:rfWrite(rd32, i32_rs1 >> i32_shamt);pcWrite(pc + 4);break; + } + break; + case 0x6:rfWrite(rd32, i32_rs1 | i32_i_imm);pcWrite(pc + 4);break; + case 0x7: rfWrite(rd32, i32_rs1 & i32_i_imm);pcWrite(pc + 4);break; + } + break; + case 0x33: //ALU + if (((i >> 25) & 0x7F) == 0x01) { + switch ((i >> 12) & 0x7) { + case 0x0:rfWrite(rd32, int32_t(i32_rs1) * int32_t(i32_rs2));pcWrite(pc + 4);break; + case 0x1:rfWrite(rd32,(int64_t(i32_rs1) * int64_t(i32_rs2)) >> 32);pcWrite(pc + 4);break; + case 0x2:rfWrite(rd32,(int64_t(i32_rs1) * uint64_t(uint32_t(i32_rs2)))>> 32);pcWrite(pc + 4);break; + case 0x3:rfWrite(rd32,(uint64_t(uint32_t(i32_rs1)) * uint64_t(uint32_t(i32_rs2))) >> 32);pcWrite(pc + 4);break; + case 0x4:rfWrite(rd32,i32_rs2 == 0 ? -1 : int64_t(i32_rs1) / int64_t(i32_rs2));pcWrite(pc + 4);break; + case 0x5:rfWrite(rd32,i32_rs2 == 0 ? -1 : uint32_t(i32_rs1) / uint32_t(i32_rs2));pcWrite(pc + 4);break; + case 0x6:rfWrite(rd32,i32_rs2 == 0 ? i32_rs1 : int64_t(i32_rs1)% int64_t(i32_rs2));pcWrite(pc + 4);break; + case 0x7:rfWrite(rd32,i32_rs2 == 0 ? i32_rs1 : uint32_t(i32_rs1) % uint32_t(i32_rs2));pcWrite(pc + 4);break; + } + } else { + switch ((i >> 12) & 0x7) { + case 0x0: + switch ((i >> 25) & 0x7F) { + case 0x00:rfWrite(rd32, i32_rs1 + i32_rs2);pcWrite(pc + 4);break; + case 0x20:rfWrite(rd32, i32_rs1 - i32_rs2);pcWrite(pc + 4);break; + } + break; + case 0x1:rfWrite(rd32, i32_rs1 << (i32_rs2 & 0x1F));pcWrite(pc + 4);break; + case 0x2:rfWrite(rd32, i32_rs1 < i32_rs2);pcWrite(pc + 4);break; + case 0x3:rfWrite(rd32, uint32_t(i32_rs1) < uint32_t(i32_rs2));pcWrite(pc + 4);break; + case 0x4:rfWrite(rd32, i32_rs1 ^ i32_rs2);pcWrite(pc + 4);break; + case 0x5: + switch ((i >> 25) & 0x7F) { + case 0x00:rfWrite(rd32, uint32_t(i32_rs1) >> (i32_rs2 & 0x1F));pcWrite(pc + 4);break; + case 0x20:rfWrite(rd32, i32_rs1 >> (i32_rs2 & 0x1F));pcWrite(pc + 4);break; + } + break; + case 0x6:rfWrite(rd32, i32_rs1 | i32_rs2);pcWrite(pc + 4);break; + case 0x7:rfWrite(rd32, i32_rs1 & i32_rs2); pcWrite(pc + 4);break; + } + } + break; + case 0x73:{ + if(i32_func3 == 0){ + switch(i){ + case 0x30200073:{ //MRET + if(privilege < 3){ ilegalInstruction(); return;} + privilege = status.mpp; + status.mie = status.mpie; + status.mpie = 1; + status.mpp = 0; + pcWrite(mepc); + }break; + case 0x10200073:{ //SRET + if(privilege < 1){ ilegalInstruction(); return;} + privilege = status.spp; + status.sie = status.spie; + status.spie = 1; + status.spp = 0; + pcWrite(sepc); + }break; + case 0x00000073:{ //ECALL + trap(0, 8+privilege, 0x00000073); //To follow the VexRiscv area saving implementation + }break; + case 0x10500073:{ //WFI + pcWrite(pc + 4); + }break; + default: + if((i & 0xFE007FFF) == 0x12000073){ //SFENCE.VMA + pcWrite(pc + 4); + }else { + ilegalInstruction(); + } + break; + } + } else { + //CSR + uint32_t input = (i & 0x4000) ? ((i >> 15) & 0x1F) : i32_rs1; + uint32_t clear, set; + bool write; + switch ((i >> 12) & 0x3) { + case 1: clear = ~0; set = input; write = true; break; + case 2: clear = 0; set = input; write = ((i >> 15) & 0x1F) != 0; break; + case 3: clear = input; set = 0; write = ((i >> 15) & 0x1F) != 0; break; + } + uint32_t csrAddress = i32_csr; + uint32_t old; + if(csrRead(i32_csr, &old)) { ilegalInstruction();return; } + if(write) if(csrWrite(i32_csr, (csrReadToWriteOverride(i32_csr, old) & ~clear) | set)) { ilegalInstruction();return; } + rfWrite(rd32, old); + pcWrite(pc + 4); + } + break; + } + case 0x2F: // Atomic stuff + switch(i32_func3){ + case 0x2: + switch(iBits(27,5)){ + case 0x2:{ //LR + uint32_t data; + uint32_t address = i32_rs1; + if(address & 3){ + trap(0, 4, address); + } else { + if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } + if(dRead(pAddr, 4, (uint8_t*)&data)){ + trap(0, 5, address); + } else { + lrscReserved = true; + lrscReservedAddress = pAddr; + rfWrite(rd32, data); + pcWrite(pc + 4); + } + } + } break; + case 0x3:{ //SC + uint32_t address = i32_rs1; + if(address & 3){ + trap(0, 6, address); + } else { + if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; } + #ifdef DBUS_EXCLUSIVE + bool hit = lrscReserved && lrscReservedAddress == pAddr; + #else + bool hit = lrscReserved; + #endif + if(hit){ + dWrite(pAddr, 4, (uint8_t*)&i32_rs2); + } + lrscReserved = false; + rfWrite(rd32, !hit); + pcWrite(pc + 4); + } + } break; + default: { + #ifndef AMO + ilegalInstruction(); + #else + uint32_t sel = (i >> 27) & 0x1F; + uint32_t addr = i32_rs1; + int32_t src = i32_rs2; + int32_t readValue; + + lrscReserved = false; + + + uint32_t pAddr; + if(v2p(addr, &pAddr, READ_WRITE)){ trap(0, 15, addr); return; } + if(dRead(pAddr, 4, (uint8_t*)&readValue)){ + trap(0, 15, addr); return; + return; + } + int writeValue; + switch(sel){ + case 0x0: writeValue = src + readValue; break; + case 0x1: writeValue = src; break; + case 0x4: writeValue = src ^ readValue; break; + case 0xC: writeValue = src & readValue; break; + case 0x8: writeValue = src | readValue; break; + case 0x10: writeValue = min(src, readValue); break; + case 0x14: writeValue = max(src, readValue); break; + case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break; + case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break; + default: ilegalInstruction(); return; break; + } + dWrite(pAddr, 4, (uint8_t*)&writeValue); + rfWrite(rd32, readValue); + pcWrite(pc + 4); + #endif + } break; + } + break; + default: ilegalInstruction(); break; + } + break; + case 0x0f: + if(i == 0x100F || (i & 0xF00FFFFF) == 0x000F){ // FENCE FENCE.I + pcWrite(pc + 4); + } else{ + ilegalInstruction(); + } + break; + default: ilegalInstruction(); break; + } + } else { + #ifndef COMPRESSED + cout << "ERROR : RiscvGolden got a RVC instruction while the CPU isn't RVC ready" << endl; + ilegalInstruction(); return; + #endif + switch((iBits(0, 2) << 3) + iBits(13, 3)){ + case 0: rfWrite(i16_addr2, rf_sp + i16_addi4spn_imm); pcWrite(pc + 2); break; + case 2: { + uint32_t data; + uint32_t address = i16_rf1 + i16_lw_imm; + if(address & 0x3){ + trap(0, 4, address); + } else { + if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } + if(dRead(pAddr, 4, (uint8_t*)&data)) { + trap(0, 5, address); + } else { + rfWrite(i16_addr2, data); pcWrite(pc + 2); + } + } + } break; + case 6: { + uint32_t address = i16_rf1 + i16_lw_imm; + if(address & 0x3){ + trap(0, 6, address); + } else { + if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; } + dWrite(pAddr, 4, (uint8_t*)&i16_rf2); + pcWrite(pc + 2); + lrscReserved = false; + } + }break; + case 8: rfWrite(rd32, regs[rd32] + i16_imm); pcWrite(pc + 2); break; + case 9: rfWrite(1, pc + 2);pcWrite(pc + i16_j_imm); break; + case 10: rfWrite(rd32, i16_imm);pcWrite(pc + 2); break; + case 11: + if(rd32 == 2) { rfWrite(2, rf_sp + i16_addi16sp_imm);pcWrite(pc + 2); } + else { rfWrite(rd32, i16_imm << 12);pcWrite(pc + 2); } break; + case 12: + switch(iBits(10,2)){ + case 0: rfWrite(i16_addr1, uint32_t(i16_rf1) >> i16_zimm); pcWrite(pc + 2);break; + case 1: rfWrite(i16_addr1, i16_rf1 >> i16_zimm); pcWrite(pc + 2);break; + case 2: rfWrite(i16_addr1, i16_rf1 & i16_imm); pcWrite(pc + 2);break; + case 3: + switch(iBits(5,2)){ + case 0: rfWrite(i16_addr1, i16_rf1 - i16_rf2); pcWrite(pc + 2);break; + case 1: rfWrite(i16_addr1, i16_rf1 ^ i16_rf2); pcWrite(pc + 2);break; + case 2: rfWrite(i16_addr1, i16_rf1 | i16_rf2); pcWrite(pc + 2);break; + case 3: rfWrite(i16_addr1, i16_rf1 & i16_rf2); pcWrite(pc + 2);break; + } + break; + } + break; + case 13: pcWrite(pc + i16_j_imm); break; + case 14: pcWrite(i16_rf1 == 0 ? pc + i16_b_imm : pc + 2); break; + case 15: pcWrite(i16_rf1 != 0 ? pc + i16_b_imm : pc + 2); break; + case 16: rfWrite(rd32, regs[rd32] << i16_zimm); pcWrite(pc + 2); break; + case 18:{ + uint32_t data; + uint32_t address = rf_sp + i16_lwsp_imm; + if(address & 0x3){ + trap(0, 4, address); + } else { + if(v2p(address, &pAddr, READ)){ trap(0, 13, address); return; } + if(dRead(pAddr, 4,(uint8_t*) &data)){ + trap(0, 5, address); + } else { + rfWrite(rd32, data); pcWrite(pc + 2); + } + } + }break; + case 20: + if(i & 0x1000){ + if(iBits(2,10) == 0){ + + } else if(iBits(2,5) == 0){ + rfWrite(1, pc + 2); pcWrite(regs[rd32] & ~1); + } else { + rfWrite(rd32, regs[rd32] + regs[iBits(2,5)]); pcWrite(pc + 2); + } + } else { + if(iBits(2,5) == 0){ + pcWrite(regs[rd32] & ~1); + } else { + rfWrite(rd32, regs[iBits(2,5)]); pcWrite(pc + 2); + } + } + break; + case 22: { + uint32_t address = rf_sp + i16_swsp_imm; + if(address & 3){ + trap(0,6, address); + } else { + if(v2p(address, &pAddr, WRITE)){ trap(0, 15, address); return; } + dWrite(pAddr, 4, (uint8_t*)®s[iBits(2,5)]); pcWrite(pc + 2); + lrscReserved = false; + } + }break; + } + } + } +}; + + +class SimElement{ +public: + virtual ~SimElement(){} + virtual void onReset(){} + virtual void postReset(){} + virtual void preCycle(){} + virtual void postCycle(){} +}; + + + +class Workspace; + +class Workspace{ +public: + static mutex staticMutex; + static uint32_t testsCounter, successCounter; + static uint64_t cycles; + uint64_t instanceCycles = 0; + vector<SimElement*> simElements; + Memory mem; + string name; + uint64_t currentTime = 22; + uint64_t mTimeCmp = 0; + uint64_t mTime = 0; + VVexRiscv* top; + bool resetDone = false; + bool riscvRefEnable = false; + uint64_t i; + double cyclesPerSecond = 10e6; + double allowedCycles = 0.0; + uint32_t bootPc = -1; + uint32_t iStall = STALL,dStall = STALL; + #ifdef TRACE + VerilatedFstC* tfp; + #endif + bool allowInvalidate = true; + + uint32_t seed; + + Workspace* setIStall(bool enable) { iStall = enable; return this; } + Workspace* setDStall(bool enable) { dStall = enable; return this; } + + ofstream regTraces; + ofstream memTraces; + ofstream logTraces; + ofstream debugLog; + + struct timespec start_time; + + class CpuRef : public RiscvGolden{ + public: + Memory mem; + + class MemWrite { + public: + int32_t address, size; + uint8_t data42[64]; + }; + + class MemRead { + public: + int32_t address, size; + uint8_t data42[64]; + bool error; + }; + + uint32_t periphWriteTimer = 0; + queue<MemWrite> periphWritesGolden; + queue<MemWrite> periphWrites; + queue<MemRead> periphRead; + Workspace *ws; + CpuRef(Workspace *ws){ + this->ws = ws; + } + + virtual void fail() { ws->fail(); } + + + virtual bool isMmuRegion(uint32_t v) {return ws->isMmuRegion(v);} + + bool rfWriteValid; + int32_t rfWriteAddress; + int32_t rfWriteData; + virtual void rfWrite(int32_t address, int32_t data){ + rfWriteValid = address != 0; + rfWriteAddress = address; + rfWriteData = data; + RiscvGolden::rfWrite(address,data); + } + + + virtual bool iRead(int32_t address, uint32_t *data){ + bool error; + ws->iBusAccess(address, data, &error); +// ws->iBusAccessPatch(address,data,&error); + return error; + } + + virtual bool dRead(int32_t address, int32_t size, uint8_t *data){ + if(size < 1 || size > 8){ + cout << "dRead size=" << size << endl; + fail(); + } + if((address & (size-1)) != 0) + cout << "Ref did a unaligned read" << endl; + if(ws->isPerifRegion(address)){ + MemRead t = periphRead.front(); + if(t.address != address || t.size != size){ + cout << "DRead missmatch" << hex << endl; + cout << " REF : address=" << address << " size=" << size << endl; + cout << " DUT : address=" << t.address << " size=" << t.size << endl; + fail(); + } + + for(int i = 0; i < size; i++){ + data[i] = t.data42[i]; + } + periphRead.pop(); + return t.error; + }else { + mem.read(address, size, data); + } + return false; + } + virtual void dWrite(int32_t address, int32_t size, uint8_t *data){ + if(address & (size-1) != 0) + cout << "Ref did a unaligned write" << endl; + + if(!ws->isPerifRegion(address)){ + mem.write(address, size, data); + } + if(ws->isDBusCheckedRegion(address)){ + MemWrite w; + w.address = address; + w.size = size; + for(int i = 0; i < size; i++){ + w.data42[i] = data[i]; + } + periphWritesGolden.push(w); + if(periphWritesGolden.size() > 10){ + cout << "??? periphWritesGolden" << endl; + fail(); + } + } + } + + + void step() { + rfWriteValid = false; + RiscvGolden::step(); + + switch(periphWrites.empty() + uint32_t(periphWritesGolden.empty())*2){ + case 3: periphWriteTimer = 0; break; + case 1: case 2: if(periphWriteTimer++ == 20){ + cout << "periphWrite timout" << endl; fail(); + } break; + case 0: + MemWrite t = periphWrites.front(); + MemWrite t2 = periphWritesGolden.front(); + bool dataMatch = true; + for(int i = 0;i < min(t.size, t2.size);i++) dataMatch &= t.data42[i] == t2.data42[i]; + if(t.address != t2.address || t.size != t2.size || !dataMatch){ + cout << hex << "periphWrite missmatch" << endl; + cout << " DUT address=" << t.address << " size=" << t.size << " data=" << *((uint32_t*)t.data42) << endl; + cout << " REF address=" << t2.address << " size=" << t2.size << " data=" << *((uint32_t*)t2.data42) << endl; + fail(); + } + periphWrites.pop(); + periphWritesGolden.pop(); + periphWriteTimer = 0; + break; + } + + + } + }; + + CpuRef riscvRef = CpuRef(this); + string vcdName; + Workspace* setVcdName(string name){ + vcdName = name; + return this; + } + Workspace(string name){ + vcdName = name; + //seed = VL_RANDOM_I_WIDTH(32)^VL_RANDOM_I_WIDTH(32)^0x1093472; + //srand48(seed); + // setIStall(false); + // setDStall(false); + staticMutex.lock(); + testsCounter++; + staticMutex.unlock(); + this->name = name; + top = new VVexRiscv; + #ifdef TRACE_ACCESS + regTraces.open (name + ".regTrace"); + memTraces.open (name + ".memTrace"); + #endif + logTraces.open (name + ".logTrace"); + debugLog.open (name + ".debugTrace"); + fillSimELements(); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); + } + + virtual ~Workspace(){ + delete top; + #ifdef TRACE + delete tfp; + #endif + + for(SimElement* simElement : simElements) { + delete simElement; + } + } + + Workspace* loadHex(string path){ + loadHexImpl(path,&mem); + loadHexImpl(path,&riscvRef.mem); + return this; + } + + Workspace* loadBin(string path, uint32_t offset){ + loadBinImpl(path,&mem, offset); + loadBinImpl(path,&riscvRef.mem, offset); + return this; + } + + Workspace* setCyclesPerSecond(double value){ + cyclesPerSecond = value; + return this; + } + + Workspace* bootAt(uint32_t pc) { + bootPc = pc; + riscvRef.pc = pc; + return this; + } + + Workspace* withRiscvRef(){ + #ifdef WITH_RISCV_REF + riscvRefEnable = true; + #endif + return this; + } + + Workspace* withInvalidation(){ + allowInvalidate = true; + return this; + } + Workspace* withoutInvalidation(){ + allowInvalidate = false; + return this; + } + Workspace* writeWord(uint32_t address, uint32_t data){ + mem.write(address, 4, (uint8_t*)&data); + riscvRef.mem.write(address, 4, (uint8_t*)&data); + return this; + } + + virtual bool isPerifRegion(uint32_t addr) { return false; } + virtual bool isMmuRegion(uint32_t addr) { return true;} + virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error) { + if(addr % 4 != 0) { + cout << "Warning, unaligned IBusAccess : " << addr << endl; + fail(); + } + *data = ( (mem[addr + 0] << 0) + | (mem[addr + 1] << 8) + | (mem[addr + 2] << 16) + | (mem[addr + 3] << 24)); + *error = false; + } + + + virtual bool isDBusCheckedRegion(uint32_t address){ return isPerifRegion(address);} + virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size, uint8_t *data, bool *error) { + assertEq(addr % size, 0); + if(!isPerifRegion(addr)) { + if(wr){ + for(uint32_t b = 0;b < size;b++){ + *mem.get(addr + b) = ((uint8_t*)data)[b]; + } + + }else{ + uint32_t innerOffset = addr & (DBUS_LOAD_DATA_WIDTH/8-1); + for(uint32_t b = 0;b < size;b++){ + ((uint8_t*)data)[b] = mem[addr + b]; + } + } + } + + + if(wr){ + if(isDBusCheckedRegion(addr)){ + CpuRef::MemWrite w; + w.address = addr; + w.size = size; + for(uint32_t b = 0;b < size;b++){ + w.data42[b] = data[b]; + } + riscvRef.periphWrites.push(w); + } + } else { + if(isPerifRegion(addr)){ + CpuRef::MemRead r; + r.address = addr; + r.size = size; + for(uint32_t b = 0;b < size;b++){ + r.data42[b] = data[b]; + } + r.error = *error; + riscvRef.periphRead.push(r); + } + } + } + +// void periphAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error){ +// if(wr){ +// CpuRef::MemWrite w; +// w.address = addr; +// w.size = 1 << size; +// w.data = *data; +// riscvRef.periphWrites.push(w); +// } else { +// CpuRef::MemRead r; +// r.address = addr; +// r.size = 1 << size; +// r.data = *data; +// r.error = *error; +// riscvRef.periphRead.push(r); +// } +// } + + virtual void postReset() {} + virtual void checks(){} + virtual void pass(){ throw success();} + virtual void fail(){ throw std::exception();} + virtual void fillSimELements(); + void dump(uint64_t i){ + #ifdef TRACE + if(i == TRACE_START && i != 0) cout << "**" << endl << "**" << endl << "**" << endl << "**" << endl << "**" << endl << "START TRACE" << endl; + if(i >= TRACE_START) tfp->dump(i); + #ifdef TRACE_SPORADIC + else if(i % 1000000 < 100) tfp->dump(i); + #endif + #endif + } + + uint64_t privilegeCounters[4] = {0,0,0,0}; + Workspace* run(uint64_t timeout = 5000){ +// cout << "Start " << name << endl; + if(timeout == 0) timeout = 0x7FFFFFFFFFFFFFFF; + + currentTime = 4; + // init trace dump + #ifdef TRACE + Verilated::traceEverOn(true); + tfp = new VerilatedFstC; + top->trace(tfp, 99); + tfp->open((vcdName + ".fst").c_str()); + #endif + + // Reset + top->clk = 0; + top->reset = 0; + + + top->eval(); currentTime = 3; + for(SimElement* simElement : simElements) simElement->onReset(); + + top->reset = 1; + top->eval(); + top->clk = 1; + top->eval(); + top->clk = 0; + top->eval(); + #ifdef CSR + top->timerInterrupt = 0; + top->externalInterrupt = 1; + top->softwareInterrupt = 0; + #endif + #ifdef SUPERVISOR + top->externalInterruptS = 0; + #endif + #ifdef DEBUG_PLUGIN_EXTERNAL + top->timerInterrupt = 0; + top->externalInterrupt = 0; + #endif + dump(0); + top->reset = 0; + for(SimElement* simElement : simElements) simElement->postReset(); + + top->eval(); currentTime = 2; + + + postReset(); + + //Sync register file initial content + for(int i = 1;i < 32;i++){ + riscvRef.regs[i] = top->VexRiscv->RegFilePlugin_regFile[i]; + } + resetDone = true; + + #ifdef REF + if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc; + #else + if(bootPc != -1) { + #if defined(IBUS_SIMPLE) || defined(IBUS_SIMPLE_WISHBONE) || defined(IBUS_SIMPLE_AHBLITE3) + top->VexRiscv->IBusSimplePlugin_fetchPc_pcReg = bootPc; + #ifdef COMPRESSED + top->VexRiscv->IBusSimplePlugin_decodePc_pcReg = bootPc; + #endif + #else + top->VexRiscv->IBusCachedPlugin_fetchPc_pcReg = bootPc; + #ifdef COMPRESSED + top->VexRiscv->IBusCachedPlugin_decodePc_pcReg = bootPc; + #endif + #endif + } + #endif + + + bool failed = false; + try { + // run simulation for 100 clock periods + for (i = 16; i < timeout*2; i+=2) { + /*while(allowedCycles <= 0.0){ + struct timespec end_time; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time); + uint64_t diffInNanos = end_time.tv_sec*1e9 + end_time.tv_nsec - start_time.tv_sec*1e9 - start_time.tv_nsec; + start_time = end_time; + double dt = diffInNanos*1e-9; + allowedCycles += dt*cyclesPerSecond; + if(allowedCycles > cyclesPerSecond/100) allowedCycles = cyclesPerSecond/100; + } + allowedCycles-=1.0;*/ + + + #ifndef REF_TIME + #ifndef MTIME_INSTR_FACTOR + mTime = i/2; + #else + mTime += top->VexRiscv->lastStageIsFiring*MTIME_INSTR_FACTOR; + #endif + #endif + #ifdef TIMER_INTERRUPT + top->timerInterrupt = mTime >= mTimeCmp ? 1 : 0; + //if(mTime == mTimeCmp) printf("SIM timer tick\n"); + #endif + + + #ifdef UTIME_INPUT + top->utime = mTime; + #endif + + currentTime = i; + + #ifdef FLOW_INFO + if(i % 5000000 == 0) cout << endl << "**" << endl << "**" << endl << "PROGRESS TRACE_START=" << i << endl; + #endif + + + // dump variables into VCD file and toggle clock + + dump(i); + //top->eval(); + top->clk = 0; + top->eval(); + + #ifdef CSR + if(riscvRefEnable) { + riscvRef.ipInput = 0; + #ifdef TIMER_INTERRUPT + riscvRef.ipInput |= top->timerInterrupt << 7; + #endif + #ifdef EXTERNAL_INTERRUPT + riscvRef.ipInput |= top->externalInterrupt << 11; + #endif + #ifdef CSR + riscvRef.ipInput |= top->softwareInterrupt << 3; + #endif + #ifdef SUPERVISOR + // riscvRef.ipInput |= top->timerInterruptS << 5; + riscvRef.ipInput |= top->externalInterruptS << 9; + #endif + + riscvRef.liveness(top->VexRiscv->CsrPlugin_inWfi); + if(top->VexRiscv->CsrPlugin_interruptJump){ + if(riscvRefEnable) riscvRef.trap(true, top->VexRiscv->CsrPlugin_interrupt_code); + } + } + #endif + + #ifdef RVF + if(riscvRefEnable) { + if(top->VexRiscv->writeBack_FpuPlugin_commit_valid && top->VexRiscv->writeBack_FpuPlugin_commit_ready && top->VexRiscv->writeBack_FpuPlugin_commit_payload_write){ + FpuCommit c; + c.value = top->VexRiscv->writeBack_FpuPlugin_commit_payload_value; + riscvRef.fpuCommit.push(c); + } + + if(top->VexRiscv->FpuPlugin_port_rsp_valid && top->VexRiscv->FpuPlugin_port_rsp_ready && top->VexRiscv->lastStageIsFiring){ + FpuRsp c; + c.value = top->VexRiscv->FpuPlugin_port_rsp_payload_value; + c.flags = (top->VexRiscv->FpuPlugin_port_rsp_payload_NX << 0) | + (top->VexRiscv->FpuPlugin_port_rsp_payload_NV << 4); + riscvRef.fpuRsp.push(c); + } + + if(top->VexRiscv->FpuPlugin_port_completion_valid && top->VexRiscv->FpuPlugin_port_completion_payload_written){ + FpuCompletion c; + c.flags = (top->VexRiscv->FpuPlugin_port_completion_payload_flags_NX << 0) | + (top->VexRiscv->FpuPlugin_port_completion_payload_flags_UF << 1) | + (top->VexRiscv->FpuPlugin_port_completion_payload_flags_OF << 2) | + (top->VexRiscv->FpuPlugin_port_completion_payload_flags_DZ << 3) | + (top->VexRiscv->FpuPlugin_port_completion_payload_flags_NV << 4); + riscvRef.fpuCompletion.push(c); + } + } + #endif + + + + if(top->VexRiscv->lastStageIsFiring){ + if(riscvRefEnable) { +// privilegeCounters[riscvRef.privilege]++; +// if((riscvRef.stepCounter & 0xFFFFF) == 0){ +// cout << "privilege report" << endl; +// cout << "- U " << privilegeCounters[0] << endl; +// cout << "- S " << privilegeCounters[1] << endl; +// cout << "- M " << privilegeCounters[3] << endl; +// } + riscvRef.dutRfWriteValue = top->VexRiscv->lastStageRegFileWrite_payload_data; + riscvRef.step(); + bool mIntTimer = false; + bool mIntExt = false; + } + + if(riscvRefEnable && top->VexRiscv->lastStagePc != riscvRef.lastPc){ + cout << hex << " pc missmatch " << top->VexRiscv->lastStagePc << " should be " << riscvRef.lastPc << dec << endl; + fail(); + } + + + bool rfWriteValid = false; + int32_t rfWriteAddress; + int32_t rfWriteData; + + if(top->VexRiscv->lastStageRegFileWrite_valid == 1 && top->VexRiscv->lastStageRegFileWrite_payload_address != 0){ + rfWriteValid = true; + rfWriteAddress = top->VexRiscv->lastStageRegFileWrite_payload_address; + rfWriteData = top->VexRiscv->lastStageRegFileWrite_payload_data; + #ifdef TRACE_ACCESS + regTraces << + #ifdef TRACE_WITH_TIME + currentTime << + #endif + " PC " << hex << setw(8) << top->VexRiscv->lastStagePc << " : reg[" << dec << setw(2) << (uint32_t)top->VexRiscv->lastStageRegFileWrite_payload_address << "] = " << hex << setw(8) << top->VexRiscv->lastStageRegFileWrite_payload_data << dec << endl; + #endif + } else { + #ifdef TRACE_ACCESS + regTraces << + #ifdef TRACE_WITH_TIME + currentTime << + #endif + " PC " << hex << setw(8) << top->VexRiscv->lastStagePc << dec << endl; + #endif + } + if(riscvRefEnable) if(rfWriteValid != riscvRef.rfWriteValid || + (rfWriteValid && (rfWriteAddress!= riscvRef.rfWriteAddress || rfWriteData!= riscvRef.rfWriteData))){ + cout << "regFile write missmatch :" << endl; + if(rfWriteValid) cout << " REF: RF[" << riscvRef.rfWriteAddress << "] = 0x" << hex << riscvRef.rfWriteData << dec << endl; + if(rfWriteValid) cout << " DUT: RF[" << rfWriteAddress << "] = 0x" << hex << rfWriteData << dec << endl; + fail(); + } + } + + #ifdef CSR + if(top->VexRiscv->CsrPlugin_hadException){ + if(riscvRefEnable) { + riscvRef.step(); + } + } + #endif + + for(SimElement* simElement : simElements) simElement->preCycle(); + + dump(i + 1); + + checks(); + //top->eval(); + top->clk = 1; + top->eval(); + + instanceCycles += 1; + + for(SimElement* simElement : simElements) simElement->postCycle(); + #ifdef RVF + top->fpuCmdHalt = VL_RANDOM_I_WIDTH(1); + top->fpuCommitHalt = VL_RANDOM_I_WIDTH(1); + top->fpuRspHalt = VL_RANDOM_I_WIDTH(1); + #endif + + + + if (Verilated::gotFinish()) + exit(0); + } + cout << "timeout" << endl; + fail(); + } catch (const success e) { + staticMutex.lock(); + cout <<"SUCCESS " << name << endl; + successCounter++; + cycles += instanceCycles; + staticMutex.unlock(); + } catch (const std::exception& e) { + staticMutex.lock(); + + cout << "FAIL " << name << " at PC=" << hex << setw(8) << top->VexRiscv->lastStagePc << dec; //<< " seed : " << seed << + if(riscvRefEnable) cout << hex << " REF PC=" << riscvRef.lastPc << " REF I=" << riscvRef.lastInstruction << dec; + cout << " time=" << i; + cout << endl; + + cycles += instanceCycles; + staticMutex.unlock(); + failed = true; + } + + + + dump(i+2); + dump(i+10); + #ifdef TRACE + tfp->close(); + #endif + #ifdef STOP_ON_ERROR + if(failed){ + sleep(1); + exit(-1); + } + #endif + return this; + } +}; + + +class WorkspaceRegression : public Workspace { +public: + + WorkspaceRegression(string name) : Workspace(name){ + + } + + virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xF0000000;} + + + virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error){ + Workspace::iBusAccess(addr,data,error); + *error = addr == 0xF00FFF60u; + } + + virtual void dutPutChar(char c){} + + virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size, uint8_t *dataBytes, bool *error) { + uint32_t *data = ((uint32_t*)dataBytes); + if(wr){ + switch(addr){ + case 0xF0010000u: { + cout << (char)*data; + logTraces << (char)*data; + dutPutChar((char)*data); + break; + } +#ifdef EXTERNAL_INTERRUPT + case 0xF0011000u: top->externalInterrupt = *data & 1; break; +#endif +#ifdef SUPERVISOR + case 0xF0012000u: top->externalInterruptS = *data & 1; break; +#endif +#ifdef CSR + case 0xF0013000u: top->softwareInterrupt = *data & 1; break; +#endif + case 0xF00FFF00u: { + cout << (char)*data; + logTraces << (char)*data; + dutPutChar((char)*data); + break; + } + #ifndef DEBUG_PLUGIN_EXTERNAL + case 0xF00FFF20u: + if(*data == 0) + pass(); + else + fail(); + break; + case 0xF00FFF24u: + cout << "TEST ERROR CODE " << *data << endl; + fail(); + break; + #endif + case 0xF00FFF48u: mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data;break; + case 0xF00FFF4Cu: mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); break; + case 0xF00FFF50u: cout << "mTime " << *data << " : " << mTime << endl; + } + if((addr & 0xFFFFF000) == 0xF5670000){ + uint32_t t = 0x900FF000 | (addr & 0xFFF); + uint32_t old = (*mem.get(t + 3) << 24) | (*mem.get(t + 2) << 16) | (*mem.get(t + 1) << 8) | (*mem.get(t + 0) << 0); + old++; + *mem.get(t + 0) = old & 0xFF; old >>= 8; + *mem.get(t + 1) = old & 0xFF; old >>= 8; + *mem.get(t + 2) = old & 0xFF; old >>= 8; + *mem.get(t + 3) = old & 0xFF; old >>= 8; + } + }else{ + switch(addr){ + case 0xF00FFF10u: + *data = mTime; + #ifdef REF_TIME + mTime += 100000; + #endif + break; + case 0xF00FFF40u: *data = mTime; break; + case 0xF00FFF44u: *data = mTime >> 32; break; + case 0xF00FFF48u: *data = mTimeCmp; break; + case 0xF00FFF4Cu: *data = mTimeCmp >> 32; break; + case 0xF0010004u: *data = ~0; break; + } + } + + *error = addr == 0xF00FFF60u; + Workspace::dBusAccess(addr,wr,size,dataBytes,error); + } + + + +}; + + + +class ZephyrRegression : public WorkspaceRegression{ +public: + + + uint32_t regFileWriteRefIndex = 0; + const char *target = "PROJECT EXECUTION SUCCESSFUL"; + const char *hit = target; + + ZephyrRegression(string name) : WorkspaceRegression(name) { + cout << endl << endl; + + } + + virtual void dutPutChar(char c){ + if(*hit == c) hit++; else hit = target; + if(*hit == 0) { + cout << endl << "T=" << i <<endl; + cout << endl; + pass(); + } + } +}; + + + + + + +#ifdef IBUS_SIMPLE +class IBusSimple : public SimElement{ +public: + uint32_t pendings[256]; + uint32_t rPtr = 0, wPtr = 0; + + Workspace *ws; + VVexRiscv* top; + IBusSimple(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->iBus_cmd_ready = 1; + top->iBus_rsp_valid = 0; + } + + virtual void preCycle(){ + if (top->iBus_cmd_valid && top->iBus_cmd_ready) { + //assertEq(top->iBus_cmd_payload_pc & 3,0); + pendings[wPtr] = (top->iBus_cmd_payload_pc); + wPtr = (wPtr + 1) & 0xFF; + //ws->iBusAccess(top->iBus_cmd_payload_pc,&inst_next,&error_next); + } + } + //TODO doesn't catch when instruction removed ? + virtual void postCycle(){ + top->iBus_rsp_valid = 0; + if(rPtr != wPtr && (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100)){ + uint32_t inst_next; + bool error_next; + ws->iBusAccess(pendings[rPtr], &inst_next,&error_next); + rPtr = (rPtr + 1) & 0xFF; + top->iBus_rsp_payload_inst = inst_next; + top->iBus_rsp_valid = 1; + top->iBus_rsp_payload_error = error_next; + } else { + top->iBus_rsp_payload_inst = VL_RANDOM_I_WIDTH(32); + top->iBus_rsp_payload_error = VL_RANDOM_I_WIDTH(1); + } + if(ws->iStall) top->iBus_cmd_ready = VL_RANDOM_I_WIDTH(7) < 100; + } +}; +#endif + + +#ifdef IBUS_TC + +class IBusTc : public SimElement{ +public: + + uint32_t nextData; + + Workspace *ws; + VVexRiscv* top; + IBusTc(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + } + + virtual void preCycle(){ + if (top->iBusTc_enable) { + if((top->iBusTc_address & 0x70000000) != 0){ + printf("IBusTc access out of range\n"); + ws->fail(); + } + bool error_next; + ws->iBusAccess(top->iBusTc_address, &nextData,&error_next); + } + } + + virtual void postCycle(){ + top->iBusTc_data = nextData; + } +}; + +#endif + + +#ifdef IBUS_SIMPLE_AVALON + +struct IBusSimpleAvalonRsp{ + uint32_t data; + bool error; +}; + + +class IBusSimpleAvalon : public SimElement{ +public: + queue<IBusSimpleAvalonRsp> rsps; + + Workspace *ws; + VVexRiscv* top; + IBusSimpleAvalon(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->iBusAvalon_waitRequestn = 1; + top->iBusAvalon_readDataValid = 0; + } + + virtual void preCycle(){ + if (top->iBusAvalon_read && top->iBusAvalon_waitRequestn) { + IBusSimpleAvalonRsp rsp; + ws->iBusAccess(top->iBusAvalon_address,&rsp.data,&rsp.error); + rsps.push(rsp); + } + } + //TODO doesn't catch when instruction removed ? + virtual void postCycle(){ + if(!rsps.empty() && (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100)){ + IBusSimpleAvalonRsp rsp = rsps.front(); rsps.pop(); + top->iBusAvalon_readDataValid = 1; + top->iBusAvalon_readData = rsp.data; + top->iBusAvalon_response = rsp.error ? 3 : 0; + } else { + top->iBusAvalon_readDataValid = 0; + top->iBusAvalon_readData = VL_RANDOM_I_WIDTH(32); + top->iBusAvalon_response = VL_RANDOM_I_WIDTH(2); + } + if(ws->iStall) + top->iBusAvalon_waitRequestn = VL_RANDOM_I_WIDTH(7) < 100; + } +}; +#endif + + + +#ifdef IBUS_SIMPLE_AHBLITE3 +class IBusSimpleAhbLite3 : public SimElement{ +public: + Workspace *ws; + VVexRiscv* top; + + uint32_t iBusAhbLite3_HRDATA; + bool iBusAhbLite3_HRESP; + bool pending; + + IBusSimpleAhbLite3(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + pending = false; + top->iBusAhbLite3_HREADY = 1; + top->iBusAhbLite3_HRESP = 0; + } + + virtual void preCycle(){ + if (top->iBusAhbLite3_HTRANS == 2 && top->iBusAhbLite3_HREADY && !top->iBusAhbLite3_HWRITE) { + ws->iBusAccess(top->iBusAhbLite3_HADDR,&iBusAhbLite3_HRDATA,&iBusAhbLite3_HRESP); + pending = true; + } + } + + virtual void postCycle(){ + if(ws->iStall) + top->iBusAhbLite3_HREADY = (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100); + + if(pending && top->iBusAhbLite3_HREADY){ + top->iBusAhbLite3_HRDATA = iBusAhbLite3_HRDATA; + top->iBusAhbLite3_HRESP = iBusAhbLite3_HRESP; + pending = false; + } else { + top->iBusAhbLite3_HRDATA = VL_RANDOM_I_WIDTH(32); + top->iBusAhbLite3_HRESP = VL_RANDOM_I_WIDTH(1); + } + } +}; +#endif + + +#ifdef IBUS_CACHED +class IBusCached : public SimElement{ +public: + bool error_next = false; + uint32_t pendingCount = 0; + uint32_t address; + + Workspace *ws; + VVexRiscv* top; + IBusCached(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + + virtual void onReset(){ + top->iBus_cmd_ready = 1; + top->iBus_rsp_valid = 0; + } + + virtual void preCycle(){ + if (top->iBus_cmd_valid && top->iBus_cmd_ready && pendingCount == 0) { + assertEq((top->iBus_cmd_payload_address & 3),0); + pendingCount = (1 << top->iBus_cmd_payload_size)/4; + address = top->iBus_cmd_payload_address; + } + } + + virtual void postCycle(){ + bool error; + top->iBus_rsp_valid = 0; + if(pendingCount != 0 && (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100)){ + #ifdef IBUS_TC + if((address & 0x70000000) == 0){ + printf("IBUS_CACHED access out of range\n"); + ws->fail(); + } + #endif + error = false; + for(int idx = 0;idx < IBUS_DATA_WIDTH/32;idx++){ + bool localError = false; + ws->iBusAccess(address+idx*4,((uint32_t*)&top->iBus_rsp_payload_data)+idx,&localError); + error |= localError; + } + top->iBus_rsp_payload_error = error; + pendingCount-=IBUS_DATA_WIDTH/32; + address = address + IBUS_DATA_WIDTH/8; + top->iBus_rsp_valid = 1; + } + if(ws->iStall) top->iBus_cmd_ready = VL_RANDOM_I_WIDTH(7) < 100 && pendingCount == 0; + } +}; +#endif + +#ifdef IBUS_CACHED_AVALON +#include <queue> + +struct IBusCachedAvalonTask{ + uint32_t address; + uint32_t pendingCount; +}; + +class IBusCachedAvalon : public SimElement{ +public: + uint32_t inst_next = VL_RANDOM_I_WIDTH(32); + bool error_next = false; + + queue<IBusCachedAvalonTask> tasks; + Workspace *ws; + VVexRiscv* top; + + IBusCachedAvalon(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->iBusAvalon_waitRequestn = 1; + top->iBusAvalon_readDataValid = 0; + } + + virtual void preCycle(){ + if (top->iBusAvalon_read && top->iBusAvalon_waitRequestn) { + assertEq(top->iBusAvalon_address & 3,0); + IBusCachedAvalonTask task; + task.address = top->iBusAvalon_address; + task.pendingCount = top->iBusAvalon_burstCount; + tasks.push(task); + } + } + + virtual void postCycle(){ + bool error; + top->iBusAvalon_readDataValid = 0; + if(!tasks.empty() && (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100)){ + uint32_t &address = tasks.front().address; + uint32_t &pendingCount = tasks.front().pendingCount; + bool error; + ws->iBusAccess(address,&top->iBusAvalon_readData,&error); + top->iBusAvalon_response = error ? 3 : 0; + pendingCount--; + address = (address & ~0x1F) + ((address + 4) & 0x1F); + top->iBusAvalon_readDataValid = 1; + if(pendingCount == 0) + tasks.pop(); + } + if(ws->iStall) + top->iBusAvalon_waitRequestn = VL_RANDOM_I_WIDTH(7) < 100; + } +}; +#endif + + +#if defined(IBUS_CACHED_WISHBONE) || defined(IBUS_SIMPLE_WISHBONE) +#include <queue> + +class IBusCachedWishbone : public SimElement{ +public: + + Workspace *ws; + VVexRiscv* top; + + IBusCachedWishbone(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->iBusWishbone_ACK = !ws->iStall; + top->iBusWishbone_ERR = 0; + } + + virtual void preCycle(){ + + } + + virtual void postCycle(){ + + if(ws->iStall) + top->iBusWishbone_ACK = VL_RANDOM_I_WIDTH(7) < 100; + + top->iBusWishbone_DAT_MISO = VL_RANDOM_I_WIDTH(32); + if (top->iBusWishbone_CYC && top->iBusWishbone_STB && top->iBusWishbone_ACK) { + if(top->iBusWishbone_WE){ + + } else { + bool error; + ws->iBusAccess(top->iBusWishbone_ADR << 2,&top->iBusWishbone_DAT_MISO,&error); + top->iBusWishbone_ERR = error; + } + } + } +}; +#endif + + +#ifdef DBUS_SIMPLE +class DBusSimple : public SimElement{ +public: + uint32_t data_next = VL_RANDOM_I_WIDTH(32); + bool error_next = false; + bool pending = false; + + Workspace *ws; + VVexRiscv* top; + DBusSimple(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->dBus_cmd_ready = 1; + top->dBus_rsp_ready = 1; + } + + virtual void preCycle(){ + if (top->dBus_cmd_valid && top->dBus_cmd_ready) { + pending = true; + data_next = top->dBus_cmd_payload_data; + ws->dBusAccess(top->dBus_cmd_payload_address,top->dBus_cmd_payload_wr,1 << top->dBus_cmd_payload_size,((uint8_t*)&data_next) + (top->dBus_cmd_payload_address & 3),&error_next); + } + } + + virtual void postCycle(){ + top->dBus_rsp_ready = 0; + if(pending && (!ws->dStall || VL_RANDOM_I_WIDTH(7) < 100)){ + pending = false; + top->dBus_rsp_ready = 1; + top->dBus_rsp_data = data_next; + top->dBus_rsp_error = error_next; + } else{ + top->dBus_rsp_data = VL_RANDOM_I_WIDTH(32); + } + + if(ws->dStall) top->dBus_cmd_ready = VL_RANDOM_I_WIDTH(7) < 100 && !pending; + } +}; +#endif + +#ifdef DBUS_SIMPLE_AVALON +#include <queue> +struct DBusSimpleAvalonRsp{ + uint32_t data; + bool error; +}; + + +class DBusSimpleAvalon : public SimElement{ +public: + queue<DBusSimpleAvalonRsp> rsps; + + Workspace *ws; + VVexRiscv* top; + DBusSimpleAvalon(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->dBusAvalon_waitRequestn = 1; + top->dBusAvalon_readDataValid = 0; + } + + virtual void preCycle(){ + if (top->dBusAvalon_write && top->dBusAvalon_waitRequestn) { + bool dummy; + ws->dBusAccess(top->dBusAvalon_address,1,2,top->dBusAvalon_byteEnable,&top->dBusAvalon_writeData,&dummy); + } + if (top->dBusAvalon_read && top->dBusAvalon_waitRequestn) { + DBusSimpleAvalonRsp rsp; + ws->dBusAccess(top->dBusAvalon_address,0,2,0xF,&rsp.data,&rsp.error); + rsps.push(rsp); + } + } + //TODO doesn't catch when instruction removed ? + virtual void postCycle(){ + if(!rsps.empty() && (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100)){ + DBusSimpleAvalonRsp rsp = rsps.front(); rsps.pop(); + top->dBusAvalon_readDataValid = 1; + top->dBusAvalon_readData = rsp.data; + top->dBusAvalon_response = rsp.error ? 3 : 0; + } else { + top->dBusAvalon_readDataValid = 0; + top->dBusAvalon_readData = VL_RANDOM_I_WIDTH(32); + top->dBusAvalon_response = VL_RANDOM_I_WIDTH(2); + } + if(ws->iStall) + top->dBusAvalon_waitRequestn = VL_RANDOM_I_WIDTH(7) < 100; + } +}; +#endif + + + +#ifdef DBUS_SIMPLE_AHBLITE3 +class DBusSimpleAhbLite3 : public SimElement{ +public: + Workspace *ws; + VVexRiscv* top; + + uint32_t dBusAhbLite3_HADDR, dBusAhbLite3_HSIZE, dBusAhbLite3_HTRANS, dBusAhbLite3_HWRITE; + + DBusSimpleAhbLite3(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->dBusAhbLite3_HREADY = 1; + top->dBusAhbLite3_HRESP = 0; + dBusAhbLite3_HTRANS = 0; + } + + virtual void preCycle(){ + if(top->dBusAhbLite3_HREADY && dBusAhbLite3_HTRANS == 2 && dBusAhbLite3_HWRITE){ + uint32_t data = top->dBusAhbLite3_HWDATA; + bool error; + ws->dBusAccess(dBusAhbLite3_HADDR, 1, dBusAhbLite3_HSIZE, ((1 << (1 << dBusAhbLite3_HSIZE))-1) << (dBusAhbLite3_HADDR & 0x3),&data,&error); + } + + if(top->dBusAhbLite3_HREADY){ + dBusAhbLite3_HADDR = top->dBusAhbLite3_HADDR ; + dBusAhbLite3_HSIZE = top->dBusAhbLite3_HSIZE ; + dBusAhbLite3_HTRANS = top->dBusAhbLite3_HTRANS ; + dBusAhbLite3_HWRITE = top->dBusAhbLite3_HWRITE ; + } + } + + virtual void postCycle(){ + if(ws->iStall) + top->dBusAhbLite3_HREADY = (!ws->iStall || VL_RANDOM_I_WIDTH(7) < 100); + + top->dBusAhbLite3_HRDATA = VL_RANDOM_I_WIDTH(32); + top->dBusAhbLite3_HRESP = VL_RANDOM_I_WIDTH(1); + + if(top->dBusAhbLite3_HREADY && dBusAhbLite3_HTRANS == 2 && !dBusAhbLite3_HWRITE){ + + bool error; + ws->dBusAccess(dBusAhbLite3_HADDR, 0, dBusAhbLite3_HSIZE, ((1 << (1 << dBusAhbLite3_HSIZE))-1) << (dBusAhbLite3_HADDR & 0x3),&top->dBusAhbLite3_HRDATA,&error); + top->dBusAhbLite3_HRESP = error; + } + } +}; +#endif + + +#if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE) +#include <queue> + + +class DBusCachedWishbone : public SimElement{ +public: + + Workspace *ws; + VVexRiscv* top; + + DBusCachedWishbone(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->dBusWishbone_ACK = !ws->iStall; + top->dBusWishbone_ERR = 0; + } + + virtual void preCycle(){ + + } + + virtual void postCycle(){ + if(ws->iStall) + top->dBusWishbone_ACK = VL_RANDOM_I_WIDTH(7) < 100; + top->dBusWishbone_DAT_MISO = VL_RANDOM_I_WIDTH(32); + if (top->dBusWishbone_CYC && top->dBusWishbone_STB && top->dBusWishbone_ACK) { + if(top->dBusWishbone_WE){ + bool dummy; + ws->dBusAccess(top->dBusWishbone_ADR << 2 ,1,2,top->dBusWishbone_SEL,&top->dBusWishbone_DAT_MOSI,&dummy); + } else { + bool error; + ws->dBusAccess(top->dBusWishbone_ADR << 2,0,2,0xF,&top->dBusWishbone_DAT_MISO,&error); + top->dBusWishbone_ERR = error; + } + } + } +}; +#endif + +#ifdef DBUS_CACHED + +//#include "VVexRiscv_DataCache.h" +#include <queue> + +struct DBusCachedTask{ + char data[DBUS_LOAD_DATA_WIDTH/8]; + bool error; + bool last; + bool exclusive; +}; + +class DBusCached : public SimElement{ +public: + queue<DBusCachedTask> rsps; + queue<uint32_t> invalidationHint; + + bool reservationValid = false; + uint32_t reservationAddress; + uint32_t pendingSync = 0; + + Workspace *ws; + VVexRiscv* top; + DBusCachedTask rsp; + + DBusCached(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->dBus_cmd_ready = 1; + top->dBus_rsp_valid = 0; + #ifdef DBUS_AGGREGATION + top->dBus_rsp_payload_aggregated = 0; + #endif + #ifdef DBUS_INVALIDATE + top->dBus_inv_valid = 0; + top->dBus_ack_ready = 0; + top->dBus_sync_valid = 0; + #ifdef DBUS_AGGREGATION + top->dBus_sync_payload_aggregated = 0; + #endif + #endif + } + + virtual void preCycle(){ + if (top->dBus_cmd_valid && top->dBus_cmd_ready) { + if(top->dBus_cmd_payload_wr){ + int size = 1 << top->dBus_cmd_payload_size; + #ifdef DBUS_INVALIDATE + pendingSync += 1; + #endif + #ifndef DBUS_EXCLUSIVE + bool error; + int shift = top->dBus_cmd_payload_address & (DBUS_STORE_DATA_WIDTH/8-1); + ws->dBusAccess(top->dBus_cmd_payload_address,1,size,((uint8_t*)&top->dBus_cmd_payload_data) + shift,&error); + #else + bool cancel = false, error = false; + if(top->dBus_cmd_payload_exclusive){ + bool hit = reservationValid && reservationAddress == top->dBus_cmd_payload_address; + rsp.exclusive = hit; + cancel = !hit; + } + if(!cancel) { + for(int idx = 0;idx < 1;idx++){ + bool localError = false; + int shift = top->dBus_cmd_payload_address & (DBUS_STORE_DATA_WIDTH/8-1); + ws->dBusAccess(top->dBus_cmd_payload_address,1,size,((uint8_t*)&top->dBus_cmd_payload_data) + shift,&localError); + error |= localError; + } + } + + reservationValid = false; + rsp.last = true; + rsp.error = error; + rsps.push(rsp); + #endif + } else { + bool error = false; + uint32_t beatCount = (((1 << top->dBus_cmd_payload_size)*8+DBUS_LOAD_DATA_WIDTH-1) / DBUS_LOAD_DATA_WIDTH)-1; + uint32_t startAt = top->dBus_cmd_payload_address; + uint32_t endAt = top->dBus_cmd_payload_address + (1 << top->dBus_cmd_payload_size); + uint32_t address = top->dBus_cmd_payload_address & ~(DBUS_LOAD_DATA_WIDTH/8-1); + uint8_t buffer[64]; + ws->dBusAccess(top->dBus_cmd_payload_address,0,1 << top->dBus_cmd_payload_size,buffer, &error); + for(int beat = 0;beat <= beatCount;beat++){ + for(int i = 0;i < DBUS_LOAD_DATA_WIDTH/8;i++){ + rsp.data[i] = (address >= startAt && address < endAt) ? buffer[address-top->dBus_cmd_payload_address] : VL_RANDOM_I_WIDTH(8); + address += 1; + } + rsp.last = beat == beatCount; + #ifdef DBUS_EXCLUSIVE + if(top->dBus_cmd_payload_exclusive){ + rsp.exclusive = true; + reservationValid = true; + reservationAddress = top->dBus_cmd_payload_address; + } + #endif + rsp.error = error; + rsps.push(rsp); + } + + #ifdef DBUS_INVALIDATE + if(ws->allowInvalidate){ + if(VL_RANDOM_I_WIDTH(7) < 10){ + invalidationHint.push(top->dBus_cmd_payload_address + VL_RANDOM_I_WIDTH(5)); + } + } + #endif + } + } + #ifdef DBUS_INVALIDATE + if(top->dBus_sync_valid && top->dBus_sync_ready){ + pendingSync -= 1; + } + #endif + } + + virtual void postCycle(){ + + if(!rsps.empty() && (!ws->dStall || VL_RANDOM_I_WIDTH(7) < 100)){ + DBusCachedTask rsp = rsps.front(); + rsps.pop(); + top->dBus_rsp_valid = 1; + top->dBus_rsp_payload_error = rsp.error; + for(int idx = 0;idx < DBUS_LOAD_DATA_WIDTH/32;idx++){ + ((uint32_t*)&top->dBus_rsp_payload_data)[idx] = ((uint32_t*)rsp.data)[idx]; + } + top->dBus_rsp_payload_last = rsp.last; + #ifdef DBUS_EXCLUSIVE + top->dBus_rsp_payload_exclusive = rsp.exclusive; + #endif + } else{ + top->dBus_rsp_valid = 0; + for(int idx = 0;idx < DBUS_LOAD_DATA_WIDTH/32;idx++){ + ((uint32_t*)&top->dBus_rsp_payload_data)[idx] = VL_RANDOM_I_WIDTH(32); + } + top->dBus_rsp_payload_error = VL_RANDOM_I_WIDTH(1); + top->dBus_rsp_payload_last = VL_RANDOM_I_WIDTH(1); + #ifdef DBUS_EXCLUSIVE + top->dBus_rsp_payload_exclusive = VL_RANDOM_I_WIDTH(1); + #endif + } + top->dBus_cmd_ready = (ws->dStall ? VL_RANDOM_I_WIDTH(7) < 100 : 1); + + #ifdef DBUS_INVALIDATE + if(ws->allowInvalidate){ + if(top->dBus_inv_ready) top->dBus_inv_valid = 0; + if(top->dBus_inv_valid == 0 && VL_RANDOM_I_WIDTH(7) < 5){ + top->dBus_inv_valid = 1; + top->dBus_inv_payload_fragment_enable = VL_RANDOM_I_WIDTH(7) < 100; + if(!invalidationHint.empty()){ + top->dBus_inv_payload_fragment_address = invalidationHint.front(); + invalidationHint.pop(); + } else { + top->dBus_inv_payload_fragment_address = VL_RANDOM_I_WIDTH(32); + } + } + } + top->dBus_ack_ready = (ws->dStall ? VL_RANDOM_I_WIDTH(7) < 100 : 1); + if(top->dBus_sync_ready) top->dBus_sync_valid = 0; + if(top->dBus_sync_valid == 0 && pendingSync != 0 && (ws->dStall ? VL_RANDOM_I_WIDTH(7) < 80 : 1) ){ + top->dBus_sync_valid = 1; + } + #endif + + } +}; +#endif + +#ifdef DBUS_CACHED_AVALON +#include <queue> + +struct DBusCachedAvalonTask{ + uint32_t data; + bool error; +}; + +class DBusCachedAvalon : public SimElement{ +public: + uint32_t beatCounter = 0; + queue<DBusCachedAvalonTask> rsps; + + Workspace *ws; + VVexRiscv* top; + DBusCachedAvalon(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + } + + virtual void onReset(){ + top->dBusAvalon_waitRequestn = 1; + top->dBusAvalon_readDataValid = 0; + } + + + virtual void preCycle(){ + if ((top->dBusAvalon_read || top->dBusAvalon_write) && top->dBusAvalon_waitRequestn) { + if(top->dBusAvalon_write){ + uint32_t size = __builtin_popcount(top->dBusAvalon_byteEnable); + uint32_t offset = ffs(top->dBusAvalon_byteEnable)-1; + bool error_next = false; + ws->dBusAccess(top->dBusAvalon_address + beatCounter * 4 + offset,1,size,((uint8_t*)&top->dBusAvalon_writeData)+offset,&error_next); + beatCounter++; + if(beatCounter == top->dBusAvalon_burstCount){ + beatCounter = 0; + } + } else { + for(int beat = 0;beat < top->dBusAvalon_burstCount;beat++){ + DBusCachedAvalonTask rsp; + ws->dBusAccess(top->dBusAvalon_address + beat * 4 ,0,4,((uint8_t*)&rsp.data),&rsp.error); + rsps.push(rsp); + } + } + } + } + + virtual void postCycle(){ + if(!rsps.empty() && (!ws->dStall || VL_RANDOM_I_WIDTH(7) < 100)){ + DBusCachedAvalonTask rsp = rsps.front(); + rsps.pop(); + top->dBusAvalon_response = rsp.error ? 3 : 0; + top->dBusAvalon_readData = rsp.data; + top->dBusAvalon_readDataValid = 1; + } else{ + top->dBusAvalon_readDataValid = 0; + top->dBusAvalon_readData = VL_RANDOM_I_WIDTH(32); + top->dBusAvalon_response = VL_RANDOM_I_WIDTH(2); //TODO + } + + top->dBusAvalon_waitRequestn = (ws->dStall ? VL_RANDOM_I_WIDTH(7) < 100 : 1); + } +}; +#endif + + +#ifdef DEBUG_PLUGIN +#include <stdio.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <string.h> +#include <arpa/inet.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <netinet/tcp.h> + +/** Returns true on success, or false if there was an error */ +bool SetSocketBlockingEnabled(int fd, bool blocking) +{ + if (fd < 0) return false; + +#ifdef WIN32 + unsigned long mode = blocking ? 0 : 1; + return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? true : false; +#else + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) return false; + flags = blocking ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK); + return (fcntl(fd, F_SETFL, flags) == 0) ? true : false; +#endif +} + +struct DebugPluginTask{ + bool wr; + uint32_t address; + uint32_t data; +}; + +class DebugPlugin : public SimElement{ +public: + Workspace *ws; + VVexRiscv* top; + + int serverSocket, clientHandle; + struct sockaddr_in serverAddr; + struct sockaddr_storage serverStorage; + socklen_t addr_size; + char buffer[1024]; + uint32_t timeSpacer = 0; + bool taskValid = false; + DebugPluginTask task; + + + DebugPlugin(Workspace* ws){ + this->ws = ws; + this->top = ws->top; + + #ifdef DEBUG_PLUGIN_EXTERNAL + ws->mTimeCmp = ~0; + #endif + top->debugReset = 0; + + + + //---- Create the socket. The three arguments are: ----// + // 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) // + serverSocket = socket(PF_INET, SOCK_STREAM, 0); + assert(serverSocket != -1); + SetSocketBlockingEnabled(serverSocket,0); + int flag = 1; + int result = setsockopt(serverSocket, /* socket affected */ + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (char *) &flag, /* the cast is historical + cruft */ + sizeof(int)); /* length of option value */ + + //---- Configure settings of the server address struct ----// + // Address family = Internet // + serverAddr.sin_family = AF_INET; + // Set port number, using htons function to use proper byte order // + serverAddr.sin_port = htons(7893); + // Set IP address to localhost // + serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + // Set all bits of the padding field to 0 // + memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); + + //---- Bind the address struct to the socket ----// + bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); + + //---- Listen on the socket, with 5 max connection requests queued ----// + listen(serverSocket,1); + + //---- Accept call creates a new socket for the incoming connection ----// + addr_size = sizeof serverStorage; + + clientHandle = -1; + } + + virtual ~DebugPlugin(){ + if(clientHandle != -1) { + shutdown(clientHandle,SHUT_RDWR); + usleep(100); + } + if(serverSocket != -1) { + close(serverSocket); + usleep(100); + } + } + + virtual void onReset(){ + top->debugReset = 1; + } + + + + virtual void postReset(){ + top->debugReset = 0; + } + + void connectionReset(){ + printf("CONNECTION RESET\n"); + shutdown(clientHandle,SHUT_RDWR); + clientHandle = -1; + } + + + virtual void preCycle(){ + + } + + virtual void postCycle(){ + top->reset = top->debug_resetOut; + if(timeSpacer == 0){ + if(clientHandle == -1){ + clientHandle = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size); + if(clientHandle != -1) + printf("CONNECTED\n"); + timeSpacer = 1000; + } + + + if(clientHandle != -1 && taskValid == false){ + int requiredSize = 1 + 1 + 4 + 4; + int n; + timeSpacer = 20; + if(ioctl(clientHandle,FIONREAD,&n) != 0){ + connectionReset(); + } else if(n >= requiredSize){ + if(requiredSize != read(clientHandle,buffer,requiredSize)){ + connectionReset(); + } else { + bool wr = buffer[0]; + uint32_t size = buffer[1]; + uint32_t address = *((uint32_t*)(buffer + 2)); + uint32_t data = *((uint32_t*)(buffer + 6)); + + if((address & ~ 0x4) == 0xF00F0000){ + assert(size == 2); + timeSpacer = 100; + + taskValid = true; + task.wr = wr; + task.address = address; + task.data = data; + } + } + } else { + int error = 0; + socklen_t len = sizeof (error); + int retval = getsockopt (clientHandle, SOL_SOCKET, SO_ERROR, &error, &len); + if (retval != 0 || error != 0) { + connectionReset(); + } + } + } + } else { + timeSpacer--; + } + } + + void sendRsp(uint32_t data){ + if(clientHandle != -1){ + if(send(clientHandle,&data,4,0) == -1) connectionReset(); + } + } +}; +#endif + +#ifdef DEBUG_PLUGIN_STD +class DebugPluginStd : public DebugPlugin{ +public: + DebugPluginStd(Workspace* ws) : DebugPlugin(ws){ + + } + + virtual void onReset(){ + DebugPlugin::onReset(); + top->debug_bus_cmd_valid = 0; + } + + bool rspFire = false; + + virtual void preCycle(){ + DebugPlugin::preCycle(); + + if(rspFire){ + sendRsp(top->debug_bus_rsp_data); + rspFire = false; + } + + if(top->debug_bus_cmd_valid && top->debug_bus_cmd_ready){ + taskValid = false; + if(!top->debug_bus_cmd_payload_wr){ + rspFire = true; + } + } + } + + virtual void postCycle(){ + DebugPlugin::postCycle(); + + if(taskValid){ + top->debug_bus_cmd_valid = 1; + top->debug_bus_cmd_payload_wr = task.wr; + top->debug_bus_cmd_payload_address = task.address; + top->debug_bus_cmd_payload_data = task.data; + }else { + top->debug_bus_cmd_valid = 0; + top->debug_bus_cmd_payload_wr = VL_RANDOM_I_WIDTH(1); + top->debug_bus_cmd_payload_address = VL_RANDOM_I_WIDTH(8); + top->debug_bus_cmd_payload_data = VL_RANDOM_I_WIDTH(32); + } + } +}; + +#endif + +#ifdef DEBUG_PLUGIN_AVALON +class DebugPluginAvalon : public DebugPlugin{ +public: + DebugPluginAvalon(Workspace* ws) : DebugPlugin(ws){ + + } + + virtual void onReset(){ + DebugPlugin::onReset(); + top->debugBusAvalon_read = 0; + top->debugBusAvalon_write = 0; + } + + bool rspFire = false; + + virtual void preCycle(){ + DebugPlugin::preCycle(); + + if(rspFire){ + sendRsp(top->debugBusAvalon_readData); + rspFire = false; + } + + if((top->debugBusAvalon_read || top->debugBusAvalon_write) && top->debugBusAvalon_waitRequestn){ + taskValid = false; + if(top->debugBusAvalon_read){ + rspFire = true; + } + } + } + + virtual void postCycle(){ + DebugPlugin::postCycle(); + + if(taskValid){ + top->debugBusAvalon_write = task.wr; + top->debugBusAvalon_read = !task.wr; + top->debugBusAvalon_address = task.address; + top->debugBusAvalon_writeData = task.data; + }else { + top->debugBusAvalon_write = 0; + top->debugBusAvalon_read = 0; + top->debugBusAvalon_address = VL_RANDOM_I_WIDTH(8); + top->debugBusAvalon_writeData = VL_RANDOM_I_WIDTH(32); + } + } +}; + +#endif + +void Workspace::fillSimELements(){ + #ifdef IBUS_SIMPLE + simElements.push_back(new IBusSimple(this)); + #endif + #ifdef IBUS_SIMPLE_AVALON + simElements.push_back(new IBusSimpleAvalon(this)); + #endif + #ifdef IBUS_SIMPLE_AHBLITE3 + simElements.push_back(new IBusSimpleAhbLite3(this)); + #endif + + + #ifdef IBUS_CACHED + simElements.push_back(new IBusCached(this)); + #endif + #ifdef IBUS_CACHED_AVALON + simElements.push_back(new IBusCachedAvalon(this)); + #endif + #if defined(IBUS_CACHED_WISHBONE) || defined(IBUS_SIMPLE_WISHBONE) + simElements.push_back(new IBusCachedWishbone(this)); + #endif + + #ifdef IBUS_TC + simElements.push_back(new IBusTc(this)); + #endif + + #ifdef DBUS_SIMPLE + simElements.push_back(new DBusSimple(this)); + #endif + #ifdef DBUS_SIMPLE_AVALON + simElements.push_back(new DBusSimpleAvalon(this)); + #endif + #ifdef DBUS_SIMPLE_AHBLITE3 + simElements.push_back(new DBusSimpleAhbLite3(this)); + #endif + #ifdef DBUS_CACHED + simElements.push_back(new DBusCached(this)); + #endif + #ifdef DBUS_CACHED_AVALON + simElements.push_back(new DBusCachedAvalon(this)); + #endif + #if defined(DBUS_CACHED_WISHBONE) || defined(DBUS_SIMPLE_WISHBONE) + simElements.push_back(new DBusCachedWishbone(this)); + #endif + #ifdef DEBUG_PLUGIN_STD + simElements.push_back(new DebugPluginStd(this)); + #endif + #ifdef DEBUG_PLUGIN_AVALON + simElements.push_back(new DebugPluginAvalon(this)); + #endif +} + +mutex Workspace::staticMutex; +uint64_t Workspace::cycles = 0; +uint32_t Workspace::testsCounter = 0, Workspace::successCounter = 0; + +#ifndef REF +#define testA1ReagFileWriteRef {1,10},{2,20},{3,40},{4,60} +#define testA2ReagFileWriteRef {5,1},{7,3} +uint32_t regFileWriteRefArray[][2] = { + testA1ReagFileWriteRef, + testA1ReagFileWriteRef, + testA2ReagFileWriteRef, + testA2ReagFileWriteRef +}; + +class TestA : public WorkspaceRegression{ +public: + + + uint32_t regFileWriteRefIndex = 0; + + TestA() : WorkspaceRegression("testA") { + loadHex(string(REGRESSION_PATH) + "../../resources/hex/testA.hex"); + } + + virtual void checks(){ + if(top->VexRiscv->lastStageRegFileWrite_valid == 1 && top->VexRiscv->lastStageRegFileWrite_payload_address != 0){ + assertEq(top->VexRiscv->lastStageRegFileWrite_payload_address, regFileWriteRefArray[regFileWriteRefIndex][0]); + assertEq(top->VexRiscv->lastStageRegFileWrite_payload_data, regFileWriteRefArray[regFileWriteRefIndex][1]); + //printf("%d\n",i); + + regFileWriteRefIndex++; + if(regFileWriteRefIndex == sizeof(regFileWriteRefArray)/sizeof(regFileWriteRefArray[0])){ + pass(); + } + } + } +}; + +class TestX28 : public WorkspaceRegression{ +public: + uint32_t refIndex = 0; + uint32_t *ref; + uint32_t refSize; + + TestX28(string name, uint32_t *ref, uint32_t refSize) : WorkspaceRegression(name) { + this->ref = ref; + this->refSize = refSize; + loadHex(string(REGRESSION_PATH) + "../../resources/hex/" + name + ".hex"); + } + + virtual void checks(){ + if(top->VexRiscv->lastStageRegFileWrite_valid == 1 && top->VexRiscv->lastStageRegFileWrite_payload_address == 28){ + assertEq(top->VexRiscv->lastStageRegFileWrite_payload_data, ref[refIndex]); + //printf("%d\n",i); + + refIndex++; + if(refIndex == refSize){ + pass(); + } + } + } +}; + + +class RiscvTest : public WorkspaceRegression{ +public: + RiscvTest(string name) : WorkspaceRegression(name) { + loadHex(string(REGRESSION_PATH) + "../../resources/hex/" + name + ".hex"); + bootAt(0x800000bcu); + } + + virtual void postReset() { +// #ifdef CSR +// top->VexRiscv->prefetch_PcManagerSimplePlugin_pcReg = 0x80000000u; +// #else +// #endif + } + + virtual void checks(){ + if(top->VexRiscv->lastStageIsFiring && top->VexRiscv->lastStageInstruction == 0x00000013){ + uint32_t instruction; + bool error; + Workspace::mem.read(top->VexRiscv->lastStagePc, 4, (uint8_t*)&instruction); + //printf("%x => %x\n", top->VexRiscv->lastStagePc, instruction ); + if(instruction == 0x00000073){ + uint32_t code = top->VexRiscv->RegFilePlugin_regFile[28]; + uint32_t code2 = top->VexRiscv->RegFilePlugin_regFile[3]; + if((code & 1) == 0 && (code2 & 1) == 0){ + cout << "Wrong error code"<< endl; + fail(); + } + if(code == 1 || code2 == 1){ + pass(); + }else{ + cout << "Error code " << code2/2 << endl; + fail(); + } + } + } + } + + virtual void iBusAccess(uint32_t addr, uint32_t *data, bool *error){ + WorkspaceRegression::iBusAccess(addr,data,error); + if(*data == 0x0ff0000f) *data = 0x00000013; + if(*data == 0x00000073) *data = 0x00000013; + } +}; +#endif +class Dhrystone : public WorkspaceRegression{ +public: + string hexName; + Dhrystone(string name,string hexName,bool iStall, bool dStall) : WorkspaceRegression(name) { + setIStall(iStall); + setDStall(dStall); + withRiscvRef(); + loadHex(string(REGRESSION_PATH) + "../../resources/hex/" + hexName + ".hex"); + this->hexName = hexName; + } + + virtual void checks(){ + + } + + virtual void pass(){ + FILE *refFile = fopen((hexName + ".logRef").c_str(), "r"); + fseek(refFile, 0, SEEK_END); + uint32_t refSize = ftell(refFile); + fseek(refFile, 0, SEEK_SET); + char* ref = new char[refSize]; + fread(ref, 1, refSize, refFile); + fclose(refFile); + + + logTraces.flush(); + logTraces.close(); + + FILE *logFile = fopen((name + ".logTrace").c_str(), "r"); + fseek(logFile, 0, SEEK_END); + uint32_t logSize = ftell(logFile); + fseek(logFile, 0, SEEK_SET); + char* log = new char[logSize]; + fread(log, 1, logSize, logFile); + fclose(logFile); + + if(refSize > logSize || memcmp(log,ref,refSize)) + fail(); + else + Workspace::pass(); + } +}; + +class Compliance : public WorkspaceRegression{ +public: + string name; + ofstream out32; + int out32Counter = 0; + Compliance(string name) : WorkspaceRegression(name) { + withRiscvRef(); + loadHex(string(REGRESSION_PATH) + "../../resources/hex/" + name + ".elf.hex"); + out32.open (name + ".out32"); + this->name = name; + } + + + virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size, uint8_t *dataBytes, bool *error) { + if(wr && addr == 0xF00FFF2C){ + uint32_t *data = (uint32_t*)dataBytes; + out32 << hex << setw(8) << std::setfill('0') << *data << dec; + if(++out32Counter % 4 == 0) out32 << "\n"; + } + WorkspaceRegression::dBusAccess(addr,wr,size,dataBytes,error); + } + + virtual void checks(){ + + } + + + + virtual void pass(){ + FILE *refFile = fopen((string(REGRESSION_PATH) + string("../../resources/ref/") + name + ".reference_output").c_str(), "r"); + fseek(refFile, 0, SEEK_END); + uint32_t refSize = ftell(refFile); + fseek(refFile, 0, SEEK_SET); + char* ref = new char[refSize]; + fread(ref, 1, refSize, refFile); + fclose(refFile); + + + out32.flush(); + out32.close(); + + FILE *logFile = fopen((name + ".out32").c_str(), "r"); + fseek(logFile, 0, SEEK_END); + uint32_t logSize = ftell(logFile); + fseek(logFile, 0, SEEK_SET); + char* log = new char[logSize]; + fread(log, 1, logSize, logFile); + fclose(logFile); + + if(refSize > logSize || memcmp(log,ref,refSize)) + fail(); + else + Workspace::pass(); + } +}; + + +#ifdef DEBUG_PLUGIN + +#include<pthread.h> +#include<stdlib.h> +#include<unistd.h> +#include <netinet/tcp.h> + +#define RISCV_SPINAL_FLAGS_RESET 1<<0 +#define RISCV_SPINAL_FLAGS_HALT 1<<1 +#define RISCV_SPINAL_FLAGS_PIP_BUSY 1<<2 +#define RISCV_SPINAL_FLAGS_IS_IN_BREAKPOINT 1<<3 +#define RISCV_SPINAL_FLAGS_STEP 1<<4 +#define RISCV_SPINAL_FLAGS_PC_INC 1<<5 + +#define RISCV_SPINAL_FLAGS_RESET_SET 1<<16 +#define RISCV_SPINAL_FLAGS_HALT_SET 1<<17 + +#define RISCV_SPINAL_FLAGS_RESET_CLEAR 1<<24 +#define RISCV_SPINAL_FLAGS_HALT_CLEAR 1<<25 + +class DebugPluginTest : public WorkspaceRegression{ +public: + pthread_t clientThreadId; + char buffer[1024]; + bool clientSuccess = false, clientFail = false; + + static void* clientThreadWrapper(void *debugModule){ + ((DebugPluginTest*)debugModule)->clientThread(); + return NULL; + } + + int clientSocket; + void accessCmd(bool wr, uint32_t size, uint32_t address, uint32_t data){ + buffer[0] = wr; + buffer[1] = size; + *((uint32_t*) (buffer + 2)) = address; + *((uint32_t*) (buffer + 6)) = data; + send(clientSocket,buffer,10,0); + } + + void writeCmd(uint32_t size, uint32_t address, uint32_t data){ + accessCmd(true, 2, address, data); + } + + + uint32_t readCmd(uint32_t size, uint32_t address){ + accessCmd(false, 2, address, VL_RANDOM_I_WIDTH(32)); + int error; + if((error = recv(clientSocket, buffer, 4, 0)) != 4){ + printf("Should read 4 bytes, had %d", error); + while(1); + } + + return *((uint32_t*) buffer); + } + + + + void clientThread(){ + struct sockaddr_in serverAddr; + + //---- Create the socket. The three arguments are: ----// + // 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) // + clientSocket = socket(PF_INET, SOCK_STREAM, 0); + int flag = 1; + int result = setsockopt(clientSocket, /* socket affected */ + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (char *) &flag, /* the cast is historical + cruft */ + sizeof(int)); /* length of option value */ + + //---- Configure settings of the server address struct ----// + // Address family = Internet // + serverAddr.sin_family = AF_INET; + // Set port number, using htons function to use proper byte order // + serverAddr.sin_port = htons(7893); + // Set IP address to localhost // + serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + // Set all bits of the padding field to 0 // + memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); + + //---- Connect the socket to the server using the address struct ----// + socklen_t addr_size = sizeof serverAddr; + int error = connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); +// printf("!! %x\n",readCmd(2,0x8)); + uint32_t debugAddress = 0xF00F0000; + uint32_t readValue; + + while(resetDone != true){usleep(100);} + + while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);} + if((readValue = readCmd(2,debugAddress + 4)) != 0x8000000C){ + printf("wrong breakA PC %x\n",readValue); + clientFail = true; return; + } + + writeCmd(2, debugAddress + 4, 0x13 + (1 << 15)); //Read regfile + if((readValue = readCmd(2,debugAddress + 4)) != 10){ + printf("wrong breakB PC %x\n",readValue); + clientFail = true; return; + } + + writeCmd(2, debugAddress + 4, 0x13 + (2 << 15)); //Read regfile + if((readValue = readCmd(2,debugAddress + 4)) != 20){ + printf("wrong breakC PC %x\n",readValue); + clientFail = true; return; + } + + writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read regfile + if((readValue = readCmd(2,debugAddress + 4)) != 30){ + printf("wrong breakD PC %x\n",readValue); + clientFail = true; return; + } + + writeCmd(2, debugAddress + 4, 0x13 + (1 << 7) + (40 << 20)); //Write x1 with 40 + writeCmd(2, debugAddress + 4, 0x80000eb7); //Write x29 with 0x10 + writeCmd(2, debugAddress + 4, 0x010e8e93); //Write x29 with 0x10 + writeCmd(2, debugAddress + 4, 0x67 + (29 << 15)); //Branch x29 + writeCmd(2, debugAddress + 0, RISCV_SPINAL_FLAGS_HALT_CLEAR); //Run CPU + + while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);} + if((readValue = readCmd(2,debugAddress + 4)) != 0x80000014){ + printf("wrong breakE PC 3 %x\n",readValue); + clientFail = true; return; + } + + + writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read regfile + if((readValue = readCmd(2,debugAddress + 4)) != 60){ + printf("wrong x1 %x\n",readValue); + clientFail = true; return; + } + + + writeCmd(2, debugAddress + 4, 0x80000eb7); //Write x29 with 0x10 + writeCmd(2, debugAddress + 4, 0x018e8e93); //Write x29 with 0x10 + writeCmd(2, debugAddress + 4, 0x67 + (29 << 15)); //Branch x29 + writeCmd(2, debugAddress + 0, RISCV_SPINAL_FLAGS_HALT_CLEAR); //Run CPU + + + + while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);} + if((readValue = readCmd(2,debugAddress + 4)) != 0x80000024){ + printf("wrong breakF PC 3 %x\n",readValue); + clientFail = true; return; + } + + + writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read x3 + if((readValue = readCmd(2,debugAddress + 4)) != 171){ + printf("wrong x3 %x\n",readValue); + clientFail = true; return; + } + + + clientSuccess = true; + } + + + DebugPluginTest() : WorkspaceRegression("DebugPluginTest") { + loadHex(string(REGRESSION_PATH) + "../../resources/hex/debugPlugin.hex"); + pthread_create(&clientThreadId, NULL, &clientThreadWrapper, this); + } + + virtual ~DebugPluginTest(){ + if(clientSocket != -1) close(clientSocket); + } + + virtual void checks(){ + if(clientSuccess) pass(); + if(clientFail) fail(); + } + + virtual void postReset(){ + Workspace::postReset(); + top->VexRiscv->DebugPlugin_debugUsed = 1; + } +}; + +#endif + + +//#ifdef LITEX +//class LitexSoC : public Workspace{ +//public: +// +// LitexSoC(string name) : Workspace(name) { +// +// } +// virtual bool isDBusCheckedRegion(uint32_t address){ return true;} +// virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xB0000000 || (addr & 0xE0000000) == 0xE0000000;} +// virtual bool isMmuRegion(uint32_t addr) { return (addr & 0xFF000000) != 0x81000000;} +// +// virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { +// if(isPerifRegion(addr)) switch(addr){ +// //TODO Emulate peripherals here +// case 0xFFFFFFE0: if(wr) fail(); else *data = mTime; break; +// case 0xFFFFFFE4: if(wr) fail(); else *data = mTime >> 32; break; +// case 0xFFFFFFE8: if(wr) mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data; else *data = mTimeCmp; break; +// case 0xFFFFFFEC: if(wr) mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); else *data = mTimeCmp >> 32; break; +// case 0xFFFFFFF8: +// if(wr){ +// cout << (char)*data; +// logTraces << (char)*data; +// logTraces.flush(); +// } else fail(); +// break; +// case 0xFFFFFFFC: fail(); break; //Simulation end +// default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " mask=0x" << mask << " data=0x" << data << dec << endl; fail(); break; +// } +// +// Workspace::dBusAccess(addr,wr,size,mask,data,error); +// } +//}; +//#endif + + + +#include <unistd.h> +#include <termios.h> +#include <fcntl.h> +termios stdinRestoreSettings; +void stdinNonBuffered(){ + static struct termios old, new1; + tcgetattr(STDIN_FILENO, &old); // grab old terminal i/o settings + new1 = old; // make new settings same as old settings + new1.c_lflag &= ~ICANON; // disable buffered i/o + new1.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &new1); // use these new terminal i/o settings now + setvbuf(stdin, NULL, _IONBF, 0); + stdinRestoreSettings = old; +} + + +bool stdinNonEmpty(){ + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return (FD_ISSET(0, &fds)); +} + + +void stdoutNonBuffered(){ + setvbuf(stdout, NULL, _IONBF, 0); +} + +void stdinRestore(){ + tcsetattr(STDIN_FILENO, TCSANOW, &stdinRestoreSettings); +} + + + +void my_handler(int s){ + printf("Caught signal %d\n",s); + stdinRestore(); + exit(1); +} +#include <signal.h> + +void captureCtrlC(){ + struct sigaction sigIntHandler; + + sigIntHandler.sa_handler = my_handler; + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + + sigaction(SIGINT, &sigIntHandler, NULL); +} + + + + +#if defined(LINUX_SOC) || defined(LINUX_REGRESSION) +#include <queue> +class LinuxSoc : public Workspace{ +public: + queue <char> customCin; + void pushCin(string m){ + for(char& c : m) { + customCin.push(c); + } + } + + LinuxSoc(string name) : Workspace(name) { + #ifdef WITH_USER_IO + stdinNonBuffered(); + captureCtrlC(); + #endif + stdoutNonBuffered(); + } + + virtual ~LinuxSoc(){ + #ifdef WITH_USER_IO + stdinRestore(); + #endif + } + virtual bool isDBusCheckedRegion(uint32_t address){ return true;} + virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xF0000000 || (addr & 0xE0000000) == 0xE0000000;} + virtual bool isMmuRegion(uint32_t addr) { return true; } + + + + virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint8_t *dataBytes, bool *error) { + uint32_t *data = (uint32_t*)dataBytes; + + if(isPerifRegion(addr)) { + switch(addr){ + case 0xFFFFFFE0: if(wr) fail(); else *data = mTime; break; + case 0xFFFFFFE4: if(wr) fail(); else *data = mTime >> 32; break; + case 0xFFFFFFE8: if(wr) mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data; else *data = mTimeCmp; break; + case 0xFFFFFFEC: if(wr) mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); else *data = mTimeCmp >> 32; break; + case 0xFFFFFFF8: + if(wr){ + char c = (char)*data; + cout << c; + logTraces << c; + logTraces.flush(); + onStdout(c); + } else { + #ifdef WITH_USER_IO + if(stdinNonEmpty()){ + char c; + read(0, &c, 1); + *data = c; + } else + #endif + if(!customCin.empty()){ + *data = customCin.front(); + customCin.pop(); + } else { + *data = -1; + } + } + break; + case 0xFFFFFFFC: fail(); break; //Simulation end + default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " mask=0x" << " data=0x" << data << dec << endl; fail(); break; + } + } + Workspace::dBusAccess(addr,wr,size,dataBytes,error); + } + + virtual void onStdout(char c){ + + } +}; + +class LinuxRegression: public LinuxSoc{ +public: + string pendingLine = ""; + bool pendingLineContain(string m) { + return strstr(pendingLine.c_str(), m.c_str()) != NULL; + } + + enum State{LOGIN, ECHO_FILE, HEXDUMP, HEXDUMP_CHECK, PASS}; + State state = LOGIN; + LinuxRegression(string name) : LinuxSoc(name) { + + } + + ~LinuxRegression() { + } + + + virtual void onStdout(char c){ + pendingLine += c; + switch(state){ + case LOGIN: if (pendingLineContain("buildroot login:")) { pushCin("root\n"); state = ECHO_FILE; } break; + case ECHO_FILE: if (pendingLineContain("# ")) { pushCin("echo \"miaou\" > test.txt\n"); state = HEXDUMP; pendingLine = "";} break; + case HEXDUMP: if (pendingLineContain("# ")) { pushCin("hexdump -C test.txt\n"); state = HEXDUMP_CHECK; pendingLine = "";} break; + case HEXDUMP_CHECK: if (pendingLineContain("00000000 6d 69 61 6f 75 0a ")) { pushCin(""); state = PASS; pendingLine = "";} break; + case PASS: if (pendingLineContain("# ")) { pass(); } break; + } + if(c == '\n' || pendingLine.length() > 200) pendingLine = ""; + } +}; + +#endif + +#ifdef LINUX_SOC_SMP + +class LinuxSocSmp : public Workspace{ +public: + queue <char> customCin; + void pushCin(string m){ + for(char& c : m) { + customCin.push(c); + } + } + + LinuxSocSmp(string name) : Workspace(name) { + #ifdef WITH_USER_IO + stdinNonBuffered(); + captureCtrlC(); + #endif + stdoutNonBuffered(); + } + + virtual ~LinuxSocSmp(){ + #ifdef WITH_USER_IO + stdinRestore(); + #endif + } + virtual bool isDBusCheckedRegion(uint32_t address){ return true;} + virtual bool isPerifRegion(uint32_t addr) { return (addr & 0xF0000000) == 0xF0000000;} + virtual bool isMmuRegion(uint32_t addr) { return true; } + + + + virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size, uint8_t *dataBytes, bool *error) { + uint32_t *data = (uint32_t*)dataBytes; + if(isPerifRegion(addr)) switch(addr){ + case 0xF0010000: if(wr && *data != 0) fail(); else *data = 0; break; + case 0xF001BFF8: if(wr) fail(); else *data = mTime; break; + case 0xF001BFFC: if(wr) fail(); else *data = mTime >> 32; break; + case 0xF0014000: if(wr) mTimeCmp = (mTimeCmp & 0xFFFFFFFF00000000) | *data; else fail(); break; + case 0xF0014004: if(wr) mTimeCmp = (mTimeCmp & 0x00000000FFFFFFFF) | (((uint64_t)*data) << 32); else fail(); break; + case 0xF0000000: + if(wr){ + char c = (char)*data; + cout << c; + logTraces << c; + logTraces.flush(); + onStdout(c); + } + case 0xF0000004: + if(!wr){ + #ifdef WITH_USER_IO + if(stdinNonEmpty()){ + char c; + read(0, &c, 1); + *data = c; + } else + #endif + if(!customCin.empty()){ + *data = customCin.front(); + customCin.pop(); + } else { + *data = -1; + } + } + break; + default: cout << "Unmapped peripheral access : addr=0x" << hex << addr << " wr=" << wr << " data=0x" << data << dec << endl; fail(); break; + } + Workspace::dBusAccess(addr,wr,size,dataBytes,error); + } + + virtual void onStdout(char c){ + + } +}; + +#endif + +string riscvTestMain[] = { + //"rv32ui-p-simple", + "rv32ui-p-lui", + "rv32ui-p-auipc", + "rv32ui-p-jal", + "rv32ui-p-jalr", + "rv32ui-p-beq", + "rv32ui-p-bge", + "rv32ui-p-bgeu", + "rv32ui-p-blt", + "rv32ui-p-bltu", + "rv32ui-p-bne", + "rv32ui-p-add", + "rv32ui-p-addi", + "rv32ui-p-and", + "rv32ui-p-andi", + "rv32ui-p-or", + "rv32ui-p-ori", + "rv32ui-p-sll", + "rv32ui-p-slli", + "rv32ui-p-slt", + "rv32ui-p-slti", + "rv32ui-p-sra", + "rv32ui-p-srai", + "rv32ui-p-srl", + "rv32ui-p-srli", + "rv32ui-p-sub", + "rv32ui-p-xor", + "rv32ui-p-xori" +}; + +string riscvTestMemory[] = { + "rv32ui-p-lb", + "rv32ui-p-lbu", + "rv32ui-p-lh", + "rv32ui-p-lhu", + "rv32ui-p-lw", + "rv32ui-p-sb", + "rv32ui-p-sh", + "rv32ui-p-sw" +}; + + +string riscvTestFloat[] = { + "rv32uf-p-fmadd", + "rv32uf-p-fadd", + "rv32uf-p-fcmp", + "rv32uf-p-fcvt_w", + "rv32uf-p-ldst", + "rv32uf-p-recoding", + "rv32uf-p-fclass", + "rv32uf-p-fcvt", + "rv32uf-p-fdiv", + "rv32uf-p-fmin", + "rv32uf-p-move" +}; + + +string riscvTestDouble[] = { + "rv32ud-p-fmadd", + "rv32ud-p-fadd", + "rv32ud-p-fcvt", + "rv32ud-p-recoding", + "rv32ud-p-fclass", + "rv32ud-p-fcvt_w", + "rv32ud-p-fmin", + "rv32ud-p-fcmp", + "rv32ud-p-fdiv", + "rv32ud-p-ldst" +}; + + + + +string riscvTestMul[] = { + "rv32um-p-mul", + "rv32um-p-mulh", + "rv32um-p-mulhsu", + "rv32um-p-mulhu" +}; + +string riscvTestDiv[] = { + "rv32um-p-div", + "rv32um-p-divu", + "rv32um-p-rem", + "rv32um-p-remu" +}; + +string freeRtosTests[] = { +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1", +// "test1","test1","test1","test1","test1","test1","test1","test1" + + "AltQTest", "AltBlock", "AltPollQ", "blocktim", "countsem", "dead", "EventGroupsDemo", "flop", "integer", "QPeek", + "QueueSet", "recmutex", "semtest", "TaskNotify", "crhook", "dynamic", + "GenQTest", "PollQ", "QueueOverwrite", "QueueSetPolling", "sp_flop", "test1" + //"BlockQ","BlockQ","BlockQ","BlockQ","BlockQ","BlockQ","BlockQ","BlockQ" +// "flop" +// "flop", "sp_flop" // <- Simple test + // "AltBlckQ" ??? + +}; + + +string zephyrTests[] = { + "tests_kernel_stack_stack_api", + "tests_kernel_context", +// "tests_kernel_critical", //Too long + "tests_kernel_fifo_fifo_api", + "tests_kernel_mbox_mbox_usage", +// "tests_kernel_mem_pool_mem_pool_threadsafe", //Too long + "tests_kernel_sleep" +// "tests_kernel_timer_timer_api" //Lock like if the CPU is too slow, it will make it fail +}; + + + +string riscvComplianceMain[] = { + "I-IO", + "I-NOP-01", + "I-LUI-01", + "I-ADD-01", + "I-ADDI-01", + "I-AND-01", + "I-ANDI-01", + "I-SUB-01", + "I-OR-01", + "I-ORI-01", + "I-XOR-01", + "I-XORI-01", + "I-SRA-01", + "I-SRAI-01", + "I-SRL-01", + "I-SRLI-01", + "I-SLL-01", + "I-SLLI-01", + "I-SLT-01", + "I-SLTI-01", + "I-SLTIU-01", + "I-SLTU-01", + "I-AUIPC-01", + "I-BEQ-01", + "I-BGE-01", + "I-BGEU-01", + "I-BLT-01", + "I-BLTU-01", + "I-BNE-01", + "I-JAL-01", + "I-JALR-01", + "I-DELAY_SLOTS-01", + "I-ENDIANESS-01", + "I-RF_size-01", + "I-RF_width-01", + "I-RF_x0-01", +}; + + + +string complianceTestMemory[] = { + "I-LB-01", + "I-LBU-01", + "I-LH-01", + "I-LHU-01", + "I-LW-01", + "I-SB-01", + "I-SH-01", + "I-SW-01" +}; + + +string complianceTestCsr[] = { + "I-CSRRC-01", + "I-CSRRCI-01", + "I-CSRRS-01", + "I-CSRRSI-01", + "I-CSRRW-01", + "I-CSRRWI-01", + #ifndef COMPRESSED + "I-MISALIGN_JMP-01", //Only apply for non RVC cores + #endif + "I-MISALIGN_LDST-01", + "I-ECALL-01", +}; + + +string complianceTestMul[] = { + "MUL", + "MULH", + "MULHSU", + "MULHU", +}; + +string complianceTestDiv[] = { + "DIV", + "DIVU", + "REM", + "REMU", +}; + + +string complianceTestC[] = { + "C.ADD", + "C.ADDI16SP", + "C.ADDI4SPN", + "C.ADDI", + "C.AND", + "C.ANDI", + "C.BEQZ", + "C.BNEZ", + "C.JAL", + "C.JALR", + "C.J", + "C.JR", + "C.LI", + "C.LUI", + "C.LW", + "C.LWSP", + "C.MV", + "C.OR", + "C.SLLI", + "C.SRAI", + "C.SRLI", + "C.SUB", + "C.SW", + "C.SWSP", + "C.XOR", +}; + + + + + + +struct timespec timer_start(){ + struct timespec start_time; + clock_gettime(CLOCK_REALTIME, &start_time); //CLOCK_PROCESS_CPUTIME_ID + return start_time; +} + +long timer_end(struct timespec start_time){ + struct timespec end_time; + clock_gettime(CLOCK_REALTIME, &end_time); + uint64_t diffInNanos = end_time.tv_sec*1e9 + end_time.tv_nsec - start_time.tv_sec*1e9 - start_time.tv_nsec; + return diffInNanos; +} + +#define redo(count,that) for(uint32_t xxx = 0;xxx < count;xxx++) that +#include <pthread.h> +#include <queue> +#include <functional> +#include <thread> + + +static void multiThreading(queue<std::function<void()>> *lambdas, std::mutex *mutex){ + uint32_t counter = 0; + while(true){ + mutex->lock(); + if(lambdas->empty()){ + mutex->unlock(); + break; + } + + #ifdef SEED + uint32_t seed = SEED + counter; + counter++; + srand48(seed); + printf("MT_SEED=%d \n", seed); + #endif + std::function<void()> lambda = lambdas->front(); + lambdas->pop(); + mutex->unlock(); + + lambda(); + } +} + + +static void multiThreadedExecute(queue<std::function<void()>> &lambdas){ + std::mutex mutex; + if(THREAD_COUNT == 1){ + multiThreading(&lambdas, &mutex); + } else { + std::thread * t[THREAD_COUNT]; + for(int id = 0;id < THREAD_COUNT;id++){ + t[id] = new thread(multiThreading,&lambdas,&mutex); + } + for(int id = 0;id < THREAD_COUNT;id++){ + t[id]->join(); + delete t[id]; + } + } +} + +int main(int argc, char **argv, char **env) { + #ifdef SEED + srand48(SEED); + #endif + Verilated::randReset(2); + Verilated::commandArgs(argc, argv); + + printf("BOOT\n"); + timespec startedAt = timer_start(); + + +#ifdef LINUX_SOC_SMP + { + + LinuxSocSmp soc("linuxSmp"); + #ifndef DEBUG_PLUGIN_EXTERNAL + soc.withRiscvRef(); + soc.loadBin(EMULATOR, 0x80000000); + soc.loadBin(VMLINUX, 0x80400000); + soc.loadBin(DTB, 0x80FF0000); + soc.loadBin(RAMDISK, 0x81000000); + #endif + //soc.setIStall(true); + //soc.setDStall(true); + soc.bootAt(0x80000000); + soc.run(0); +// soc.run((496300000l + 2000000) / 2); +// soc.run(438700000l/2); + return -1; + } +#endif + + + + #ifdef RVF + for(const string &name : riscvTestFloat){ + redo(REDO,RiscvTest(name).withRiscvRef()->bootAt(0x80000188u)->writeWord(0x80000184u, 0x00305073)->run();) + } + #endif + #ifdef RVD + for(const string &name : riscvTestDouble){ + redo(REDO,RiscvTest(name).withRiscvRef()->bootAt(0x80000188u)->writeWord(0x80000184u, 0x00305073)->run();) + } + #endif + //return 0; + +//#ifdef LITEX +// LitexSoC("linux") +// .withRiscvRef() +// ->loadBin(EMULATOR, 0x80000000) +// ->loadBin(DTB, 0x81000000) +// ->loadBin(VMLINUX, 0xc0000000) +// ->loadBin(RAMDISK, 0xc2000000) +// ->setIStall(false) //TODO It currently improve speed but should be removed later +// ->setDStall(false) +// ->bootAt(0x80000000) +// ->run(0); +//#endif + +// { +// static struct termios old, new1; +// tcgetattr(0, &old); /* grab old terminal i/o settings */ +// new1 = old; /* make new settings same as old settings */ +// new1.c_lflag &= ~ICANON; /* disable buffered i/o */ +// new1.c_lflag &= ~ECHO; +// tcsetattr(0, TCSANOW, &new1); /* use these new terminal i/o settings now */ +// } +// +// std::string initialCommand; +// +// while(true){ +// if(!inputAvailable()) { +// std::cout << "Waiting for input (Ctrl-C to cancel)..." << std::endl; +// sleep(1); +// } else { +// char c; +// read(0, &c, 1); printf("%d\n", c); +//// std::getline(std::cin, initialCommand); +// } +// } +// + +// char c; +// while (1) { read(0, &c, 1); printf("%d\n", c); } +// while(true){ +// char c = getchar(); +// if(c > 0) +// { +// putchar(c); +// } else { +// putchar('*'); +// sleep(500); +// } +// } + +#ifdef LINUX_SOC + { + + LinuxSoc soc("linux"); + #ifndef DEBUG_PLUGIN_EXTERNAL + soc.withRiscvRef(); + soc.loadBin(EMULATOR, 0x80000000); + soc.loadBin(VMLINUX, 0xC0000000); + soc.loadBin(DTB, 0xC3000000); + soc.loadBin(RAMDISK, 0xC2000000); + #endif + //soc.setIStall(true); + //soc.setDStall(true); + soc.bootAt(0x80000000); + soc.run(0); +// soc.run((496300000l + 2000000) / 2); +// soc.run(438700000l/2); + return -1; + } +#endif + + + + + +// #ifdef MMU +// redo(REDO,WorkspaceRegression("mmu").withRiscvRef()->loadHex("../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3);); +// #endif +// redo(REDO,WorkspaceRegression("deleg").withRiscvRef()->loadHex("../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3);); +// return 0; + + + for(int idx = 0;idx < 1;idx++){ + + #if defined(DEBUG_PLUGIN_EXTERNAL) || defined(RUN_HEX) + { + WorkspaceRegression w("run"); + #ifdef RUN_HEX + //w.loadHex("/home/spinalvm/hdl/zephyr/zephyrSpinalHdl/samples/synchronization/build/zephyr/zephyr.hex"); + w.loadHex(RUN_HEX); + w.withRiscvRef(); + #endif + w.setIStall(false); + w.setDStall(false); + + #if defined(TRACE) || defined(TRACE_ACCESS) + //w.setCyclesPerSecond(5e3); + //printf("Speed reduced 5Khz\n"); + #endif + w.run(0xFFFFFFFFFFFF); + exit(0); + } + #endif + + + #ifdef ISA_TEST + + // redo(REDO,TestA().run();) + for(const string &name : riscvComplianceMain){ + redo(REDO, Compliance(name).run();) + } + for(const string &name : complianceTestMemory){ + redo(REDO, Compliance(name).run();) + } + + #ifdef COMPRESSED + for(const string &name : complianceTestC){ + redo(REDO, Compliance(name).run();) + } + #endif + + #ifdef MUL + for(const string &name : complianceTestMul){ + redo(REDO, Compliance(name).run();) + } + #endif + #ifdef DIV + for(const string &name : complianceTestDiv){ + redo(REDO, Compliance(name).run();) + } + #endif + #if defined(CSR) && !defined(CSR_SKIP_TEST) + for(const string &name : complianceTestCsr){ + redo(REDO, Compliance(name).run();) + } + #endif + + #ifdef FENCEI + redo(REDO, Compliance("I-FENCE.I-01").run();) + #endif + #ifdef EBREAK + redo(REDO, Compliance("I-EBREAK-01").run();) + #endif + + for(const string &name : riscvTestMain){ + redo(REDO,RiscvTest(name).withRiscvRef()->run();) + } + for(const string &name : riscvTestMemory){ + redo(REDO,RiscvTest(name).withRiscvRef()->run();) + } + + + #ifdef MUL + for(const string &name : riscvTestMul){ + redo(REDO,RiscvTest(name).withRiscvRef()->run();) + } + #endif + #ifdef DIV + for(const string &name : riscvTestDiv){ + redo(REDO,RiscvTest(name).withRiscvRef()->run();) + } + #endif + + #ifdef COMPRESSED + redo(REDO,RiscvTest("rv32uc-p-rvc").withRiscvRef()->bootAt(0x800000FCu)->run()); + #endif + + #if defined(CSR) && !defined(CSR_SKIP_TEST) + #ifndef COMPRESSED + uint32_t machineCsrRef[] = {1,11, 2,0x80000003u, 3,0x80000007u, 4,0x8000000bu, 5,6,7,0x80000007u , + 8,6,9,6,10,4,11,4, 12,13,0, 14,2, 15,5,16,17,1 }; + redo(REDO,TestX28("../../cpp/raw/machineCsr/build/machineCsr",machineCsrRef, sizeof(machineCsrRef)/4).withRiscvRef()->setVcdName("machineCsr")->run(10e4);) + #else + uint32_t machineCsrRef[] = {1,11, 2,0x80000003u, 3,0x80000007u, 4,0x8000000bu, 5,6,7,0x80000007u , + 8,6,9,6,10,4,11,4, 12,13, 14,2, 15,5,16,17,1 }; + redo(REDO,TestX28("../../cpp/raw/machineCsr/build/machineCsrCompressed",machineCsrRef, sizeof(machineCsrRef)/4).withRiscvRef()->setVcdName("machineCsrCompressed")->run(10e4);) + #endif + #endif +// #ifdef MMU +// uint32_t mmuRef[] = {1,2,3, 0x11111111, 0x11111111, 0x11111111, 0x22222222, 0x22222222, 0x22222222, 4, 0x11111111, 0x33333333, 0x33333333, 5, +// 13, 0xC4000000,0x33333333, 6,7, +// 1,2,3, 0x11111111, 0x11111111, 0x11111111, 0x22222222, 0x22222222, 0x22222222, 4, 0x11111111, 0x33333333, 0x33333333, 5, +// 13, 0xC4000000,0x33333333, 6,7}; +// redo(REDO,TestX28("mmu",mmuRef, sizeof(mmuRef)/4).noInstructionReadCheck()->run(4e4);) +// #endif + + #ifdef IBUS_CACHED + redo(REDO,WorkspaceRegression("icache").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/icache/build/icache.hex")->bootAt(0x80000000u)->run(50e3);); + #endif + #ifdef DBUS_CACHED + redo(REDO,WorkspaceRegression("dcache").loadHex(string(REGRESSION_PATH) + "../raw/dcache/build/dcache.hex")->bootAt(0x80000000u)->run(2500e3);); + #endif + + #ifdef MMU + redo(REDO,WorkspaceRegression("mmu").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/mmu/build/mmu.hex")->bootAt(0x80000000u)->run(50e3);); + #endif + #ifdef SUPERVISOR + redo(REDO,WorkspaceRegression("deleg").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/deleg/build/deleg.hex")->bootAt(0x80000000u)->run(50e3);); + #endif + + #ifdef DEBUG_PLUGIN + #ifndef CONCURRENT_OS_EXECUTIONS + redo(REDO,DebugPluginTest().run(1e6);); + #endif + #endif + #endif + + #ifdef CUSTOM_SIMD_ADD + redo(REDO,WorkspaceRegression("custom_simd_add").loadHex(string(REGRESSION_PATH) + "../custom/simd_add/build/custom_simd_add.hex")->bootAt(0x00000000u)->run(50e3);); + #endif + + #ifdef CUSTOM_CSR + redo(REDO,WorkspaceRegression("custom_csr").loadHex(string(REGRESSION_PATH) + "../custom/custom_csr/build/custom_csr.hex")->bootAt(0x00000000u)->run(50e3);); + #endif + + + #ifdef LRSC + redo(REDO,WorkspaceRegression("lrsc").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/lrsc/build/lrsc.hex")->bootAt(0x00000000u)->run(10e3);); + #endif + + #ifdef PMP + redo(REDO,WorkspaceRegression("pmp").loadHex(string(REGRESSION_PATH) + "../raw/pmp/build/pmp.hex")->bootAt(0x80000000u)->run(10e3);); + #endif + + #ifdef AMO + redo(REDO,WorkspaceRegression("amo").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../raw/amo/build/amo.hex")->bootAt(0x00000000u)->run(10e3);); + #endif + + #ifdef DHRYSTONE + Dhrystone("dhrystoneO3_Stall","dhrystoneO3",true,true).run(1.5e6); + #if defined(COMPRESSED) + Dhrystone("dhrystoneO3C_Stall","dhrystoneO3C",true,true).run(1.5e6); + #endif + #if defined(MUL) && defined(DIV) + Dhrystone("dhrystoneO3M_Stall","dhrystoneO3M",true,true).run(1.9e6); + #if defined(COMPRESSED) + Dhrystone("dhrystoneO3MC_Stall","dhrystoneO3MC",true,true).run(1.9e6); + #endif + #endif + #if defined(COMPRESSED) + Dhrystone("dhrystoneO3C","dhrystoneO3C",false,false).run(1.9e6); + #endif + Dhrystone("dhrystoneO3","dhrystoneO3",false,false).run(1.9e6); + #if defined(MUL) && defined(DIV) + #if defined(COMPRESSED) + Dhrystone("dhrystoneO3MC","dhrystoneO3MC",false,false).run(1.9e6); + #endif + Dhrystone("dhrystoneO3M","dhrystoneO3M",false,false).run(1.9e6); + #endif + #endif + + #ifdef COREMARK + for(int withStall = 1; true ;withStall--){ + string rv = "rv32i"; + #if defined(MUL) && defined(DIV) + rv += "m"; + #endif + #if defined(COMPRESSED) + if(withStall == -2) break; + if(withStall != -1) rv += "c"; + #else + if(withStall == -1) break; + #endif + WorkspaceRegression("coremark_" + rv + (withStall > 0 ? "_stall" : "_nostall")).withRiscvRef() + ->loadBin(string(REGRESSION_PATH) + "../../resources/bin/coremark_" + rv + ".bin", 0x80000000) + ->bootAt(0x80000000) + ->setIStall(withStall > 0) + ->setDStall(withStall > 0) + ->run(50e6); + } + #endif + + + + #ifdef FREERTOS + { + #ifdef SEED + srand48(SEED); + #endif + //redo(1,WorkspaceRegression("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);) + vector <std::function<void()>> tasks; + + /*for(int redo = 0;redo < 4;redo++)*/{ + for(const string &name : freeRtosTests){ + tasks.push_back([=]() { WorkspaceRegression(name + "_rv32i_O0").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/freertos/" + name + "_rv32i_O0.hex")->bootAt(0x80000000u)->run(4e6*15);}); + tasks.push_back([=]() { WorkspaceRegression(name + "_rv32i_O3").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/freertos/" + name + "_rv32i_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); + #ifdef COMPRESSED +// tasks.push_back([=]() { WorkspaceRegression(name + "_rv32ic_O0").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/freertos/" + name + "_rv32ic_O0.hex")->bootAt(0x80000000u)->run(5e6*15);}); + tasks.push_back([=]() { WorkspaceRegression(name + "_rv32ic_O3").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/freertos/" + name + "_rv32ic_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); + #endif + #if defined(MUL) && defined(DIV) +// #ifdef COMPRESSED +// tasks.push_back([=]() { WorkspaceRegression(name + "_rv32imac_O3").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/freertos/" + name + "_rv32imac_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); +// #else + tasks.push_back([=]() { WorkspaceRegression(name + "_rv32im_O3").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/freertos/" + name + "_rv32im_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); +// #endif + #endif + } + } + + while(tasks.size() > FREERTOS_COUNT){ + tasks.erase(tasks.begin() + (VL_RANDOM_I_WIDTH(32)%tasks.size())); + } + + + queue <std::function<void()>> tasksSelected(std::deque<std::function<void()>>(tasks.begin(), tasks.end())); + multiThreadedExecute(tasksSelected); + } + #endif + + #ifdef ZEPHYR + { + #ifdef SEED + srand48(SEED); + #endif + //redo(1,WorkspaceRegression("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);) + vector <std::function<void()>> tasks; + + /*for(int redo = 0;redo < 4;redo++)*/{ + for(const string &name : zephyrTests){ + #ifdef COMPRESSED + tasks.push_back([=]() { ZephyrRegression(name + "_rv32ic").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/VexRiscvRegressionData/sim/zephyr/" + name + "_rv32ic.hex")->bootAt(0x80000000u)->run(180e6);}); + #else + tasks.push_back([=]() { ZephyrRegression(name + "_rv32i").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/VexRiscvRegressionData/sim/zephyr/" + name + "_rv32i.hex")->bootAt(0x80000000u)->run(180e6);}); + #endif + #if defined(MUL) && defined(DIV) + tasks.push_back([=]() { ZephyrRegression(name + "_rv32im").withRiscvRef()->loadHex(string(REGRESSION_PATH) + "../../resources/VexRiscvRegressionData/sim/zephyr/" + name + "_rv32im.hex")->bootAt(0x80000000u)->run(180e6);}); + #endif + } + } + + while(tasks.size() > ZEPHYR_COUNT){ + tasks.erase(tasks.begin() + (VL_RANDOM_I_WIDTH(32)%tasks.size())); + } + + + queue <std::function<void()>> tasksSelected(std::deque<std::function<void()>>(tasks.begin(), tasks.end())); + multiThreadedExecute(tasksSelected); + } + #endif + + #if defined(LINUX_REGRESSION) + { + + LinuxRegression soc("linux"); + #ifndef DEBUG_PLUGIN_EXTERNAL + soc.withRiscvRef(); + soc.loadBin(string(REGRESSION_PATH) + EMULATOR, 0x80000000); + soc.loadBin(string(REGRESSION_PATH) + VMLINUX, 0xC0000000); + soc.loadBin(string(REGRESSION_PATH) + DTB, 0xC3000000); + soc.loadBin(string(REGRESSION_PATH) + RAMDISK, 0xC2000000); + #endif + //soc.setIStall(true); + //soc.setDStall(true); + soc.bootAt(0x80000000); + soc.run(153995602l*9); +// soc.run((470000000l + 2000000) / 2); +// soc.run(438700000l/2); + } + #endif + + } + + uint64_t duration = timer_end(startedAt); + cout << endl << "****************************************************************" << endl; + cout << "Had simulate " << Workspace::cycles << " clock cycles in " << duration*1e-9 << " s (" << Workspace::cycles / (duration*1e-6) << " Khz)" << endl; + if(Workspace::successCounter == Workspace::testsCounter) + cout << "REGRESSION SUCCESS " << Workspace::successCounter << "/" << Workspace::testsCounter << endl; + else + cout<< "REGRESSION FAILURE " << Workspace::testsCounter - Workspace::successCounter << "/" << Workspace::testsCounter << endl; + cout << "****************************************************************" << endl << endl; + + + exit(0); +} diff --git a/VexRiscv/src/test/cpp/regression/makefile b/VexRiscv/src/test/cpp/regression/makefile new file mode 100644 index 0000000..b8759c9 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/makefile @@ -0,0 +1,345 @@ +DEBUG?=no +REGRESSION_PATH?=./ +VEXRISCV_FILE?=../../../../VexRiscv.v +IBUS?=CACHED +IBUS_TC?=no +IBUS_DATA_WIDTH?=32 +DBUS?=CACHED +DBUS_LOAD_DATA_WIDTH?=32 +DBUS_STORE_DATA_WIDTH?=32 +TRACE?=no +TRACE_ACCESS?=no +TRACE_START=0 +TRACE_SPORADIC?=no +ISA_TEST?=yes +MUL?=yes +DIV?=yes +RVF?=no +RVD?=no +CSR?=yes +CSR_SKIP_TEST?=no +EBREAK?=no +FENCEI?=no +MMU?=yes +DBUS_EXCLUSIVE?=no +DBUS_INVALIDATE?=no +PMP?=no +SEED?=no +LRSC?=no +AMO?=no +NO_STALL?=no +DEBUG_PLUGIN?=STD +DEBUG_PLUGIN_EXTERNAL?=no +RUN_HEX=no +WITH_RISCV_REF=yes +CUSTOM_SIMD_ADD?=no +CUSTOM_CSR?=no +DHRYSTONE=yes +FREERTOS?=no +ZEPHYR?=no +REDO?=10 +REF=no +TRACE_WITH_TIME=no +REF_TIME=no +THREAD_COUNT?=$(shell nproc) +MTIME_INSTR_FACTOR?=no +COMPRESSED?=no +SUPERVISOR?=no +STOP_ON_ERROR?=no +COREMARK=no +WITH_USER_IO?=no + + +ADDCFLAGS += -CFLAGS -DREGRESSION_PATH='\"$(REGRESSION_PATH)/\"' +ADDCFLAGS += -CFLAGS -DIBUS_${IBUS} +ADDCFLAGS += -CFLAGS -DIBUS_DATA_WIDTH=${IBUS_DATA_WIDTH} +ADDCFLAGS += -CFLAGS -DDBUS_LOAD_DATA_WIDTH=${DBUS_LOAD_DATA_WIDTH} +ADDCFLAGS += -CFLAGS -DDBUS_STORE_DATA_WIDTH=${DBUS_STORE_DATA_WIDTH} + +ADDCFLAGS += -CFLAGS -DDBUS_${DBUS} +ADDCFLAGS += -CFLAGS -DREDO=${REDO} +ADDCFLAGS += -CFLAGS -pthread +ADDCFLAGS += -CFLAGS -Wno-unused-result + + + +ADDCFLAGS += -CFLAGS -DTHREAD_COUNT=${THREAD_COUNT} + +ifeq ($(DEBUG),yes) + ADDCFLAGS += -CFLAGS -O0 -CFLAGS -g +else + ADDCFLAGS += -CFLAGS -O3 -O3 +endif + +ifeq ($(CONCURRENT_OS_EXECUTIONS),yes) + ADDCFLAGS += -CFLAGS -DCONCURRENT_OS_EXECUTIONS +endif + +ifeq ($(LITEX),yes) + ADDCFLAGS += -CFLAGS -DLITEX + ADDCFLAGS += -CFLAGS -DVMLINUX='\"$(VMLINUX)\"' + ADDCFLAGS += -CFLAGS -DDTB='\"$(DTB)\"' + ADDCFLAGS += -CFLAGS -DRAMDISK='\"$(RAMDISK)\"' + ADDCFLAGS += -CFLAGS -DEMULATOR='\"$(EMULATOR)\"' +endif + +ifeq ($(LINUX_SOC),yes) + ADDCFLAGS += -CFLAGS -DLINUX_SOC + ADDCFLAGS += -CFLAGS -DVMLINUX='\"$(VMLINUX)\"' + ADDCFLAGS += -CFLAGS -DDTB='\"$(DTB)\"' + ADDCFLAGS += -CFLAGS -DRAMDISK='\"$(RAMDISK)\"' + ADDCFLAGS += -CFLAGS -DEMULATOR='\"$(EMULATOR)\"' +endif + +ifeq ($(LINUX_SOC_SMP),yes) + ADDCFLAGS += -CFLAGS -DLINUX_SOC_SMP + ADDCFLAGS += -CFLAGS -DVMLINUX='\"$(VMLINUX)\"' + ADDCFLAGS += -CFLAGS -DDTB='\"$(DTB)\"' + ADDCFLAGS += -CFLAGS -DRAMDISK='\"$(RAMDISK)\"' + ADDCFLAGS += -CFLAGS -DEMULATOR='\"$(EMULATOR)\"' +endif + + +ARCH_LINUX=rv32i +ifeq ($(MUL),yes) +ifeq ($(DIV),yes) +ARCH_LINUX:=$(ARCH_LINUX)m +endif +endif +ARCH_LINUX:=$(ARCH_LINUX)a +ifeq ($(COMPRESSED),yes) +ARCH_LINUX:=$(ARCH_LINUX)c +endif + +ifeq ($(LINUX_REGRESSION),yes) +ifneq ($(ARCH_LINUX),rv32iac) +ifneq ($(ARCH_LINUX),rv32ia) + ADDCFLAGS += -CFLAGS -DLINUX_REGRESSION + ADDCFLAGS += -CFLAGS -DARCH_LINUX='\"$(ARCH_LINUX)\"' + ADDCFLAGS += -CFLAGS -DVMLINUX='\"../../resources/VexRiscvRegressionData/sim/linux/$(ARCH_LINUX)/Image\"' + ADDCFLAGS += -CFLAGS -DDTB='\"../../resources/VexRiscvRegressionData/sim/linux/$(ARCH_LINUX)/rv32.dtb\"' + ADDCFLAGS += -CFLAGS -DRAMDISK='\"../../resources/VexRiscvRegressionData/sim/linux/$(ARCH_LINUX)/rootfs.cpio\"' + ADDCFLAGS += -CFLAGS -DEMULATOR='\"../../resources/VexRiscvRegressionData/sim/linux/emulator/emulator.bin\"' +endif +endif +endif + + +ifeq ($(FLOW_INFO),yes) + ADDCFLAGS += -CFLAGS -DFLOW_INFO +endif + + +ifeq ($(COREMARK),yes) + ADDCFLAGS += -CFLAGS -DCOREMARK +endif + +ifeq ($(WITH_RISCV_REF),yes) + ADDCFLAGS += -CFLAGS -DWITH_RISCV_REF +endif + + + +ifneq ($(shell grep timerInterrupt ${VEXRISCV_FILE} -w),) + ADDCFLAGS += -CFLAGS -DTIMER_INTERRUPT +endif + +ifneq ($(shell grep externalInterrupt ${VEXRISCV_FILE} -w),) +ifneq ($(EXTERNAL_INTERRUPT),no) + ADDCFLAGS += -CFLAGS -DEXTERNAL_INTERRUPT +endif +endif + +ifneq ($(shell grep utime ${VEXRISCV_FILE} -w),) + ADDCFLAGS += -CFLAGS -DUTIME_INPUT +endif + +ifneq ($(shell grep dBus_rsp_payload_aggregated ${VEXRISCV_FILE} -w),) + ADDCFLAGS += -CFLAGS -DDBUS_AGGREGATION +endif + + +ifneq ($(RUN_HEX),no) + ADDCFLAGS += -CFLAGS -DRUN_HEX='\"$(RUN_HEX)\"' +endif + + +ifeq ($(IBUS_TC),yes) + ADDCFLAGS += -CFLAGS -DIBUS_TC=yes +endif +ifeq ($(WITH_USER_IO),yes) + ADDCFLAGS += -CFLAGS -DWITH_USER_IO=yes +endif + + +ifeq ($(COMPRESSED),yes) + ADDCFLAGS += -CFLAGS -DCOMPRESSED +endif +ifeq ($(SUPERVISOR),yes) + ADDCFLAGS += -CFLAGS -DSUPERVISOR +endif +ifeq ($(FENCEI),yes) + ADDCFLAGS += -CFLAGS -DFENCEI +endif + +ifeq ($(EBREAK),yes) + ADDCFLAGS += -CFLAGS -DEBREAK +endif + + +ifeq ($(DHRYSTONE),yes) + ADDCFLAGS += -CFLAGS -DDHRYSTONE +endif + +ifeq ($(STOP_ON_ERROR),yes) + ADDCFLAGS += -CFLAGS -DSTOP_ON_ERROR +endif + + +ifeq ($(NO_STALL),yes) + ADDCFLAGS += -CFLAGS -DSTALL=0 +else + ADDCFLAGS += -CFLAGS -DSTALL=1 +endif + +ifneq ($(MTIME_INSTR_FACTOR),no) + ADDCFLAGS += -CFLAGS -DMTIME_INSTR_FACTOR=${MTIME_INSTR_FACTOR} +endif + +ifneq ($(SEED),no) + ADDCFLAGS += -CFLAGS -DSEED=${SEED} +endif + +ifeq ($(TRACE),yes) + VERILATOR_ARGS += --trace-fst + ADDCFLAGS += -CFLAGS -DTRACE +endif + +ifeq ($(TRACE_SPORADIC),yes) + ADDCFLAGS += -CFLAGS -DTRACE_SPORADIC +endif + + + +ifeq ($(CSR),yes) + ADDCFLAGS += -CFLAGS -DCSR +endif + +ifeq ($(CSR_SKIP_TEST),yes) + ADDCFLAGS += -CFLAGS -DCSR_SKIP_TEST +endif + + +ifeq ($(LRSC),yes) + ADDCFLAGS += -CFLAGS -DLRSC +endif + +ifeq ($(AMO),yes) + ADDCFLAGS += -CFLAGS -DAMO +endif + +ifeq ($(CUSTOM_SIMD_ADD),yes) + ADDCFLAGS += -CFLAGS -DCUSTOM_SIMD_ADD +endif + +ifeq ($(CUSTOM_CSR),yes) + ADDCFLAGS += -CFLAGS -DCUSTOM_CSR +endif + +ifeq ($(TRACE_WITH_TIME),yes) + ADDCFLAGS += -CFLAGS -DTRACE_WITH_TIME +endif + +ifeq ($(REF_TIME),yes) + ADDCFLAGS += -CFLAGS -DREF_TIME +endif + +ifeq ($(ISA_TEST),yes) + ADDCFLAGS += -CFLAGS -DISA_TEST +endif + +ifeq ($(MMU),yes) + ADDCFLAGS += -CFLAGS -DMMU +endif + +ifeq ($(DBUS_EXCLUSIVE),yes) + ADDCFLAGS += -CFLAGS -DDBUS_EXCLUSIVE +endif +ifeq ($(DBUS_INVALIDATE),yes) + ADDCFLAGS += -CFLAGS -DDBUS_INVALIDATE +endif + +ifeq ($(PMP),yes) + ADDCFLAGS += -CFLAGS -DPMP +endif + +ifeq ($(MUL),yes) + ADDCFLAGS += -CFLAGS -DMUL +endif + +ifeq ($(RVF),yes) + ADDCFLAGS += -CFLAGS -DRVF +endif + +ifeq ($(RVD),yes) + ADDCFLAGS += -CFLAGS -DRVD +endif + +ifeq ($(DIV),yes) + ADDCFLAGS += -CFLAGS -DDIV +endif + +ifeq ($(TRACE_ACCESS),yes) + ADDCFLAGS += -CFLAGS -DTRACE_ACCESS +endif + +ifneq ($(DEBUG_PLUGIN),no) + ADDCFLAGS += -CFLAGS -DDEBUG_PLUGIN + ADDCFLAGS += -CFLAGS -DDEBUG_PLUGIN_${DEBUG_PLUGIN} +endif + +ifeq ($(DEBUG_PLUGIN_EXTERNAL),yes) + ADDCFLAGS += -CFLAGS -DDEBUG_PLUGIN_EXTERNAL +endif + +ifeq ($(REF),yes) + ADDCFLAGS += -CFLAGS -DREF +endif + +ADDCFLAGS += -CFLAGS -DTRACE_START=${TRACE_START} +ifeq ($(FREERTOS),yes) + ADDCFLAGS += -CFLAGS -DFREERTOS + ADDCFLAGS += -CFLAGS -DFREERTOS_COUNT=99999 +else +ifneq ($(FREERTOS),no) + ADDCFLAGS += -CFLAGS -DFREERTOS + ADDCFLAGS += -CFLAGS -DFREERTOS_COUNT=$(FREERTOS) +endif +endif + + +ifeq ($(ZEPHYR),yes) + ADDCFLAGS += -CFLAGS -DZEPHYR + ADDCFLAGS += -CFLAGS -DZEPHYR_COUNT=99999 +else +ifneq ($(ZEPHYR),no) + ADDCFLAGS += -CFLAGS -DZEPHYR + ADDCFLAGS += -CFLAGS -DZEPHYR_COUNT=$(ZEPHYR) +endif +endif + +all: clean run + +run: compile + ./obj_dir/VVexRiscv + +verilate: ${VEXRISCV_FILE} + cp ${VEXRISCV_FILE}*.bin . | true + verilator -cc ${VEXRISCV_FILE} -O3 -CFLAGS -std=c++11 -LDFLAGS -pthread ${ADDCFLAGS} --gdbbt ${VERILATOR_ARGS} -Wno-UNOPTFLAT -Wno-WIDTH --x-assign unique --exe main.cpp + +compile: verilate + make -j${THREAD_COUNT} -C obj_dir/ -f VVexRiscv.mk VVexRiscv + +clean: + rm -rf obj_dir + diff --git a/VexRiscv/src/test/cpp/regression/prediction.gtkw b/VexRiscv/src/test/cpp/regression/prediction.gtkw new file mode 100644 index 0000000..8abfdd9 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/prediction.gtkw @@ -0,0 +1,43 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Mon Jan 29 13:38:19 2018 +[*] +[dumpfile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/dhrystoneO3M.vcd" +[dumpfile_mtime] "Mon Jan 29 13:37:19 2018" +[dumpfile_size] 1215443558 +[savefile] "/home/spinalvm/hdl/VexRiscv/src/test/cpp/regression/prediction.gtkw" +[timestart] 127017 +[size] 1784 950 +[pos] -383 -155 +*-3.000000 127032 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[sst_width] 400 +[signals_width] 583 +[sst_expanded] 1 +[sst_vpaned_height] 492 +@28 +TOP.VexRiscv.iBus_cmd_valid +TOP.VexRiscv.decode_arbitration_flushAll +TOP.VexRiscv.execute_arbitration_flushAll +TOP.VexRiscv.fetch_arbitration_flushAll +TOP.VexRiscv.memory_arbitration_flushAll +TOP.VexRiscv.prefetch_arbitration_flushAll +TOP.VexRiscv.writeBack_arbitration_flushAll +TOP.VexRiscv.execute_BranchPlugin_predictionMissmatch +TOP.VexRiscv.execute_PREDICTION2_confidence[1:0] +@22 +TOP.VexRiscv.execute_PREDICTION2_source[18:0] +TOP.VexRiscv.execute_PREDICTION2_target[31:0] +@28 +TOP.VexRiscv.execute_PREDICTION_HIT2 +TOP.VexRiscv.execute_PREDICTION_WRITE_HAZARD2 +@23 +TOP.VexRiscv.execute_PC[31:0] +@28 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_valid +@22 +TOP.VexRiscv.prefetch_PcManagerSimplePlugin_jump_pcLoad_payload[31:0] +@29 +TOP.VexRiscv.execute_arbitration_isFiring +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/refDiff.gtkw b/VexRiscv/src/test/cpp/regression/refDiff.gtkw new file mode 100644 index 0000000..5be0db4 --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/refDiff.gtkw @@ -0,0 +1,40 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Fri Mar 17 18:05:14 2017 +[*] +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/DhrystoneRef.vcd" +[dumpfile_mtime] "Fri Mar 17 18:03:52 2017" +[dumpfile_size] 1483111421 +[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/refDiff.gtkw" +[timestart] 36700 +[size] 1774 451 +[pos] -775 -353 +*-2.000000 36713 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 201 +[signals_width] 583 +[sst_expanded] 1 +[sst_vpaned_height] 68 +@22 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0] +@24 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0] +@28 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid +TOP.VexRiscv.writeBack_arbitration_isValid +TOP.VexRiscv.clk +@22 +TOP.VexRiscv.core.writeBack_inInst_payload_instruction[31:0] +TOP.VexRiscv.core.writeBack_inInst_payload_pcPlus4[31:0] +TOP.dCmd_payload_address[31:0] +TOP.dCmd_payload_data[31:0] +@28 +TOP.dCmd_payload_size[1:0] +TOP.dCmd_payload_wr +TOP.dCmd_ready +TOP.dCmd_valid +@25 +TOP.dRsp_data[31:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/wrongDiff.gtkw b/VexRiscv/src/test/cpp/regression/wrongDiff.gtkw new file mode 100644 index 0000000..29d111c --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/wrongDiff.gtkw @@ -0,0 +1,62 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Sat Mar 18 09:49:22 2017 +[*] +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/DhrystoneWrong.vcd" +[dumpfile_mtime] "Sat Mar 18 08:08:53 2017" +[dumpfile_size] 1450277049 +[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/wrongDiff.gtkw" +[timestart] 37402 +[size] 1774 476 +[pos] -1 475 +*-2.000000 37407 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[treeopen] TOP.VexRiscv. +[sst_width] 201 +[signals_width] 583 +[sst_expanded] 1 +[sst_vpaned_height] 112 +@28 +TOP.VexRiscv.fetch_arbitration_isStuck +TOP.VexRiscv.decode_arbitration_isStuck +TOP.VexRiscv.execute_arbitration_isStuck +TOP.VexRiscv.memory_arbitration_isStuck +TOP.VexRiscv.writeBack_arbitration_isStuck +TOP.VexRiscv.prefetch_arbitration_isValid +TOP.VexRiscv.fetch_arbitration_isValid +@29 +TOP.VexRiscv.decode_arbitration_isValid +@28 +TOP.VexRiscv.execute_arbitration_isValid +TOP.VexRiscv.memory_arbitration_isValid +TOP.VexRiscv.writeBack_arbitration_isValid +@22 +TOP.VexRiscv.writeBack_input_PC[31:0] +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0] +@24 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0] +@28 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid +TOP.VexRiscv.writeBack_arbitration_isValid +TOP.VexRiscv.clk +TOP.dCmd_valid +TOP.dCmd_ready +TOP.dCmd_payload_wr +TOP.dCmd_payload_size[1:0] +@22 +TOP.dCmd_payload_address[31:0] +TOP.dCmd_payload_data[31:0] +@24 +TOP.dRsp_data[31:0] +@22 +TOP.VexRiscv.execute_input_PC[31:0] +TOP.VexRiscv.execute_input_INSTRUCTION[31:0] +@28 +TOP.VexRiscv.fetch_arbitration_removeIt +TOP.VexRiscv.decode_arbitration_removeIt +TOP.VexRiscv.execute_arbitration_removeIt +TOP.VexRiscv.memory_arbitration_removeIt +TOP.VexRiscv.writeBack_arbitration_removeIt +TOP.VexRiscv.execute_arbitration_isValid +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/VexRiscv/src/test/cpp/regression/yolo.gtkw b/VexRiscv/src/test/cpp/regression/yolo.gtkw new file mode 100644 index 0000000..66b5bbc --- /dev/null +++ b/VexRiscv/src/test/cpp/regression/yolo.gtkw @@ -0,0 +1,84 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Tue Mar 14 21:27:40 2017 +[*] +[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-lw.vcd" +[dumpfile_mtime] "Tue Mar 14 21:24:45 2017" +[dumpfile_size] 1017741 +[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/yolo.gtkw" +[timestart] 41 +[size] 1776 953 +[pos] -1 -1 +*-1.801840 49 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] TOP. +[sst_width] 418 +[signals_width] 559 +[sst_expanded] 1 +[sst_vpaned_height] 279 +@28 +TOP.clk +TOP.dCmd_valid +TOP.dCmd_ready +TOP.dCmd_payload_wr +@22 +TOP.dCmd_payload_address[31:0] +TOP.dCmd_payload_data[31:0] +@28 +TOP.dCmd_payload_size[1:0] +@23 +TOP.dRsp_data[31:0] +@22 +TOP.iCmd_payload_pc[31:0] +@28 +TOP.iCmd_ready +TOP.iCmd_valid +@22 +TOP.iRsp_inst[31:0] +@28 +TOP.reset +TOP.clk +TOP.iCmd_valid +@22 +TOP.iCmd_payload_pc[31:0] +@28 +TOP.iCmd_ready +@22 +TOP.iRsp_inst[31:0] +@28 +TOP.reset +TOP.VexRiscv.writeBack_arbitration_isValid +@22 +TOP.VexRiscv.writeBack_input_INSTRUCTION[31:0] +TOP.VexRiscv.writeBack_input_PC[31:0] +@28 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid +@22 +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0] +TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0] +@28 +TOP.VexRiscv.prefetch_arbitration_isValid +TOP.VexRiscv.fetch_arbitration_isValid +TOP.VexRiscv.decode_arbitration_isValid +TOP.VexRiscv.execute_arbitration_isValid +TOP.VexRiscv.memory_arbitration_isValid +TOP.VexRiscv.writeBack_arbitration_isValid +TOP.VexRiscv.prefetch_arbitration_isStuck +TOP.VexRiscv.fetch_arbitration_isStuck +TOP.VexRiscv.decode_arbitration_isStuck +TOP.VexRiscv.execute_arbitration_isStuck +TOP.VexRiscv.memory_arbitration_isStuck +TOP.VexRiscv.writeBack_arbitration_isStuck +@22 +TOP.VexRiscv.prefetch_input_PC[31:0] +TOP.VexRiscv.fetch_input_PC[31:0] +TOP.VexRiscv.decode_input_PC[31:0] +TOP.VexRiscv.execute_input_PC[31:0] +TOP.VexRiscv.memory_input_PC[31:0] +TOP.VexRiscv.writeBack_input_PC[31:0] +TOP.VexRiscv.fetch_input_INSTRUCTION[31:0] +TOP.VexRiscv.decode_input_INSTRUCTION[31:0] +TOP.VexRiscv.execute_input_INSTRUCTION[31:0] +TOP.VexRiscv.memory_input_INSTRUCTION[31:0] +TOP.VexRiscv.writeBack_input_INSTRUCTION[31:0] +[pattern_trace] 1 +[pattern_trace] 0 |