diff --git a/build.sbt b/build.sbt index 5e8ca30e..0cdecb8f 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -val spinalVersion = "1.8.1" +val spinalVersion = "1.9.0" lazy val root = (project in file(".")). settings( diff --git a/src/main/scala/vexriscv/ip/DataCache.scala b/src/main/scala/vexriscv/ip/DataCache.scala index 17766c21..5ed44f67 100644 --- a/src/main/scala/vexriscv/ip/DataCache.scala +++ b/src/main/scala/vexriscv/ip/DataCache.scala @@ -168,8 +168,9 @@ case class FenceFlags() extends Bundle { def forceAll(): Unit ={ List(SW,SR,SO,SI,PW,PR,PO,PI).foreach(_ := True) } - def clearAll(): Unit ={ + def clearFlags(): this.type ={ List(SW,SR,SO,SI,PW,PR,PO,PI).foreach(_ := False) + this } } @@ -400,7 +401,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave def toBmb(syncPendingMax : Int = 32, - timeoutCycles : Int = 16) : Bmb = new Area{ + timeoutCycles : Int = 32) : Bmb = new Area{ setCompositeName(DataCacheMemBus.this, "Bridge", true) val pipelinedMemoryBusConfig = p.getBmbParameter() val bus = Bmb(pipelinedMemoryBusConfig).setCompositeName(this,"toBmb", true) diff --git a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala index d9dcf698..b78f84f5 100644 --- a/src/main/scala/vexriscv/ip/fpu/FpuCore.scala +++ b/src/main/scala/vexriscv/ip/fpu/FpuCore.scala @@ -1547,15 +1547,22 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{ val expBase = muxDouble[UInt](input.format)(exponentF64Subnormal + 1)(exponentF32Subnormal + 1) val expDif = expBase -^ input.value.exponent val expSubnormal = !input.value.special && !expDif.msb - var discardCount = (expSubnormal ? expDif.resize(log2Up(p.internalMantissaSize) bits) | U(0)) + var discardCount = (expSubnormal ? expDif | U(0)) if (p.withDouble) when(input.format === FpuFormat.FLOAT) { discardCount \= discardCount + 29 } - val exactMask = (List(True) ++ (0 until p.internalMantissaSize + 1).map(_ < discardCount)).asBits.asUInt - val roundAdjusted = (True ## (manAggregate >> 1)) (discardCount) ## ((manAggregate & exactMask) =/= 0) + val discardCountTrunk = discardCount.resize(log2Up(p.internalMantissaSize) bits) + val exactMask = (List(True) ++ (0 until p.internalMantissaSize + 1).map(_ < discardCountTrunk)).asBits.asUInt + val roundAdjusted = (True ## (manAggregate >> 1)) (discardCountTrunk) ## ((manAggregate & exactMask) =/= 0) + val rneBit = CombInit((U"01" ## (manAggregate >> 2))(discardCountTrunk)) + when(discardCount >= widthOf(manAggregate)){ + rneBit := False + roundAdjusted(1) := False + exactMask := exactMask.maxValue + } val mantissaIncrement = !input.value.special && input.roundMode.mux( - FpuRoundMode.RNE -> (roundAdjusted(1) && (roundAdjusted(0) || (U"01" ## (manAggregate >> 2)) (discardCount))), + FpuRoundMode.RNE -> (roundAdjusted(1) && (roundAdjusted(0) || rneBit)), FpuRoundMode.RTZ -> False, FpuRoundMode.RDN -> (roundAdjusted =/= 0 && input.value.sign), FpuRoundMode.RUP -> (roundAdjusted =/= 0 && !input.value.sign), diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index cc283bc2..db63107e 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -863,7 +863,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep wakeService.askWake() } } - stoptime = out(debugMode && dcsr.stoptime).setName("stoptime") + stoptime = out(RegNext(debugMode && dcsr.stoptime) init(False)).setName("stoptime") //Very limited subset of the trigger spec val trigger = (debugTriggers > 0) generate new Area { @@ -1003,8 +1003,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep val medeleg = supervisorGen generate new Area { - val IAM, IAF, II, LAM, LAF, SAM, SAF, EU, ES, IPF, LPF, SPF = RegInit(False) - val mapping = mutable.LinkedHashMap(0 -> IAM, 1 -> IAF, 2 -> II, 4 -> LAM, 5 -> LAF, 6 -> SAM, 7 -> SAF, 8 -> EU, 9 -> ES, 12 -> IPF, 13 -> LPF, 15 -> SPF) + val IAM, IAF, II, BP, LAM, LAF, SAM, SAF, EU, ES, IPF, LPF, SPF = RegInit(False) + val mapping = mutable.LinkedHashMap(0 -> IAM, 1 -> IAF, 2 -> II, 3 -> BP, 4 -> LAM, 5 -> LAF, 6 -> SAM, 7 -> SAF, 8 -> EU, 9 -> ES, 12 -> IPF, 13 -> LPF, 15 -> SPF) } val mideleg = supervisorGen generate new Area { val ST, SE, SS = RegInit(False) @@ -1703,6 +1703,13 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep csrMapping.allowCsrSignal := True } } + //When no HPM + if(!csrMapping.mapping.contains(0xB03)){ + val masked = U(csrAddress & 0xF60) + when(arbitration.isValid && input(IS_CSR) && U(csrAddress(4 downto 0)) >= 3 && (masked === 0xB00 || masked === 0xC00 && !writeInstruction && privilege === 3 || U(csrAddress & 0xFE0) === 0x320)){ + csrMapping.allowCsrSignal := True + } + } illegalAccess clearWhen(csrMapping.allowCsrSignal) diff --git a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala index 623add8d..593eb911 100644 --- a/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala @@ -64,6 +64,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, var exceptionBus : Flow[ExceptionCause] = null var privilegeService : PrivilegeService = null var redoBranch : Flow[UInt] = null + var writesPending : Bool = null @dontName var dBusAccess : DBusAccess = null override def newDBusAccess(): DBusAccess = { @@ -270,6 +271,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, decoderService.add(FENCE, List(MEMORY_FENCE -> True)) decoderService.addDefault(MEMORY_FENCE_WR, False) decoderService.add(FENCE_I, List(MEMORY_FENCE_WR -> True)) + writesPending = Bool().setCompositeName(this, "writesPending") } } @@ -412,6 +414,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, when(arbitration.isValid && input(MEMORY_FENCE_WR) && cache.io.cpu.writesPending){ arbitration.haltItself := True } + writesPending := cache.io.cpu.writesPending } if(tightlyGen){ @@ -498,7 +501,7 @@ class DBusCachedPlugin(val config : DataCacheConfig, } when(!input(MEMORY_FENCE) || !arbitration.isFiring){ - cache.io.cpu.writeBack.fence.clearAll() + cache.io.cpu.writeBack.fence.clearFlags() } when(arbitration.isValid && (input(MEMORY_FENCE) || aquire)){ diff --git a/src/test/cpp/raw/privSpec/src/crt.S b/src/test/cpp/raw/privSpec/src/crt.S index f013ab28..b41119a5 100644 --- a/src/test/cpp/raw/privSpec/src/crt.S +++ b/src/test/cpp/raw/privSpec/src/crt.S @@ -11,6 +11,54 @@ _start: test1: li TEST_ID, 1 + + machine_setup_trap + csrr zero, ustatus + machine_handle_trap + + la x1, fail + csrw mtvec, x1 + + csrrw x0, mhpmcounter3, x0 + csrrw x0, mhpmcounter31, x0 + csrrw x0, mhpmevent3, x0 + csrrw x0, mhpmevent31, x0 + csrr x0, hpmcounter3 + csrr x0, hpmcounter31 + + machine_setup_trap + csrw hpmcounter3, x0 + machine_handle_trap + + machine_setup_trap + csrw hpmcounter31, x0 + machine_handle_trap + + machine_setup_trap; machine_to_user; csrrw x0, mhpmcounter3, x0; machine_handle_trap + machine_setup_trap; machine_to_user; csrrw x0, mhpmcounter31, x0; machine_handle_trap + machine_setup_trap; machine_to_user; csrrw x0, mhpmevent3, x0; machine_handle_trap + machine_setup_trap; machine_to_user; csrrw x0, mhpmevent31, x0; machine_handle_trap + machine_setup_trap; machine_to_user; csrr x0, hpmcounter3; machine_handle_trap + machine_setup_trap; machine_to_user; csrr x0, hpmcounter31; machine_handle_trap + + machine_setup_trap + machine_to_supervisor + ebreak + machine_handle_trap + csrr x1, mstatus + + li x1, 0x8 + csrw medeleg, x1 + machine_setup_trap + machine_to_supervisor + supervisor_setup_trap + ebreak + supervisor_handle_trap + csrr x1, sstatus + ecall + machine_handle_trap + + csrw misa, x0 //Test xtvec mode