From b7d8ed8a814ea4bffd652751ad21647ef27832a3 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 1 Feb 2018 21:28:28 +0100 Subject: [PATCH] Add onWrite/onRead/isWriting/isReading on the CsrPlugin --- .../vexriscv/demo/CustomCsrDemoPlugin.scala | 38 ++++----- .../scala/vexriscv/plugin/CsrPlugin.scala | 79 +++++++++++++----- .../custom/custom_csr/build/custom_csr.asm | 55 +++++++----- .../custom/custom_csr/build/custom_csr.elf | Bin 4592 -> 4644 bytes .../custom/custom_csr/build/custom_csr.hex | 15 ++-- .../custom/custom_csr/build/custom_csr.map | 20 ++--- .../cpp/custom/custom_csr/build/custom_csr.v | 15 ++-- src/test/cpp/custom/custom_csr/src/crt.S | 18 ++++ 8 files changed, 156 insertions(+), 84 deletions(-) diff --git a/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala b/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala index d824dc8..97aecbe 100644 --- a/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala +++ b/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala @@ -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 + } } } } diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 05c5379..f859311 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -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) + }) } } } diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.asm b/src/test/cpp/custom/custom_csr/build/custom_csr.asm index 67956bc..cf186d1 100644 --- a/src/test/cpp/custom/custom_csr/build/custom_csr.asm +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.asm @@ -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 - 14: 0221cc63 blt gp,sp,4c + 10: 06114863 blt sp,ra,80 + 14: 0621c663 blt gp,sp,80 18: 00200e13 li t3,2 1c: 005dc0b7 lui ra,0x5dc - 20: 98a08093 addi ra,ra,-1654 # 5db98a + 20: 98a08093 addi ra,ra,-1654 # 5db98a 24: b0409073 csrw mhpmcounter4,ra 28: b0402173 csrr sp,mhpmcounter4 - 2c: 02114063 blt sp,ra,4c + 2c: 04114a63 blt sp,ra,80 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 - 44: 00315463 ble gp,sp,4c - 48: 0100006f j 58 + 40: 0420d063 ble sp,ra,80 + 44: 02315e63 ble gp,sp,80 + 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 + 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 + 70: 400001b7 lui gp,0x40000 + 74: 0020f663 bleu sp,ra,80 + 78: 0030e463 bltu ra,gp,80 + 7c: 0100006f j 8c -0000004c : - 4c: f0100137 lui sp,0xf0100 - 50: f2410113 addi sp,sp,-220 # f00fff24 - 54: 01c12023 sw t3,0(sp) +00000080 : + 80: f0100137 lui sp,0xf0100 + 84: f2410113 addi sp,sp,-220 # f00fff24 + 88: 01c12023 sw t3,0(sp) -00000058 : - 58: f0100137 lui sp,0xf0100 - 5c: f2010113 addi sp,sp,-224 # f00fff20 - 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 : + 8c: f0100137 lui sp,0xf0100 + 90: f2010113 addi sp,sp,-224 # f00fff20 + 94: 00012023 sw zero,0(sp) + 98: 00000013 nop + 9c: 00000013 nop + a0: 00000013 nop + a4: 00000013 nop + a8: 00000013 nop + ac: 00000013 nop diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.elf b/src/test/cpp/custom/custom_csr/build/custom_csr.elf index 207dadf526c713363b86288271386055d6ad911b..61da8ff4515c279dbc1aacc9ff70e78c3ba321bb 100755 GIT binary patch delta 219 zcmeyMyhLS!0%OcXMP=3v3=9k#HhP}mulEpSOFpK^Cd{Y6u>C+R!{mkqGm0lTY$#TA z*pTcc$Rf;V!0=fi0LTy6@EM4cFDS4i#~CsS^EogSPe|DCS;1k0Fe8IN@)rf5SO8FM z0a(nOk-xgJfFYlOfzg~%;Da!u<0oZ>gJAaL7=aMM2B2#ofRRBA q$mp4TP+&3RhRLad%0RMHP@PFYaPlTWH3=g@1_lk7S|H5`Wdi`dTsaW{ delta 135 zcmZ3Y@up&J}U$O`2ia~199>-1%~7h!^zbGnSwq*Lm+^WK@7-F=Nf-nS#nd ea<8B|>m30G2Bpb@Lc){(2nsO$6PU~=BnAM{E++5* diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.hex b/src/test/cpp/custom/custom_csr/build/custom_csr.hex index d2f4954..16b3a39 100644 --- a/src/test/cpp/custom/custom_csr/build/custom_csr.hex +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.hex @@ -1,9 +1,12 @@ :10000000130E1000F32040B0732140B0F32140B034 -:10001000634E110263CC2102130E2000B7C05D00B5 -:100020009380A098739040B0732140B06340110258 +:100010006348110663C62106130E2000B7C05D00B9 +:100020009380A098739040B0732140B0634A11044C :10003000130E3000F32050B0732150B0F32150B0B4 -:1000400063D62000635431006F000001370110F0C7 -:10005000130141F22320C101370110F0130101F215 -:100060002320010013000000130000001300000013 -:0C0070001300000013000000130000004B +:1000400063D02004635E3102130E4000739060B0F1 +:10005000F32040B01301001063F42002130E50008F +:10006000F32070B0F32040B03701004013010110BD +:10007000B701004063F6200063E430006F00000128 +:10008000370110F0130141F22320C101370110F0B4 +:10009000130101F2232001001300000013000000EF +:1000A0001300000013000000130000001300000004 :00000001FF diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.map b/src/test/cpp/custom/custom_csr/build/custom_csr.map index d9ece69..ec2b738 100644 --- a/src/test/cpp/custom/custom_csr/build/custom_csr.map +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.map @@ -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 diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.v b/src/test/cpp/custom/custom_csr/build/custom_csr.v index 0e434cb..81c1861 100755 --- a/src/test/cpp/custom/custom_csr/build/custom_csr.v +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.v @@ -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 diff --git a/src/test/cpp/custom/custom_csr/src/crt.S b/src/test/cpp/custom/custom_csr/src/crt.S index 6f211c3..8b7e43b 100644 --- a/src/test/cpp/custom/custom_csr/src/crt.S +++ b/src/test/cpp/custom/custom_csr/src/crt.S @@ -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