From e42a542f8160e679102ec423fd5fbd03d4b99533 Mon Sep 17 00:00:00 2001 From: Martin Schoeberl Date: Fri, 26 Jul 2024 16:56:28 +0200 Subject: [PATCH] Finish refactoring the FSM --- src/main/scala/leros/Decode.scala | 29 ++++-------- src/main/scala/leros/Leros.scala | 73 +++++++++++++++++-------------- src/main/scala/leros/State.scala | 6 +-- 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/main/scala/leros/Decode.scala b/src/main/scala/leros/Decode.scala index a33f687..2aa9313 100644 --- a/src/main/scala/leros/Decode.scala +++ b/src/main/scala/leros/Decode.scala @@ -17,13 +17,8 @@ class DecodeOut extends Bundle { val nextState = State() val enaByte = Bool() val enaHalf = Bool() - val isStoreInd = Bool() - val isStoreIndB = Bool() - val isStoreIndH = Bool() val isDataAccess = Bool() - val isBranch = Bool() val brType = UInt(4.W) - val exit = Bool() } object DecodeOut { @@ -40,16 +35,11 @@ object DecodeOut { v.brOff := 0.S v.isRegOpd := false.B v.useDecOpd := false.B - v.nextState := execute + v.nextState := init v.enaByte := false.B v.enaHalf := false.B - v.isStoreInd := false.B - v.isStoreIndB := false.B - v.isStoreIndH := false.B v.isDataAccess := false.B - v.isBranch := false.B v.brType := 0.U - v.exit := false.B v } } @@ -77,11 +67,10 @@ class Decode() extends Module { def mask(i: Int) = ((i >> 4) & 0x0f).asUInt val field = io.din(15, 12) - when (field === mask(BR)) { d.isBranch := true.B } - when (field === mask(BRZ)) { d.isBranch := true.B } - when (field === mask(BRNZ)) { d.isBranch := true.B } - when (field === mask(BRP)) { d.isBranch := true.B } - when (field === mask(BRN)) { d.isBranch := true.B } + when (field === mask(BR) || field === mask(BRZ) || field === mask(BRNZ) || + field === mask(BRP) || field === mask(BRN)) { + d.nextState := branch + } val instr = io.din d.brType := field @@ -214,21 +203,21 @@ class Decode() extends Module { off := instrSignExt << 1 } is (STIND.U) { + d.nextState := storeInd d.isDataAccess := true.B - d.isStoreInd := true.B } is (STINDB.U) { + d.nextState := storeIndB d.isDataAccess := true.B - d.isStoreIndB := true.B off := instrSignExt } is(STINDH.U) { + d.nextState := storeIndH d.isDataAccess := true.B - d.isStoreIndH := true.B off := instrSignExt << 1 } is(SCALL.U) { - d.exit := true.B + d.nextState := scall } } diff --git a/src/main/scala/leros/Leros.scala b/src/main/scala/leros/Leros.scala index 8aaad6a..3c894df 100644 --- a/src/main/scala/leros/Leros.scala +++ b/src/main/scala/leros/Leros.scala @@ -102,46 +102,51 @@ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends LerosBa dataMem.io.wr := true.B } - is (execute) { + is (storeInd) { + dataMem.io.wr := true.B + // TODO: am I missing here something? See the other store indirect + // TODO: this is a super quick hack to get the LED blinking + outReg := accu + } - when(decReg.isStoreInd) { - dataMem.io.wr := true.B - // TODO: am I missing here something? See the other store indirect - // TODO: this is a super quick hack to get the LED blinking - outReg := accu - } - when(decReg.isStoreIndB) { - // wr and wrMask could be set in decode and registered - dataMem.io.wr := true.B - dataMem.io.wrMask := "b0001".U << effAddrOffReg - vecAccu(effAddrOffReg) := accu(7, 0) - dataMem.io.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) - } - when(decReg.isStoreIndH) { - dataMem.io.wr := true.B - dataMem.io.wrMask := "b0011".U << effAddrOffReg - vecAccu(effAddrOffReg) := accu(7, 0) - vecAccu(effAddrOffReg | 1.U) := accu(15, 8) - dataMem.io.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) + is (storeIndB) { + // wr and wrMask could be set in decode and registered + dataMem.io.wr := true.B + dataMem.io.wrMask := "b0001".U << effAddrOffReg + vecAccu(effAddrOffReg) := accu(7, 0) + dataMem.io.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) + } + + is (storeIndH) { + dataMem.io.wr := true.B + dataMem.io.wrMask := "b0011".U << effAddrOffReg + vecAccu(effAddrOffReg) := accu(7, 0) + vecAccu(effAddrOffReg | 1.U) := accu(15, 8) + dataMem.io.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) + } + + is (branch) { + val doBranch = WireDefault(false.B) + switch(decReg.brType) { + is ((BR >> 4).U) { doBranch := true.B } + is ((BRZ >> 4).U) { doBranch := accu === 0.U } + is ((BRNZ >> 4).U) { doBranch := accu =/= 0.U } + is ((BRP >> 4).U) { doBranch := accu(31) === 0.U } + is ((BRN >> 4).U) { doBranch := accu(31) =/= 0.U } } - when(decReg.isBranch) { - val doBranch = WireDefault(false.B) - switch(decReg.brType) { - is ((BR >> 4).U) { doBranch := true.B } - is ((BRZ >> 4).U) { doBranch := accu === 0.U } - is ((BRNZ >> 4).U) { doBranch := accu =/= 0.U } - is ((BRP >> 4).U) { doBranch := accu(31) === 0.U } - is ((BRN >> 4).U) { doBranch := accu(31) =/= 0.U } - } - when (doBranch) { - pcNext := (pcReg.asSInt + decReg.brOff).asUInt - } + when (doBranch) { + pcNext := (pcReg.asSInt + decReg.brOff).asUInt } } - } - exit := RegNext(decReg.exit) + is (jal) { + // TODO: write tests first + } + is (scall) { + exit := RegNext(true.B) + } + } } object Leros extends App { diff --git a/src/main/scala/leros/State.scala b/src/main/scala/leros/State.scala index 93ab65e..d2d751a 100644 --- a/src/main/scala/leros/State.scala +++ b/src/main/scala/leros/State.scala @@ -2,8 +2,8 @@ package leros import chisel3.ChiselEnum object State extends ChiselEnum { - val fetch, execute, + val init, fetch, loadAddr, loadInd, - store, storeInd, storeindB, storeIndH, - branch, jal = Value + store, storeInd, storeIndB, storeIndH, + branch, jal, scall = Value } \ No newline at end of file