Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perf counters #388

Merged
merged 20 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
- [YamlPlugin](#yamlplugin)
- [FpuPlugin](#fpuplugin)
- [AesPlugin](#aesplugin)
- [CounterPlugin](#counterplugin)



Expand Down Expand Up @@ -1319,3 +1320,21 @@ It was also ported on libressl via the following patch :
<https://github.com/SpinalHDL/buildroot-spinal-saxon/blob/main/patches/libressl/0000-vexriscv-aes.patch>

Speed up of 4 was observed in libressl running in linux. <https://github.com/SpinalHDL/SaxonSoc/pull/53#issuecomment-730133020>

#### CounterPlugin

Provides performance-counter and time CSRs.

Here is how to provide a custom event condition (which can then be configured by code):
In setup phase
```scala
val ctrSrv = pipeline.service(classOf[CounterService])
ctrSrv.createEvent(eventId)
```
In build phase
```scala
val ctrSrv = pipeline.service(classOf[CounterService])
ctrSrv.getCondition(eventId) := boolCond
```
eventId is BigInt, but only events between 0 and 2 ** XLEN (excluding boundaries) can be selected by cpu.
The configured counter counts clockcycles with boolCond asserted.
6 changes: 6 additions & 0 deletions src/main/scala/vexriscv/Riscv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ object Riscv{
def MCYCLEH = 0xB80 // MRW Upper 32 bits of mcycle, RV32I only.
def MINSTRETH = 0xB82 // MRW Upper 32 bits of minstret, RV32I only.
val MCOUNTEREN = 0x306
val MCOUNTER = 0xB03 // MRW Base address for mhpmcounterX.
val MCOUNTERH = 0xB83 // MRW Base address for mhpmcounterXh, RV32I only.
val MCOUNTINHIBIT = 0x320
val MEVENT = 0x323 // MRW Base address for mhpmeventX.

val SSTATUS = 0x100
val SIE = 0x104
Expand All @@ -234,6 +238,8 @@ object Riscv{
def UTIMEH = 0xC81
def UINSTRET = 0xC02 // UR Machine instructions-retired counter.
def UINSTRETH = 0xC82 // UR Upper 32 bits of minstret, RV32I only.
val UCOUNTER = 0xC03 // UR Base address for hpmcounter.
val UCOUNTERH = 0xC83 // UR Base address for hpmcounterXh, RV32I only.

val FFLAGS = 0x1
val FRM = 0x2
Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/vexriscv/Services.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ trait PrivilegeService{
def isUser() : Bool
def isSupervisor() : Bool
def isMachine() : Bool
def hasUser() : Boolean
def hasSupervisor() : Boolean
def forceMachine() : Unit

def encodeBits() : Bits = {
Expand All @@ -70,6 +72,8 @@ case class PrivilegeServiceDefault() extends PrivilegeService{
override def isUser(): Bool = False
override def isSupervisor(): Bool = False
override def isMachine(): Bool = True
override def hasUser(): Boolean = false
override def hasSupervisor(): Boolean = false
override def forceMachine(): Unit = {}
}

Expand Down Expand Up @@ -143,4 +147,4 @@ class CacheReport {

class DebugReport {
@BeanProperty var hardwareBreakpointCount = 0
}
}
6 changes: 1 addition & 5 deletions src/main/scala/vexriscv/demo/Briey.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,8 @@ object BrieyConfig{
mscratchGen = false,
mcauseAccess = CsrAccess.READ_ONLY,
mbadaddrAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
wfiGenAsWait = false
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/vexriscv/demo/GenFull.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ object GenFull extends App{
earlyBranch = false,
catchAddressMisaligned = true
),
new CounterPlugin(CounterPluginConfig()),
new YamlPlugin("cpu0.yaml")
)
)
Expand Down
6 changes: 1 addition & 5 deletions src/main/scala/vexriscv/demo/VexRiscvAhbLite3.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,8 @@ object VexRiscvAhbLite3{
mscratchGen = false,
mcauseAccess = CsrAccess.READ_ONLY,
mbadaddrAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.NONE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to still keep those option ?
I know that would be redundant to the CounterPlugin implementation, but that would preserve backward compatibility without any disruption. (not break users setups)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is a general comment, so would also apply for the other demo)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The options are still available in the CSRPlugin. I removed them from here and other places, since CsrAccess.NONE was and is the default value for these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be possible to revert all the removals of "mcycleAccess = CsrAccess.NONE" and similar things ?

They are there to make it clear to the user that it isn't included, and that if they want they can just turn it on there.

minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
wfiGenAsWait = false
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
6 changes: 1 addition & 5 deletions src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,8 @@ object VexRiscvAvalonForSim{
mscratchGen = false,
mcauseAccess = CsrAccess.READ_ONLY,
mbadaddrAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
wfiGenAsWait = false
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,8 @@ object VexRiscvAvalonWithIntegratedJtag{
mscratchGen = false,
mcauseAccess = CsrAccess.READ_ONLY,
mbadaddrAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
wfiGenAsWait = false
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
19 changes: 17 additions & 2 deletions src/main/scala/vexriscv/demo/VexRiscvAxi4LinuxPlicClint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,20 @@ object VexRiscvAxi4LinuxPlicClint{
earlyBranch = false,
catchAddressMisaligned = true
),
new CsrPlugin(CsrPluginConfig.openSbi(mhartid = 0, misa = Riscv.misaToInt(s"ima")).copy(utimeAccess = CsrAccess.READ_ONLY)),
new CsrPlugin(CsrPluginConfig.openSbi(mhartid = 0, misa = Riscv.misaToInt(s"ima"))),
new CounterPlugin(CounterPluginConfig(
NumOfCounters = 0,
mcycleAccess = CsrAccess.NONE,
ucycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE,
mcounterenAccess = CsrAccess.NONE,
scounterenAccess = CsrAccess.NONE,
mcounterAccess = CsrAccess.NONE,
ucounterAccess = CsrAccess.NONE,
meventAccess = CsrAccess.NONE,
mcountinhibitAccess = CsrAccess.NONE
)),
new YamlPlugin("cpu0.yaml")
)
)
Expand Down Expand Up @@ -152,7 +165,9 @@ object VexRiscvAxi4LinuxPlicClint{
plugin.softwareInterrupt setAsDirectionLess() := cpu.clintCtrl.io.softwareInterrupt(0)
plugin.externalInterrupt setAsDirectionLess() := cpu.plicCtrl.io.targets(0)
plugin.externalInterruptS setAsDirectionLess() := cpu.plicCtrl.io.targets(1)
plugin.utime setAsDirectionLess() := cpu.clintCtrl.io.time
}
case plugin: CounterPlugin => {
plugin.time setAsDirectionLess() := cpu.clintCtrl.io.time
}
case _ =>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,8 @@ object VexRiscvAxi4WithIntegratedJtag{
mscratchGen = false,
mcauseAccess = CsrAccess.READ_ONLY,
mbadaddrAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
ecallGen = false,
wfiGenAsWait = false,
ucycleAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE
wfiGenAsWait = false
)
),
new YamlPlugin("cpu0.yaml")
Expand Down
26 changes: 16 additions & 10 deletions src/main/scala/vexriscv/demo/smp/VexRiscvSmpCluster.scala
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class VexRiscvSmpClusterWithPeripherals(p : VexRiscvSmpClusterParameter) extends
plic.addTarget(core.cpu.externalSupervisorInterrupt)
List(clint.logic, core.cpu.logic).produce {
for (plugin <- core.cpu.config.plugins) plugin match {
case plugin: CsrPlugin if plugin.utime != null => plugin.utime := clint.logic.io.time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, would need to preserve that feature in the CsrPlugin. (even if that is a duplication) to not break people code

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature is still in CSRPlugin, even if disabled when CounterService is present (which in this demo it is), so it should break no existing code which uses the Counters in CsrPlugin.

case plugin: CounterPlugin if plugin.time != null => plugin.time := clint.logic.io.time
case _ =>
}
}
Expand Down Expand Up @@ -204,15 +204,11 @@ object VexRiscvSmpClusterGen {

val misa = Riscv.misaToInt(s"ima${if(withFloat) "f" else ""}${if(withDouble) "d" else ""}${if(rvc) "c" else ""}${if(withSupervisor) "s" else ""}")
val csrConfig = if(withSupervisor){
var c = CsrPluginConfig.openSbi(mhartid = hartId, misa = misa).copy(utimeAccess = CsrAccess.READ_ONLY, withPrivilegedDebug = privilegedDebug)
var c = CsrPluginConfig.openSbi(mhartid = hartId, misa = misa).copy(withPrivilegedDebug = privilegedDebug)
if(csrFull){
c = c.copy(
mcauseAccess = CsrAccess.READ_WRITE,
mbadaddrAccess = CsrAccess.READ_WRITE,
ucycleAccess = CsrAccess.READ_ONLY,
uinstretAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.READ_WRITE,
minstretAccess = CsrAccess.READ_WRITE
mbadaddrAccess = CsrAccess.READ_WRITE
)
}
c
Expand All @@ -232,13 +228,10 @@ object VexRiscvSmpClusterGen {
mscratchGen = forceMscratch,
mcauseAccess = CsrAccess.READ_ONLY,
mbadaddrAccess = CsrAccess.READ_ONLY,
mcycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
ecallGen = true,
ebreakGen = true,
wfiGenAsWait = false,
wfiGenAsNop = true,
ucycleAccess = CsrAccess.NONE,
withPrivilegedDebug = privilegedDebug
)
}
Expand Down Expand Up @@ -358,6 +351,19 @@ object VexRiscvSmpClusterGen {
catchAddressMisaligned = true,
fenceiGenAsAJump = false
),
new CounterPlugin(if(csrFull) CounterPluginConfig() else CounterPluginConfig(
NumOfCounters = 0,
mcycleAccess = CsrAccess.NONE,
ucycleAccess = CsrAccess.NONE,
minstretAccess = CsrAccess.NONE,
uinstretAccess = CsrAccess.NONE,
mcounterenAccess = CsrAccess.NONE,
scounterenAccess = CsrAccess.NONE,
mcounterAccess = CsrAccess.NONE,
ucounterAccess = CsrAccess.NONE,
meventAccess = CsrAccess.NONE,
mcountinhibitAccess = CsrAccess.NONE
)),
new YamlPlugin(s"cpu$hartId.yaml")
)
)
Expand Down