From 99898754060446dfdbc5615b5b8a97fbd316ce2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B5=A9=E5=AE=87?= Date: Sat, 14 Aug 2021 01:26:25 +0800 Subject: [PATCH] Supervisor level testbench passed --- auto_test.py | 9 +-- src/main/scala/Xim/AXI_ram.scala | 3 +- src/main/scala/Xim/CPU_Core.scala | 11 ++-- src/main/scala/Xim/CPU_EX.scala | 12 ++-- src/main/scala/Xim/csr.scala | 95 ++++++++++++++++++++++++++--- src/main/scala/Xim/priviledge.scala | 16 ++--- 6 files changed, 114 insertions(+), 32 deletions(-) diff --git a/auto_test.py b/auto_test.py index 1e18823..5879028 100644 --- a/auto_test.py +++ b/auto_test.py @@ -1,7 +1,7 @@ import os import re # regular expression -path = "/Users/cgk/ownCloud/课程/一生一芯/ict/riscv-tests/isa/" #the path of compiled risc-v test +path = "/home/wangns/riscv-tests/isa/" #the path of compiled risc-v test files= os.listdir(path) # get all file names @@ -13,7 +13,8 @@ continue if re.match('.*dump', file) != None: continue - if re.match('rv64ui-p-', file) != None: + #if re.match('rv64ui-p-', file) != None: + if re.match('rv64si-p-supervisor', file) != None: ans_files.append(file) # print(ans_files) @@ -24,6 +25,6 @@ print(i, end = '') i = i + 1 print("th test") - os.system('/Users/cgk/ownCloud/课程/一生一芯/ict/riscv64-unknown-elf-gcc-8.3.0-2020.04.0-x86_64-apple-darwin/bin/riscv64-unknown-elf-objcopy -O binary ' + path + file + ' /Users/cgk/ownCloud/课程/一生一芯/ict/test.bin.ori') - os.system('/Users/cgk/ownCloud/课程/一生一芯/ict/riscv64-unknown-elf-gcc-8.3.0-2020.04.0-x86_64-apple-darwin/bin/riscv64-unknown-elf-objcopy -I binary -O binary --reverse-bytes=8 /Users/cgk/ownCloud/课程/一生一芯/ict/test.bin.ori /Users/cgk/ownCloud/课程/一生一芯/ict/test.bin') + os.system('riscv64-unknown-elf-objcopy -O binary ' + path + file + ' /home/wangns/test.bin.ori') + os.system('riscv64-unknown-elf-objcopy -I binary -O binary --reverse-bytes=8 /home/wangns/test.bin.ori /home/wangns/test.bin') os.system('sbt "test:runMain Xim.SoC_Main_Type_Two --backend-name verilator"') diff --git a/src/main/scala/Xim/AXI_ram.scala b/src/main/scala/Xim/AXI_ram.scala index a136af4..083f11a 100644 --- a/src/main/scala/Xim/AXI_ram.scala +++ b/src/main/scala/Xim/AXI_ram.scala @@ -209,7 +209,8 @@ initial begin end // mem[0] = 32'h863; mem[1] = 32'h06400093; mem[2] = 32'h00000013; mem[3] = 32'h00000013; mem[4] = 32'h00102023; mem[5] = 32'h00002103; // mem[6] = 32'h00f00093; mem[7] = 32'h34101073; mem[8] = 32'h34109073; mem[9] = 32'h34186073; mem[10] = 32'h341020f3; - mem_file = $$fopen("/home/wangns/rtt-mbcore/bsp/mb-core/rtthread_reversed.bin", "r"); + //mem_file = $$fopen("/home/wangns/rtt-mbcore/bsp/mb-core/rtthread_reversed.bin", "r"); + mem_file = $$fopen("/home/wangns/test.bin", "r"); $$fread(mem, mem_file); end diff --git a/src/main/scala/Xim/CPU_Core.scala b/src/main/scala/Xim/CPU_Core.scala index e0ac960..6cbdc98 100644 --- a/src/main/scala/Xim/CPU_Core.scala +++ b/src/main/scala/Xim/CPU_Core.scala @@ -77,9 +77,9 @@ class CPU_Core(val rv_width: Int = 64, inSOC: Boolean = false) extends Module { val PrivModule = Module(new PriviledgeSignal) val CSRModule = Module(new CSRSignal) PrivModule.io.es_valid := EX_Stage.io.es_inst_valid - PrivModule.io.es_ex := EX_Stage.io.ex_valid - PrivModule.io.inst_mret := EX_Stage.io.es_inst_mret - PrivModule.io.inst_sret := EX_Stage.io.es_inst_sret + PrivModule.io.es_ex_work := CSRModule.io.es_ex_work + PrivModule.io.mret_work := CSRModule.io.mret_work + PrivModule.io.sret_work := CSRModule.io.sret_work PrivModule.io.mstatus_mpp := CSRModule.io.mstatus_mpp PrivModule.io.sstatus_spp := CSRModule.io.sstatus_spp CSRModule.io.priv_level := PrivModule.io.priv_level @@ -102,10 +102,11 @@ class CPU_Core(val rv_width: Int = 64, inSOC: Boolean = false) extends Module { CSRModule.io.Csr_num := EX_Stage.io.csr_number EX_Stage.io.csr_read_data := CSRModule.io.csr_read_data CSRModule.io.csr_write_data := EX_Stage.io.csr_write_data - EX_Stage.io.csr_mtvec := CSRModule.io.csr_mtvec EX_Stage.io.csr_timer_int := CSRModule.io.timer_int EX_Stage.io.mstatus_tsr := CSRModule.io.mstatus_tsr - + EX_Stage.io.trap_entry := CSRModule.io.trap_entry + EX_Stage.io.illegal_csr := CSRModule.io.illegal_csr + val branch_predicter = Module(new branch_pred) IF_Stage.io.next_branch := branch_predicter.io.IF_next_branch diff --git a/src/main/scala/Xim/CPU_EX.scala b/src/main/scala/Xim/CPU_EX.scala index ad77b48..31554bf 100644 --- a/src/main/scala/Xim/CPU_EX.scala +++ b/src/main/scala/Xim/CPU_EX.scala @@ -64,10 +64,11 @@ class CPU_EX(val rv_width: Int = 64) extends Module { val csr_number = Output(UInt(12.W)) val csr_read_data = Input(UInt(rv_width.W)) val csr_write_data = Output(UInt(rv_width.W)) - val csr_mtvec = Input(UInt(rv_width.W)) + val trap_entry = Input(UInt(rv_width.W)) val csr_timer_int = Input(UInt(1.W)) val mstatus_tsr = Input(UInt(1.W)) val priv_level = Input(UInt(2.W)) + val illegal_csr = Input(Bool()) }) val es_valid = RegInit(0.U(1.W)) @@ -85,7 +86,7 @@ class CPU_EX(val rv_width: Int = 64) extends Module { io.es_pc := es_pc val CSR_read_data = Wire(UInt(rv_width.W)) - val CSR_mtvec = Wire(UInt(rv_width.W)) + io.ex_target := io.trap_entry val CSR_mstatus_tsr = Wire(UInt(1.W)) val es_csr = Wire(UInt(1.W)) val timer_int = Wire(UInt(1.W)) @@ -777,7 +778,6 @@ class CPU_EX(val rv_width: Int = 64) extends Module { inst_csrrci | inst_csrrs | inst_csrrsi | inst_csrrw | inst_csrrwi CSR_read_data := io.csr_read_data - CSR_mtvec := io.csr_mtvec CSR_mstatus_tsr := io.mstatus_tsr CSR_mepc := io.mepc CSR_sepc := io.sepc @@ -931,8 +931,6 @@ class CPU_EX(val rv_width: Int = 64) extends Module { reg_wdata_s := 0.S } - io.ex_target := CSR_mtvec - val fs_ex_r = RegInit(0.U(1.W)) val fs_excode_r = RegInit(0.U(rv_width.W)) when (es_new_instr === 1.U) { @@ -967,6 +965,8 @@ class CPU_EX(val rv_width: Int = 64) extends Module { es_ex := 1.U } .elsewhen (es_valid === 1.U && es_write_ex === 1.U) { es_ex := 1.U + } .elsewhen (es_valid === 1.U && io.illegal_csr) { + es_ex := 1.U } .otherwise { es_ex := 0.U } @@ -998,6 +998,8 @@ class CPU_EX(val rv_width: Int = 64) extends Module { } .otherwise { es_excode := excode_const.UserTimerInt } + } .elsewhen (es_valid === 1.U && io.illegal_csr) { + es_excode := excode_const.IllegalInstruction } .otherwise { es_excode := 0.U } diff --git a/src/main/scala/Xim/csr.scala b/src/main/scala/Xim/csr.scala index f899550..30fe3e3 100644 --- a/src/main/scala/Xim/csr.scala +++ b/src/main/scala/Xim/csr.scala @@ -5,11 +5,13 @@ import chisel3._ class CSR(val rv_width: Int = 64) extends Module { val io = IO(new Bundle { val es_ex = Input(UInt(1.W)) + val es_ex_work = Output(UInt(1.W)) val es_new_instr = Input(UInt(1.W)) val es_excode = Input(UInt(rv_width.W)) val es_ex_pc = Input(UInt(rv_width.W)) val es_ex_addr = Input(UInt(rv_width.W)) val es_csr_wr = Input(UInt(1.W)) + val es_csr_op = Input(UInt(1.W)) val es_csr_read_num = Input(UInt(12.W)) val es_csr_write_num = Input(UInt(12.W)) val es_csr_write_data = Input(UInt(rv_width.W)) @@ -17,7 +19,7 @@ class CSR(val rv_width: Int = 64) extends Module { // timer interrupt val time_int = Output(UInt(1.W)) // trap entry - val mtrap_entry = Output(UInt(rv_width.W)) + val trap_entry = Output(UInt(rv_width.W)) // MEPC val mepc = Output(UInt(rv_width.W)) @@ -35,8 +37,10 @@ class CSR(val rv_width: Int = 64) extends Module { // mret val inst_mret = Input(UInt(1.W)) + val mret_work = Output(UInt(1.W)) // sret val inst_sret = Input(UInt(1.W)) + val sret_work = Output(UInt(1.W)) // priviledge level val priv_level = Input(UInt(2.W)) @@ -46,6 +50,9 @@ class CSR(val rv_width: Int = 64) extends Module { // delegate trap val deleg_trap = Output(Bool()) + + // illegal csr operations + val illegal_csr = Output(Bool()) }) // unimplemented signal: @@ -335,9 +342,10 @@ class CSR(val rv_width: Int = 64) extends Module { val deleg = Wire(Bool()) val SupervisorTIDeleg = Wire(UInt(1.W)) val UserTIDeleg = Wire(UInt(1.W)) + val machine_csr_op = Wire(Bool()) isInterrupt := io.es_excode(rv_width - 1) === 1.U - deleg := ((isInterrupt && csr_mideleg.value(io.es_excode(3,0))) || (!isInterrupt && csr_medeleg.value(io.es_excode(3,0))) && io.priv_level =/= priv_consts.Machine) + deleg := ((isInterrupt && csr_mideleg.value(io.es_excode(3,0)) =/= 0.U) || (!isInterrupt && csr_medeleg.value(io.es_excode(3,0)) =/= 0.U)) && io.priv_level =/= priv_consts.Machine io.deleg_trap := deleg SupervisorTIDeleg := csr_mideleg.value(5) UserTIDeleg := csr_mideleg.value(4) @@ -372,6 +380,10 @@ class CSR(val rv_width: Int = 64) extends Module { csr_mhartid.zero := 0.U + io.es_ex_work := es_ex_once + io.mret_work := mret_once + io.sret_work := sret_once + // timer interrupt when (mtime_full === mtimecmp_full) { when (io.priv_level === priv_consts.Machine) { @@ -446,7 +458,11 @@ class CSR(val rv_width: Int = 64) extends Module { // DIRECT Mode only } - io.mtrap_entry := csr_mtvec.asUInt() + when (deleg) { + io.trap_entry := csr_stvec.asUInt() + } .otherwise { + io.trap_entry := csr_mtvec.asUInt() + } // MIP // TODO: revise updating condition of MIP and MIE @@ -535,6 +551,16 @@ class CSR(val rv_width: Int = 64) extends Module { csr_mtval.value := io.es_csr_write_data } + // MIDELEG + when (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.MIDELEG) { + csr_mideleg.value := io.es_csr_write_data + } + + // MEDELEG + when (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.MEDELEG) { + csr_medeleg.value := io.es_csr_write_data + } + // SSTATUS when (es_ex_once === 1.U && deleg) { csr_sstatus.SPIE := csr_sstatus.SIE @@ -553,7 +579,7 @@ class CSR(val rv_width: Int = 64) extends Module { } when (es_ex_once === 1.U && deleg) { - csr_sstatus.SPP := 0.U // User + csr_sstatus.SPP := io.priv_level } .elsewhen (sret_once === 1.U) { csr_sstatus.SPP := 0.U // User, by spec } .elsewhen (io.es_csr_wr === 1.U && io.es_csr_write_num === csr_consts.SSTATUS) { @@ -620,56 +646,90 @@ class CSR(val rv_width: Int = 64) extends Module { when (io.es_csr_read_num === csr_consts.MSTATUS) { io.es_csr_read_data := csr_mstatus.asUInt() + machine_csr_op := true.B } .elsewhen(io.es_csr_read_num === csr_consts.MISA) { io.es_csr_read_data := csr_misa.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MVENDORID) { io.es_csr_read_data := csr_mvendorid.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MARCHID) { io.es_csr_read_data := csr_marchid.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MIMPID) { io.es_csr_read_data := csr_mimpid.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MHARTID) { io.es_csr_read_data := csr_mhartid.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MTVEC) { io.es_csr_read_data := csr_mtvec.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MIP) { io.es_csr_read_data := csr_mip.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MIE) { io.es_csr_read_data := csr_mie.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MSCRATCH) { io.es_csr_read_data := csr_mscratch.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MEPC) { io.es_csr_read_data := csr_mepc.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MCAUSE) { io.es_csr_read_data := csr_mcause.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MTVAL) { io.es_csr_read_data := csr_mtval.asUInt() + machine_csr_op := true.B + } .elsewhen (io.es_csr_read_num === csr_consts.MIDELEG) { + io.es_csr_read_data := csr_mideleg.asUInt() + machine_csr_op := true.B + } .elsewhen (io.es_csr_read_num === csr_consts.MEDELEG) { + io.es_csr_read_data := csr_medeleg.asUInt() + machine_csr_op := true.B } .elsewhen (io.es_csr_read_num === csr_consts.MTIMECMP) { io.es_csr_read_data := csr_mtimecmp.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.MTIME) { io.es_csr_read_data := csr_mtime.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.SSTATUS) { io.es_csr_read_data := csr_sstatus.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.STVEC) { io.es_csr_read_data := csr_stvec.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.SEPC) { io.es_csr_read_data := csr_sepc.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.SIP) { io.es_csr_read_data := csr_sip.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.SIE) { io.es_csr_read_data := csr_sie.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.SSCRATCH) { io.es_csr_read_data := csr_sscratch.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.SCAUSE) { io.es_csr_read_data := csr_scause.asUInt() + machine_csr_op := false.B } .elsewhen (io.es_csr_read_num === csr_consts.STVAL) { io.es_csr_read_data := csr_stval.asUInt() + machine_csr_op := false.B } .otherwise { // WARNING: TEST ONLY io.es_csr_read_data := csr_mtime.asUInt() + machine_csr_op := false.B + } + + when (io.priv_level =/= priv_consts.Machine && io.es_csr_op === 1.U && machine_csr_op) { + io.illegal_csr := true.B + } .otherwise { + io.illegal_csr := false.B } - - } object CSR extends App { @@ -683,6 +743,7 @@ class CSRSignal(val rv_width: Int = 64) extends Module { val es_new_instr = Input(UInt(1.W)) val es_ex = Input(UInt(1.W)) + val es_ex_work = Output(UInt(1.W)) val es_excode = Input(UInt(rv_width.W)) val es_pc = Input(UInt(rv_width.W)) val es_instr = Input(UInt(32.W)) @@ -692,12 +753,14 @@ class CSRSignal(val rv_width: Int = 64) extends Module { val inst_reload_r = Input(UInt(1.W)) val inst_mret = Input(UInt(1.W)) val inst_sret = Input(UInt(1.W)) + val mret_work = Output(UInt(1.W)) + val sret_work = Output(UInt(1.W)) val data_addr = Input(UInt(rv_width.W)) val Csr_num = Input(UInt(12.W)) val csr_read_data = Output(UInt(rv_width.W)) val csr_write_data = Input(UInt(rv_width.W)) - val csr_mtvec = Output(UInt(rv_width.W)) + val trap_entry = Output(UInt(rv_width.W)) val timer_int = Output(UInt(1.W)) val priv_level = Input(UInt(2.W)) @@ -707,6 +770,8 @@ class CSRSignal(val rv_width: Int = 64) extends Module { val sstatus_spp = Output(UInt(1.W)) val deleg_trap = Output(Bool()) + + val illegal_csr = Output(Bool()) }) val CSR_module = Module(new CSR) @@ -719,6 +784,7 @@ class CSRSignal(val rv_width: Int = 64) extends Module { val CSR_write_num = Wire(UInt(12.W)) val CSR_fault_addr = Wire(UInt(rv_width.W)) val CSR_fault_instr = Wire(UInt(rv_width.W)) + val CSR_op = Wire(UInt(1.W)) CSR_ex := io.es_ex CSR_excode := io.es_excode @@ -730,6 +796,7 @@ class CSRSignal(val rv_width: Int = 64) extends Module { CSR_module.io.es_ex_pc := CSR_epc CSR_module.io.es_ex_addr := CSR_badaddr CSR_module.io.es_csr_wr := CSR_write + CSR_module.io.es_csr_op := CSR_op CSR_module.io.es_csr_read_num := CSR_read_num CSR_module.io.es_csr_write_num := CSR_write_num CSR_module.io.es_csr_write_data := io.csr_write_data @@ -740,7 +807,7 @@ class CSRSignal(val rv_width: Int = 64) extends Module { CSR_module.io.priv_level := io.priv_level CSR_module.io.inst_reload := io.inst_reload_r io.csr_read_data := CSR_module.io.es_csr_read_data - io.csr_mtvec := CSR_module.io.mtrap_entry + io.trap_entry := CSR_module.io.trap_entry io.mstatus_tsr := CSR_module.io.mstatus_tsr io.mstatus_mpp := CSR_module.io.mstatus_mpp io.sstatus_spp := CSR_module.io.sstatus_spp @@ -748,6 +815,10 @@ class CSRSignal(val rv_width: Int = 64) extends Module { io.sepc := CSR_module.io.sepc io.timer_int := CSR_module.io.time_int io.deleg_trap := CSR_module.io.deleg_trap + io.illegal_csr := CSR_module.io.illegal_csr + io.es_ex_work := CSR_module.io.es_ex_work + io.mret_work := CSR_module.io.mret_work + io.sret_work := CSR_module.io.sret_work when (io.inst_reserved === 1.U) { // fill with instruction itself @@ -774,7 +845,13 @@ class CSRSignal(val rv_width: Int = 64) extends Module { } .otherwise { CSR_write := 0.U } - + + when (io.es_csr === 1.U) { + CSR_op := 1.U + } .otherwise { + CSR_op := 0.U + } + CSR_fault_instr := io.es_instr CSR_read_num := io.Csr_num CSR_write_num := io.Csr_num diff --git a/src/main/scala/Xim/priviledge.scala b/src/main/scala/Xim/priviledge.scala index d9aca90..96f794e 100644 --- a/src/main/scala/Xim/priviledge.scala +++ b/src/main/scala/Xim/priviledge.scala @@ -23,9 +23,9 @@ class PriviledgeReg extends Module { class PriviledgeSignal extends Module { val io = IO(new Bundle { val es_valid = Input(UInt(1.W)) - val es_ex = Input(UInt(1.W)) - val inst_mret = Input(UInt(1.W)) - val inst_sret = Input(UInt(1.W)) + val es_ex_work = Input(UInt(1.W)) + val mret_work = Input(UInt(1.W)) + val sret_work = Input(UInt(1.W)) val mstatus_mpp = Input(UInt(2.W)) val sstatus_spp = Input(UInt(1.W)) @@ -49,11 +49,11 @@ class PriviledgeSignal extends Module { io.priv_level := priv_rlevel - when (io.es_valid === 1.U && io.inst_mret === 1.U && priv_rlevel === priv_consts.Machine) { + when (io.es_valid === 1.U && io.mret_work === 1.U && priv_rlevel === priv_consts.Machine) { next_priv_level := io.mstatus_mpp - } .elsewhen (io.es_valid === 1.U && io.inst_sret === 1.U && priv_rlevel === priv_consts.Supervisor) { + } .elsewhen (io.es_valid === 1.U && io.sret_work === 1.U && priv_rlevel === priv_consts.Supervisor) { next_priv_level := io.sstatus_spp - } .elsewhen (io.es_ex === 1.U) { + } .elsewhen (io.es_ex_work === 1.U) { when (io.deleg_trap === true.B) { next_priv_level := priv_consts.Supervisor } .otherwise { @@ -63,9 +63,9 @@ class PriviledgeSignal extends Module { next_priv_level := priv_consts.Machine } - when (io.es_valid === 1.U && (io.inst_mret === 1.U || io.inst_sret === 1.U)) { + when (io.es_valid === 1.U && (io.mret_work === 1.U || io.sret_work === 1.U)) { priv_wen := true.B - } .elsewhen (io.es_ex === 1.U) { + } .elsewhen (io.es_ex_work === 1.U) { priv_wen := true.B } .otherwise { priv_wen := false.B