MachineCsr pass simple interrupt and exception tests
This commit is contained in:
parent
ed0660237f
commit
72d65841d2
|
@ -26,7 +26,7 @@ case class MachineCsrConfig(
|
|||
marchid : BigInt,
|
||||
mimpid : BigInt,
|
||||
mhartid : BigInt,
|
||||
misaExtensions : Int,
|
||||
misaExtensionsInit : Int,
|
||||
misaAccess : CsrAccess,
|
||||
mtvecAccess : CsrAccess,
|
||||
mtvecInit : BigInt,
|
||||
|
@ -151,18 +151,22 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
//Define CSR mapping utilities
|
||||
val csrMapping = new CsrMapping()
|
||||
implicit class CsrAccessPimper(csrAccess : CsrAccess){
|
||||
def apply(csrAddress : Int, thats : (Int, Data)*) : Unit = csrAccess match{
|
||||
case `WRITE_ONLY` | `READ_WRITE` => for(that <- thats) csrMapping.w(csrAddress,that._1, that._2)
|
||||
case `READ_ONLY` | `READ_WRITE` => for(that <- thats) csrMapping.r(csrAddress,that._1, that._2)
|
||||
def apply(csrAddress : Int, thats : (Int, Data)*) : Unit = {
|
||||
if(csrAccess == `WRITE_ONLY` || csrAccess == `READ_WRITE`) for(that <- thats) csrMapping.w(csrAddress,that._1, that._2)
|
||||
if(csrAccess == `READ_ONLY` || csrAccess == `READ_WRITE`) for(that <- thats) csrMapping.r(csrAddress,that._1, that._2)
|
||||
}
|
||||
def apply(csrAddress : Int, that : Data) : Unit = csrAccess match{
|
||||
case `WRITE_ONLY` | `READ_WRITE` => csrMapping.w(csrAddress, 0, that)
|
||||
case `READ_ONLY` | `READ_WRITE` => csrMapping.r(csrAddress, 0, that)
|
||||
def apply(csrAddress : Int, that : Data) : Unit = {
|
||||
if(csrAccess == `WRITE_ONLY` || csrAccess == `READ_WRITE`) csrMapping.w(csrAddress, 0, that)
|
||||
if(csrAccess == `READ_ONLY` || csrAccess == `READ_WRITE`) csrMapping.r(csrAddress, 0, that)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Define CSR registers
|
||||
val misa = new Area{
|
||||
val base = Reg(UInt(2 bits)) init(U"01")
|
||||
val extensions = Reg(Bits(26 bits)) init(misaExtensionsInit)
|
||||
}
|
||||
val mtvec = RegInit(U(mtvecInit,xlen bits))
|
||||
val mepc = Reg(UInt(xlen bits))
|
||||
val mstatus = new Area{
|
||||
|
@ -182,7 +186,7 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
val exceptionCode = Reg(UInt(exceptionCodeWidth bits))
|
||||
}
|
||||
val mbadaddr = Reg(UInt(xlen bits))
|
||||
val mcycle = Reg(UInt(64 bits)) randBoot()
|
||||
val mcycle = Reg(UInt(64 bits)) randBoot()
|
||||
val minstret = Reg(UInt(64 bits)) randBoot()
|
||||
|
||||
|
||||
|
@ -193,14 +197,14 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
if(mimpid != null) READ_ONLY(CSR.MIMPID , U(mimpid ))
|
||||
if(mhartid != null) READ_ONLY(CSR.MHARTID , U(mhartid ))
|
||||
|
||||
misaAccess(CSR.MISA, xlen-2 -> U"01" , 0 -> U(misaExtensions))
|
||||
misaAccess(CSR.MISA, xlen-2 -> misa.base , 0 -> misa.extensions)
|
||||
READ_ONLY(CSR.MIP, 11 -> mip.MEIP, 7 -> mip.MTIP)
|
||||
READ_WRITE(CSR.MIP, 3 -> mip.MSIP)
|
||||
READ_WRITE(CSR.MIE, 11 -> mie.MEIE, 7 -> mie.MTIE, 3 -> mie.MSIE)
|
||||
|
||||
mtvecAccess(CSR.MTVEC, mtvec)
|
||||
mepcAccess(CSR.MEPC, mepc)
|
||||
READ_ONLY(CSR.MSTATUS, 7 -> mstatus.MPIE, 3 -> mstatus.MIE)
|
||||
READ_WRITE(CSR.MSTATUS, 7 -> mstatus.MPIE, 3 -> mstatus.MIE)
|
||||
if(mscratchGen) READ_WRITE(CSR.MSCRATCH, mscratch)
|
||||
mcauseAccess(CSR.MCAUSE, xlen-1 -> mcause.interrupt, 0 -> mcause.exceptionCode)
|
||||
mbadaddrAccess(CSR.MBADADDR, mbadaddr)
|
||||
|
@ -222,7 +226,7 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
//Used to make the pipeline empty softly (for interrupts)
|
||||
val pipelineLiberator = new Area{
|
||||
val enable = False
|
||||
decode.arbitration.haltIt setWhen(enable)
|
||||
prefetch.arbitration.haltIt setWhen(enable)
|
||||
val done = ! List(fetch, decode, execute, memory, writeBack).map(_.arbitration.isValid).orR
|
||||
}
|
||||
|
||||
|
@ -295,6 +299,7 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
when(memory.arbitration.isFiring && memory.input(ENV_CTRL) === EnvCtrlEnum.MRET){
|
||||
jumpInterface.valid := True
|
||||
jumpInterface.payload := mepc
|
||||
execute.arbitration.flushIt := True
|
||||
mstatus.MIE := mstatus.MPIE
|
||||
}
|
||||
|
||||
|
@ -305,41 +310,39 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
|
||||
val imm = IMM(input(INSTRUCTION))
|
||||
|
||||
val writeEnable = !((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "10" && imm.z === 0))
|
||||
val readEnable = input(INSTRUCTION)(rdRange) =/= 0
|
||||
val writeEnable = arbitration.isValid && !arbitration.isStuckByOthers && input(IS_CSR) &&
|
||||
(!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "10" && imm.z === 0)))
|
||||
|
||||
|
||||
val writeSrc = input(INSTRUCTION)(14) ? imm.z.asBits.resized | input(SRC1)
|
||||
val readData = B(0, 32 bits)
|
||||
val writeData = input(INSTRUCTION)(12).mux(
|
||||
val writeData = input(INSTRUCTION)(13).mux(
|
||||
False -> writeSrc,
|
||||
True -> Mux(input(INSTRUCTION)(13), readData & ~writeSrc, readData | writeSrc)
|
||||
True -> Mux(input(INSTRUCTION)(12), readData & ~writeSrc, readData | writeSrc)
|
||||
)
|
||||
|
||||
when(arbitration.isValid && input(IS_CSR)) {
|
||||
when(writeEnable) {
|
||||
output(REGFILE_WRITE_DATA) := writeData
|
||||
}
|
||||
output(REGFILE_WRITE_DATA) := readData
|
||||
}
|
||||
|
||||
|
||||
//Translation of the csrMapping into real logic
|
||||
val csrAddress = input(INSTRUCTION)(csrRange)
|
||||
when(arbitration.isValid && input(IS_CSR)) {
|
||||
for ((address, jobs) <- csrMapping.mapping) {
|
||||
when(csrAddress === address) {
|
||||
when(writeEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrWrite => element.that.assignFromBits(writeData(element.bitOffset, element.that.getBitsWidth bits))
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
for ((address, jobs) <- csrMapping.mapping) {
|
||||
when(csrAddress === address) {
|
||||
when(writeEnable) {
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrRead => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
|
||||
case element: CsrWrite => element.that.assignFromBits(writeData(element.bitOffset, element.that.getBitsWidth bits))
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
for (element <- jobs) element match {
|
||||
case element: CsrRead => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class Stage() extends Area{
|
|||
val input,inputDefault = key()
|
||||
inputsDefault(key.asInstanceOf[Stageable[Data]]) = inputDefault
|
||||
input := inputDefault
|
||||
input.setPartialName(this,"input_" + key.getName())
|
||||
input.setPartialName(this, key.getName())
|
||||
}).asInstanceOf[T]
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,11 @@ class Stage() extends Area{
|
|||
val output,outputDefault = key()
|
||||
outputsDefault(key.asInstanceOf[Stageable[Data]]) = outputDefault
|
||||
output := outputDefault
|
||||
output.setPartialName(this,"output_" + key.getName())
|
||||
output //.setPartialName(this,"output_" + key.getName())
|
||||
}).asInstanceOf[T]
|
||||
}
|
||||
|
||||
def insert[T <: Data](key : Stageable[T]) : T = inserts.getOrElseUpdate(key.asInstanceOf[Stageable[Data]],outsideCondScope(key())).asInstanceOf[T].setPartialName(this,key.getName())
|
||||
def insert[T <: Data](key : Stageable[T]) : T = inserts.getOrElseUpdate(key.asInstanceOf[Stageable[Data]],outsideCondScope(key())).asInstanceOf[T] //.setPartialName(this,key.getName())
|
||||
// def apply[T <: Data](key : Stageable[T]) : T = ???
|
||||
|
||||
|
||||
|
|
|
@ -37,10 +37,10 @@ object TopLevel {
|
|||
marchid = 22,
|
||||
mimpid = 33,
|
||||
mhartid = 44,
|
||||
misaExtensions = 66,
|
||||
misaExtensionsInit = 66,
|
||||
misaAccess = READ_WRITE,
|
||||
mtvecAccess = READ_WRITE,
|
||||
mtvecInit = 0x80000004l,
|
||||
mtvecInit = 0x00000020l,
|
||||
mepcAccess = READ_WRITE,
|
||||
mscratchGen = true,
|
||||
mcauseAccess = READ_WRITE,
|
||||
|
|
|
@ -351,6 +351,32 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class TestX28 : public Workspace{
|
||||
public:
|
||||
uint32_t refIndex = 0;
|
||||
uint32_t *ref;
|
||||
uint32_t refSize;
|
||||
|
||||
TestX28(string name, uint32_t *ref, uint32_t refSize) : Workspace(name) {
|
||||
this->ref = ref;
|
||||
this->refSize = refSize;
|
||||
loadHex("../../resources/hex/" + name + ".hex");
|
||||
}
|
||||
|
||||
virtual void checks(){
|
||||
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address == 28){
|
||||
assertEq(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data, ref[refIndex]);
|
||||
//printf("%d\n",i);
|
||||
|
||||
refIndex++;
|
||||
if(refIndex == refSize){
|
||||
pass();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RiscvTest : public Workspace{
|
||||
public:
|
||||
RiscvTest(string name) : Workspace(name) {
|
||||
|
@ -362,7 +388,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void checks(){
|
||||
if(top->VexRiscv->writeBack_arbitration_isValid == 1 && top->VexRiscv->writeBack_input_INSTRUCTION == 0x00000073){
|
||||
if(top->VexRiscv->writeBack_arbitration_isValid == 1 && top->VexRiscv->writeBack_INSTRUCTION == 0x00000073){
|
||||
uint32_t code = top->VexRiscv->RegFilePlugin_regFile[28];
|
||||
if((code & 1) == 0){
|
||||
cout << "Wrong error code"<< endl;
|
||||
|
@ -521,6 +547,11 @@ int main(int argc, char **argv, char **env) {
|
|||
// Dhrystone("dhrystoneO3ML",false,false).run(8e6);
|
||||
// Dhrystone("dhrystoneO3MLL",false,false).run(80e6);
|
||||
#endif
|
||||
#ifdef CSR
|
||||
uint32_t machineCsrRef[] = {1,11, 2,0x80000003u, 3};
|
||||
TestX28("machineCsr",machineCsrRef, sizeof(machineCsrRef)/4).run(2e3);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
uint64_t duration = timer_end(startedAt);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
TRACE=no
|
||||
DHRYSTONE=yes
|
||||
REDO=5
|
||||
TRACE=yes
|
||||
CSR=yes
|
||||
DHRYSTONE=no
|
||||
REDO=1
|
||||
|
||||
ADDCFLAGS += -CFLAGS -DREDO=${REDO}
|
||||
ifeq ($(DHRYSTONE),yes)
|
||||
|
@ -12,6 +13,10 @@ ifeq ($(TRACE),yes)
|
|||
ADDCFLAGS += -CFLAGS -DTRACE
|
||||
endif
|
||||
|
||||
ifeq ($(CSR),yes)
|
||||
ADDCFLAGS += -CFLAGS -DCSR
|
||||
endif
|
||||
|
||||
run: compile
|
||||
./obj_dir/VVexRiscv
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue