Add onWrite/onRead/isWriting/isReading on the CsrPlugin

This commit is contained in:
Dolu1990 2018-02-01 21:28:28 +01:00
parent 4ee2482cbf
commit b7d8ed8a81
8 changed files with 156 additions and 84 deletions

View file

@ -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
}
}
}
}

View file

@ -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)
})
}
}
}

View file

@ -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

View file

@ -1,9 +1,12 @@
:10000000130E1000F32040B0732140B0F32140B034
:10001000634E110263CC2102130E2000B7C05D00B5
:100020009380A098739040B0732140B06340110258
:100010006348110663C62106130E2000B7C05D00B9
:100020009380A098739040B0732140B0634A11044C
:10003000130E3000F32050B0732150B0F32150B0B4
:1000400063D62000635431006F000001370110F0C7
:10005000130141F22320C101370110F0130101F215
:100060002320010013000000130000001300000013
:0C0070001300000013000000130000004B
:1000400063D02004635E3102130E4000739060B0F1
:10005000F32040B01301001063F42002130E50008F
:10006000F32070B0F32040B03701004013010110BD
:10007000B701004063F6200063E430006F00000128
:10008000370110F0130141F22320C101370110F0B4
:10009000130101F2232001001300000013000000EF
:1000A0001300000013000000130000001300000004
:00000001FF

View file

@ -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

View file

@ -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

View file

@ -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