mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-01-03 03:43:39 -05:00
Add onWrite/onRead/isWriting/isReading on the CsrPlugin
This commit is contained in:
parent
4ee2482cbf
commit
b7d8ed8a81
8 changed files with 156 additions and 84 deletions
|
@ -5,32 +5,30 @@ import vexriscv.plugin.{CsrInterface, Plugin}
|
|||
import vexriscv.{DecoderService, Stageable, VexRiscv}
|
||||
|
||||
|
||||
case class CustomCsrDemoArea(csrService : CsrInterface) extends Area{
|
||||
val instructionCounter = Reg(UInt(32 bits))
|
||||
val cycleCounter = Reg(UInt(32 bits))
|
||||
|
||||
csrService.rw(0xB04, instructionCounter)
|
||||
csrService.r(0xB05, cycleCounter)
|
||||
}
|
||||
|
||||
class CustomCsrDemoPlugin extends Plugin[VexRiscv]{
|
||||
var csrStruct : CustomCsrDemoArea = null
|
||||
|
||||
//Callback to setup the plugin and ask for different services
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
|
||||
val csrService = pipeline.service(classOf[CsrInterface])
|
||||
csrStruct = pipeline plug CustomCsrDemoArea(csrService)
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
csrStruct.cycleCounter := csrStruct.cycleCounter + 1
|
||||
when(writeBack.arbitration.isFiring) {
|
||||
csrStruct.instructionCounter := csrStruct.instructionCounter + 1
|
||||
pipeline plug new Area{
|
||||
val instructionCounter = Reg(UInt(32 bits))
|
||||
val cycleCounter = Reg(UInt(32 bits))
|
||||
|
||||
cycleCounter := cycleCounter + 1
|
||||
when(writeBack.arbitration.isFiring) {
|
||||
instructionCounter := instructionCounter + 1
|
||||
}
|
||||
|
||||
val csrService = pipeline.service(classOf[CsrInterface])
|
||||
csrService.rw(0xB04, instructionCounter)
|
||||
csrService.r(0xB05, cycleCounter)
|
||||
csrService.onWrite(0xB06){
|
||||
instructionCounter := 0
|
||||
}
|
||||
csrService.onRead(0xB07){
|
||||
instructionCounter := 0x40000000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,15 +121,21 @@ object CsrPluginConfig{
|
|||
}
|
||||
case class CsrWrite(that : Data, bitOffset : Int)
|
||||
case class CsrRead(that : Data , bitOffset : Int)
|
||||
case class CsrOnWrite(doThat :() => Unit)
|
||||
case class CsrOnRead(doThat : () => Unit)
|
||||
case class CsrMapping() extends CsrInterface{
|
||||
val mapping = mutable.HashMap[Int,ArrayBuffer[Any]]()
|
||||
def addMappingAt(address : Int,that : Any) = mapping.getOrElseUpdate(address,new ArrayBuffer[Any]) += that
|
||||
def r(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrRead(that,bitOffset))
|
||||
def w(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrWrite(that,bitOffset))
|
||||
override def r(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrRead(that,bitOffset))
|
||||
override def w(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrWrite(that,bitOffset))
|
||||
override def onWrite(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrOnWrite(() => body))
|
||||
override def onRead(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrOnRead(() => {body}))
|
||||
}
|
||||
|
||||
|
||||
trait CsrInterface{
|
||||
def onWrite(csrAddress : Int)(doThat : => Unit) : Unit
|
||||
def onRead(csrAddress : Int)(doThat : => Unit) : Unit
|
||||
def r(csrAddress : Int, bitOffset : Int, that : Data): Unit
|
||||
def w(csrAddress : Int, bitOffset : Int, that : Data): Unit
|
||||
def rw(csrAddress : Int, bitOffset : Int,that : Data): Unit ={
|
||||
|
@ -141,6 +147,21 @@ trait CsrInterface{
|
|||
def r [T <: Data](csrAddress : Int, thats : (Int, Data)*) : Unit = for(that <- thats) r(csrAddress,that._1, that._2)
|
||||
def rw[T <: Data](csrAddress : Int, that : T): Unit = rw(csrAddress,0,that)
|
||||
def r [T <: Data](csrAddress : Int, that : T): Unit = r(csrAddress,0,that)
|
||||
def isWriting(csrAddress : Int) : Bool = {
|
||||
val ret = False
|
||||
onWrite(csrAddress){
|
||||
ret := True
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
def isReading(csrAddress : Int) : Bool = {
|
||||
val ret = False
|
||||
onRead(csrAddress){
|
||||
ret := True
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -189,6 +210,8 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
|
||||
override def r(csrAddress: Int, bitOffset: Int, that: Data): Unit = csrMapping.r(csrAddress, bitOffset, that)
|
||||
override def w(csrAddress: Int, bitOffset: Int, that: Data): Unit = csrMapping.w(csrAddress, bitOffset, that)
|
||||
override def onWrite(csrAddress: Int)(body: => Unit): Unit = csrMapping.onWrite(csrAddress)(body)
|
||||
override def onRead(csrAddress: Int)(body: => Unit): Unit = csrMapping.onRead(csrAddress)(body)
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
|
@ -483,9 +506,11 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
val writeOpcode = (!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)))
|
||||
val writeInstruction = arbitration.isValid && input(IS_CSR) && writeOpcode
|
||||
val readInstruction = arbitration.isValid && input(IS_CSR) && !writeOpcode
|
||||
|
||||
arbitration.haltItself setWhen(writeInstruction && !readDataRegValid)
|
||||
val writeEnable = writeInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt && readDataRegValid
|
||||
val readEnable = readInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt
|
||||
|
||||
when(arbitration.isValid && input(IS_CSR)) {
|
||||
output(REGFILE_WRITE_DATA) := readData
|
||||
|
@ -493,33 +518,45 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
|
||||
//Translation of the csrMapping into real logic
|
||||
val csrAddress = input(INSTRUCTION)(csrRange)
|
||||
switch(csrAddress) {
|
||||
for ((address, jobs) <- csrMapping.mapping) {
|
||||
is(address) {
|
||||
val withWrite = jobs.exists(_.isInstanceOf[CsrWrite])
|
||||
val withRead = jobs.exists(_.isInstanceOf[CsrRead])
|
||||
if(withRead && withWrite) {
|
||||
illegalAccess := False
|
||||
} else {
|
||||
if (withWrite) illegalAccess.clearWhen(writeOpcode)
|
||||
if (withRead) illegalAccess.clearWhen(!writeOpcode)
|
||||
}
|
||||
Component.current.addPrePopTask(() => {
|
||||
switch(csrAddress) {
|
||||
for ((address, jobs) <- csrMapping.mapping) {
|
||||
is(address) {
|
||||
val withWrite = jobs.exists(j => j.isInstanceOf[CsrWrite] || j.isInstanceOf[CsrOnWrite])
|
||||
val withRead = jobs.exists(j => j.isInstanceOf[CsrRead] || j.isInstanceOf[CsrOnRead])
|
||||
if(withRead && withWrite) {
|
||||
illegalAccess := False
|
||||
} else {
|
||||
if (withWrite) illegalAccess.clearWhen(writeOpcode)
|
||||
if (withRead) illegalAccess.clearWhen(!writeOpcode)
|
||||
}
|
||||
|
||||
when(writeEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrWrite => element.that.assignFromBits(writeData(element.bitOffset, element.that.getBitsWidth bits))
|
||||
case element: CsrOnWrite =>
|
||||
element.doThat()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
when(writeEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrWrite => element.that.assignFromBits(writeData(element.bitOffset, element.that.getBitsWidth bits))
|
||||
case element: CsrRead if element.that.getBitsWidth != 0 => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrRead if element.that.getBitsWidth != 0 => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
|
||||
case _ =>
|
||||
when(readEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrOnRead =>
|
||||
element.doThat()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
illegalAccess setWhen(privilege.asUInt < csrAddress(9 downto 8).asUInt)
|
||||
illegalAccess setWhen(privilege.asUInt < csrAddress(9 downto 8).asUInt)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,34 +9,47 @@ Disassembly of section .crt_section:
|
|||
4: b04020f3 csrr ra,mhpmcounter4
|
||||
8: b0402173 csrr sp,mhpmcounter4
|
||||
c: b04021f3 csrr gp,mhpmcounter4
|
||||
10: 02114e63 blt sp,ra,4c <fail>
|
||||
14: 0221cc63 blt gp,sp,4c <fail>
|
||||
10: 06114863 blt sp,ra,80 <fail>
|
||||
14: 0621c663 blt gp,sp,80 <fail>
|
||||
18: 00200e13 li t3,2
|
||||
1c: 005dc0b7 lui ra,0x5dc
|
||||
20: 98a08093 addi ra,ra,-1654 # 5db98a <pass+0x5db932>
|
||||
20: 98a08093 addi ra,ra,-1654 # 5db98a <pass+0x5db8fe>
|
||||
24: b0409073 csrw mhpmcounter4,ra
|
||||
28: b0402173 csrr sp,mhpmcounter4
|
||||
2c: 02114063 blt sp,ra,4c <fail>
|
||||
2c: 04114a63 blt sp,ra,80 <fail>
|
||||
30: 00300e13 li t3,3
|
||||
34: b05020f3 csrr ra,mhpmcounter5
|
||||
38: b0502173 csrr sp,mhpmcounter5
|
||||
3c: b05021f3 csrr gp,mhpmcounter5
|
||||
40: 0020d663 ble sp,ra,4c <fail>
|
||||
44: 00315463 ble gp,sp,4c <fail>
|
||||
48: 0100006f j 58 <pass>
|
||||
40: 0420d063 ble sp,ra,80 <fail>
|
||||
44: 02315e63 ble gp,sp,80 <fail>
|
||||
48: 00400e13 li t3,4
|
||||
4c: b0609073 csrw mhpmcounter6,ra
|
||||
50: b04020f3 csrr ra,mhpmcounter4
|
||||
54: 10000113 li sp,256
|
||||
58: 0220f463 bleu sp,ra,80 <fail>
|
||||
5c: 00500e13 li t3,5
|
||||
60: b07020f3 csrr ra,mhpmcounter7
|
||||
64: b04020f3 csrr ra,mhpmcounter4
|
||||
68: 40000137 lui sp,0x40000
|
||||
6c: 10010113 addi sp,sp,256 # 40000100 <pass+0x40000074>
|
||||
70: 400001b7 lui gp,0x40000
|
||||
74: 0020f663 bleu sp,ra,80 <fail>
|
||||
78: 0030e463 bltu ra,gp,80 <fail>
|
||||
7c: 0100006f j 8c <pass>
|
||||
|
||||
0000004c <fail>:
|
||||
4c: f0100137 lui sp,0xf0100
|
||||
50: f2410113 addi sp,sp,-220 # f00fff24 <pass+0xf00ffecc>
|
||||
54: 01c12023 sw t3,0(sp)
|
||||
00000080 <fail>:
|
||||
80: f0100137 lui sp,0xf0100
|
||||
84: f2410113 addi sp,sp,-220 # f00fff24 <pass+0xf00ffe98>
|
||||
88: 01c12023 sw t3,0(sp)
|
||||
|
||||
00000058 <pass>:
|
||||
58: f0100137 lui sp,0xf0100
|
||||
5c: f2010113 addi sp,sp,-224 # f00fff20 <pass+0xf00ffec8>
|
||||
60: 00012023 sw zero,0(sp)
|
||||
64: 00000013 nop
|
||||
68: 00000013 nop
|
||||
6c: 00000013 nop
|
||||
70: 00000013 nop
|
||||
74: 00000013 nop
|
||||
78: 00000013 nop
|
||||
0000008c <pass>:
|
||||
8c: f0100137 lui sp,0xf0100
|
||||
90: f2010113 addi sp,sp,-224 # f00fff20 <pass+0xf00ffe94>
|
||||
94: 00012023 sw zero,0(sp)
|
||||
98: 00000013 nop
|
||||
9c: 00000013 nop
|
||||
a0: 00000013 nop
|
||||
a4: 00000013 nop
|
||||
a8: 00000013 nop
|
||||
ac: 00000013 nop
|
||||
|
|
Binary file not shown.
|
@ -1,9 +1,12 @@
|
|||
:10000000130E1000F32040B0732140B0F32140B034
|
||||
:10001000634E110263CC2102130E2000B7C05D00B5
|
||||
:100020009380A098739040B0732140B06340110258
|
||||
:100010006348110663C62106130E2000B7C05D00B9
|
||||
:100020009380A098739040B0732140B0634A11044C
|
||||
:10003000130E3000F32050B0732150B0F32150B0B4
|
||||
:1000400063D62000635431006F000001370110F0C7
|
||||
:10005000130141F22320C101370110F0130101F215
|
||||
:100060002320010013000000130000001300000013
|
||||
:0C0070001300000013000000130000004B
|
||||
:1000400063D02004635E3102130E4000739060B0F1
|
||||
:10005000F32040B01301001063F42002130E50008F
|
||||
:10006000F32070B0F32040B03701004013010110BD
|
||||
:10007000B701004063F6200063E430006F00000128
|
||||
:10008000370110F0130141F22320C101370110F0B4
|
||||
:10009000130101F2232001001300000013000000EF
|
||||
:1000A0001300000013000000130000001300000004
|
||||
:00000001FF
|
||||
|
|
|
@ -8,23 +8,23 @@ onChipRam 0x0000000000000000 0x0000000000002000 w !xr
|
|||
Linker script and memory map
|
||||
|
||||
LOAD build/src/crt.o
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/rv32i/ilp32/libgcc.a
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.2.0/rv32i/ilp32/libgcc.a
|
||||
START GROUP
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libgloss.a
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.2.0/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.2.0/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libgloss.a
|
||||
END GROUP
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/rv32i/ilp32/libgcc.a
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.2.0/rv32i/ilp32/libgcc.a
|
||||
0x0000000000000000 . = 0x0
|
||||
|
||||
.crt_section 0x0000000000000000 0x7c
|
||||
.crt_section 0x0000000000000000 0xb0
|
||||
0x0000000000000000 . = ALIGN (0x4)
|
||||
*crt.o(.text)
|
||||
.text 0x0000000000000000 0x7c build/src/crt.o
|
||||
.text 0x0000000000000000 0xb0 build/src/crt.o
|
||||
0x0000000000000000 _start
|
||||
OUTPUT(build/custom_csr.elf elf32-littleriscv)
|
||||
|
||||
.data 0x000000000000007c 0x0
|
||||
.data 0x000000000000007c 0x0 build/src/crt.o
|
||||
.data 0x00000000000000b0 0x0
|
||||
.data 0x00000000000000b0 0x0 build/src/crt.o
|
||||
|
||||
.bss 0x000000000000007c 0x0
|
||||
.bss 0x000000000000007c 0x0 build/src/crt.o
|
||||
.bss 0x00000000000000b0 0x0
|
||||
.bss 0x00000000000000b0 0x0 build/src/crt.o
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
@00000000
|
||||
13 0E 10 00 F3 20 40 B0 73 21 40 B0 F3 21 40 B0
|
||||
63 4E 11 02 63 CC 21 02 13 0E 20 00 B7 C0 5D 00
|
||||
93 80 A0 98 73 90 40 B0 73 21 40 B0 63 40 11 02
|
||||
63 48 11 06 63 C6 21 06 13 0E 20 00 B7 C0 5D 00
|
||||
93 80 A0 98 73 90 40 B0 73 21 40 B0 63 4A 11 04
|
||||
13 0E 30 00 F3 20 50 B0 73 21 50 B0 F3 21 50 B0
|
||||
63 D6 20 00 63 54 31 00 6F 00 00 01 37 01 10 F0
|
||||
13 01 41 F2 23 20 C1 01 37 01 10 F0 13 01 01 F2
|
||||
23 20 01 00 13 00 00 00 13 00 00 00 13 00 00 00
|
||||
13 00 00 00 13 00 00 00 13 00 00 00
|
||||
63 D0 20 04 63 5E 31 02 13 0E 40 00 73 90 60 B0
|
||||
F3 20 40 B0 13 01 00 10 63 F4 20 02 13 0E 50 00
|
||||
F3 20 70 B0 F3 20 40 B0 37 01 00 40 13 01 01 10
|
||||
B7 01 00 40 63 F6 20 00 63 E4 30 00 6F 00 00 01
|
||||
37 01 10 F0 13 01 41 F2 23 20 C1 01 37 01 10 F0
|
||||
13 01 01 F2 23 20 01 00 13 00 00 00 13 00 00 00
|
||||
13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
|
||||
|
|
|
@ -26,6 +26,24 @@ _start:
|
|||
bge x1, x2, fail
|
||||
bge x2, x3, fail
|
||||
|
||||
|
||||
|
||||
//Test 4
|
||||
li x28, 4
|
||||
csrw 0xB06, x1
|
||||
csrr x1, 0xB04
|
||||
li x2, 0x100
|
||||
bgeu x1, x2, fail
|
||||
|
||||
//Test 5
|
||||
li x28, 5
|
||||
csrr x1, 0xB07
|
||||
csrr x1, 0xB04
|
||||
li x2, 0x40000100
|
||||
li x3, 0x40000000
|
||||
bgeu x1, x2, fail
|
||||
bltu x1, x3, fail
|
||||
|
||||
j pass
|
||||
|
||||
fail: //x28 => error code
|
||||
|
|
Loading…
Reference in a new issue