Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ SIMTOP = top.TopMain
IMAGE ?= ready-to-run/linux.bin

DATAWIDTH ?= 64
BOARD ?= sim # sim pynq axu4cg
CORE ?= seq # seq ooo small
BOARD ?= sim # sim pynq axu3cg
CORE ?= inorder # inorder ooo embedded

.DEFAULT_GOAL = verilog

Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/nutcore/NutCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ class NutCore(implicit val p: NutCoreConfig) extends NutCoreModule {

// Frontend
val frontend = (Settings.get("IsRV32"), Settings.get("EnableOutOfOrderExec")) match {
case (true, _) => Module(new Frontend_dummy)
case (false, true) => Module(new Frontend)
case (true, _) => Module(new Frontend_embedded)
case (false, true) => Module(new Frontend_ooo)
case (false, false) => Module(new Frontend_inorder)
}

// Backend
if (EnableOutOfOrderExec) {
val mmioXbar = Module(new SimpleBusCrossbarNto1(if (HasDcache) 2 else 3))
val backend = Module(new Backend)
val backend = Module(new Backend_ooo)
PipelineVector2Connect(new DecodeIO, frontend.io.out(0), frontend.io.out(1), backend.io.in(0), backend.io.in(1), frontend.io.flushVec(1), 16)
backend.io.flush := frontend.io.flushVec(2)
frontend.io.redirect <> backend.io.redirect
Expand Down Expand Up @@ -141,7 +141,7 @@ class NutCore(implicit val p: NutCoreConfig) extends NutCoreModule {
io.mmio <> mmioXbar.io.out

} else {
val backend = Module(new Backend_seq)
val backend = Module(new Backend_inorder)

PipelineVector2Connect(new DecodeIO, frontend.io.out(0), frontend.io.out(1), backend.io.in(0), backend.io.in(1), frontend.io.flushVec(1), 4)

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/nutcore/backend/ooo/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ trait HasBackendConst{
}

// NutShell/Argo Out Of Order Execution Backend
class Backend(implicit val p: NutCoreConfig) extends NutCoreModule with HasRegFileParameter with HasBackendConst{
class Backend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule with HasRegFileParameter with HasBackendConst{

val io = IO(new Bundle {
// EXU
Expand Down Expand Up @@ -662,7 +662,7 @@ class Backend(implicit val p: NutCoreConfig) extends NutCoreModule with HasRegFi

}

class Backend_seq(implicit val p: NutCoreConfig) extends NutCoreModule {
class Backend_inorder(implicit val p: NutCoreConfig) extends NutCoreModule {
val io = IO(new Bundle {
val in = Vec(2, Flipped(Decoupled(new DecodeIO)))
val flush = Input(UInt(2.W))
Expand Down
101 changes: 51 additions & 50 deletions src/main/scala/nutcore/frontend/BPU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class BPUUpdateReq extends NutCoreBundle {
}

// nextline predicter generates NPC from current NPC in 1 cycle
class NLP extends NutCoreModule {
class BPU_ooo extends NutCoreModule {
val io = IO(new Bundle {
val in = new Bundle { val pc = Flipped(Valid((UInt(VAddrBits.W)))) }
val out = new RedirectIO
Expand Down Expand Up @@ -190,7 +190,7 @@ class NLP extends NutCoreModule {
// ROCKET uses a 32 bit instline, and its IDU logic is more simple than this implentation.
}

class BPU1 extends NutCoreModule {
class BPU_embedded extends NutCoreModule {
val io = IO(new Bundle {
val in = new Bundle { val pc = Flipped(Valid((UInt(32.W)))) }
val out = new RedirectIO
Expand Down Expand Up @@ -277,53 +277,7 @@ class BPU1 extends NutCoreModule {
io.out.rtype := 0.U
}


class BPU2 extends NutCoreModule {
val io = IO(new Bundle {
val in = Flipped(Valid(new CtrlFlowIO))
val out = new RedirectIO
})

val instr = io.in.bits.instr
val immJ = SignExt(Cat(instr(31), instr(19, 12), instr(20), instr(30, 21), 0.U(1.W)), XLEN)
val immB = SignExt(Cat(instr(31), instr(7), instr(30, 25), instr(11, 8), 0.U(1.W)), XLEN)
val table = Array(
RV32I_BRUInstr.JAL -> List(immJ, true.B),
RV32I_BRUInstr.BNE -> List(immB, instr(31)),
RV32I_BRUInstr.BEQ -> List(immB, instr(31)),
RV32I_BRUInstr.BLT -> List(immB, instr(31)),
RV32I_BRUInstr.BGE -> List(immB, instr(31)),
RV32I_BRUInstr.BLTU -> List(immB, instr(31)),
RV32I_BRUInstr.BGEU -> List(immB, instr(31))
)
val default = List(immB, false.B)
val offset :: predict :: Nil = ListLookup(instr, default, table)

io.out.target := io.in.bits.pc + offset
io.out.valid := io.in.valid && predict(0)
io.out.rtype := 0.U
}

// multi-cycle predicter must generates NPC from current NPC in no more than 3 cycles
class DummyPredicter extends NutCoreModule {
val io = IO(new Bundle {
val in = new Bundle { val pc = Flipped(Valid((UInt(VAddrBits.W)))) }
val out = new RedirectIO
val valid = Output(Bool())
val flush = Input(Bool())
val ignore = Input(Bool())
val brIdx = Output(Vec(4, Bool()))
})
// Note: when io.ignore, io.out.valid must be false.B for this pc
// This limitation is for cross instline inst fetch logic
io.valid := io.in.pc.valid // Predicter is returning a result
io.out.valid := false.B // Need redirect
io.out.target := DontCare // Redirect target
io.out.rtype := DontCare // Predicter does not need to care about it
io.brIdx := VecInit(Seq.fill(4)(false.B)) // Which inst triggers jump
}

class BPU3 extends NutCoreModule {
class BPU_inorder extends NutCoreModule {
val io = IO(new Bundle {
val in = new Bundle { val pc = Flipped(Valid((UInt(VAddrBits.W)))) }
val out = new RedirectIO
Expand Down Expand Up @@ -472,4 +426,51 @@ class BPU3 extends NutCoreModule {
// `&& !crosslineJump` is used to make sure this logic will run correctly when imem stalls (pcUpdate === false)
// by using `instline`, we mean a 64 bit instfetch result from imem
// ROCKET uses a 32 bit instline, and its IDU logic is more simple than this implentation.
}
}

class DummyPredicter extends NutCoreModule {
val io = IO(new Bundle {
val in = new Bundle { val pc = Flipped(Valid((UInt(VAddrBits.W)))) }
val out = new RedirectIO
val valid = Output(Bool())
val flush = Input(Bool())
val ignore = Input(Bool())
val brIdx = Output(Vec(4, Bool()))
})
// Note: when io.ignore, io.out.valid must be false.B for this pc
// This limitation is for cross instline inst fetch logic
io.valid := io.in.pc.valid // Predicter is returning a result
io.out.valid := false.B // Need redirect
io.out.target := DontCare // Redirect target
io.out.rtype := DontCare // Predicter does not need to care about it
io.brIdx := VecInit(Seq.fill(4)(false.B)) // Which inst triggers jump
}

//---- Legacy BPUs ----
/*
class BPU_nodelay extends NutCoreModule {
val io = IO(new Bundle {
val in = Flipped(Valid(new CtrlFlowIO))
val out = new RedirectIO
})

val instr = io.in.bits.instr
val immJ = SignExt(Cat(instr(31), instr(19, 12), instr(20), instr(30, 21), 0.U(1.W)), XLEN)
val immB = SignExt(Cat(instr(31), instr(7), instr(30, 25), instr(11, 8), 0.U(1.W)), XLEN)
val table = Array(
RV32I_BRUInstr.JAL -> List(immJ, true.B),
RV32I_BRUInstr.BNE -> List(immB, instr(31)),
RV32I_BRUInstr.BEQ -> List(immB, instr(31)),
RV32I_BRUInstr.BLT -> List(immB, instr(31)),
RV32I_BRUInstr.BGE -> List(immB, instr(31)),
RV32I_BRUInstr.BLTU -> List(immB, instr(31)),
RV32I_BRUInstr.BGEU -> List(immB, instr(31))
)
val default = List(immB, false.B)
val offset :: predict :: Nil = ListLookup(instr, default, table)

io.out.target := io.in.bits.pc + offset
io.out.valid := io.in.valid && predict(0)
io.out.rtype := 0.U
}
*/
8 changes: 4 additions & 4 deletions src/main/scala/nutcore/frontend/Frontend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import chisel3.util.experimental.BoringUtils
import utils._
import bus.simplebus._

class Frontend(implicit val p: NutCoreConfig) extends NutCoreModule {
class Frontend_ooo(implicit val p: NutCoreConfig) extends NutCoreModule {
val io = IO(new Bundle {
val out = Vec(2, Decoupled(new DecodeIO))
val imem = new SimpleBusUC(userBits = ICacheUserBundleWidth, addrBits = VAddrBits)
Expand All @@ -38,7 +38,7 @@ class Frontend(implicit val p: NutCoreConfig) extends NutCoreModule {
right <> FlushableQueue(left, isFlush, entries = entries, pipe = pipe)
}

val ifu = Module(new IFU)
val ifu = Module(new IFU_ooo)
val ibf = Module(new IBF)
val idu = Module(new IDU)

Expand All @@ -63,7 +63,7 @@ class Frontend(implicit val p: NutCoreConfig) extends NutCoreModule {
Debug(idu.io.in(1).valid, "IDU2: pc = 0x%x, instr = 0x%x, pnpc = 0x%x\n", idu.io.in(1).bits.pc, idu.io.in(1).bits.instr, idu.io.in(1).bits.pnpc)
}

class Frontend_dummy(implicit val p: NutCoreConfig) extends NutCoreModule {
class Frontend_embedded(implicit val p: NutCoreConfig) extends NutCoreModule {
val io = IO(new Bundle {
val out = Vec(2, Decoupled(new DecodeIO))
val imem = new SimpleBusUC(userBits = ICacheUserBundleWidth, addrBits = VAddrBits)
Expand All @@ -73,7 +73,7 @@ class Frontend_dummy(implicit val p: NutCoreConfig) extends NutCoreModule {
val redirect = Flipped(new RedirectIO)
})

val ifu = Module(new IFU_dummy)
val ifu = Module(new IFU_embedded)
val idu = Module(new IDU)

PipelineConnect(ifu.io.out, idu.io.in(0), idu.io.out(0).fire(), ifu.io.flushVec(0))
Expand Down
12 changes: 6 additions & 6 deletions src/main/scala/nutcore/frontend/IFU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ICacheUserBundle extends NutCoreBundle {
}
// Note: update ICacheUserBundleWidth when change ICacheUserBundle

class IFU extends NutCoreModule with HasResetVector {
class IFU_ooo extends NutCoreModule with HasResetVector {
val io = IO(new Bundle {

val imem = new SimpleBusUC(userBits = ICacheUserBundleWidth, addrBits = VAddrBits)
Expand All @@ -59,7 +59,7 @@ class IFU extends NutCoreModule with HasResetVector {
// Note: we define instline as 8 Byte aligned data from icache

// Next-line branch predictor
val nlp = Module(new NLP)
val nlp = Module(new BPU_ooo)

// nlpxxx_latch is used for the situation when I$ is disabled
val nlpvalidreg = RegInit(false.B)
Expand Down Expand Up @@ -167,7 +167,7 @@ class IFU extends NutCoreModule with HasResetVector {
(mcpResultQueue.io.deq.bits.brIdx.asUInt & io.imem.resp.bits.user.get(VAddrBits*2 + 7, VAddrBits*2 + 4)).orR //mcp reports a valid branch


//val bp2 = Module(new BPU2)
//val bp2 = Module(new BPU_nodelay)
//bp2.io.in.bits := io.out.bits
//bp2.io.in.valid := io.imem.resp.fire()

Expand Down Expand Up @@ -255,7 +255,7 @@ class IFU extends NutCoreModule with HasResetVector {
BoringUtils.addSource(io.flushVec.orR, "perfCntCondMifuFlush")
}

class IFU_dummy extends NutCoreModule with HasResetVector {
class IFU_embedded extends NutCoreModule with HasResetVector {
val io = IO(new Bundle {
val imem = new SimpleBusUC(userBits = 64, addrBits = VAddrBits)
val out = Decoupled(new CtrlFlowIO)
Expand All @@ -270,7 +270,7 @@ class IFU_dummy extends NutCoreModule with HasResetVector {
val pcUpdate = io.redirect.valid || io.imem.req.fire()
val snpc = pc + 4.U // sequential next pc

val bpu = Module(new BPU1)
val bpu = Module(new BPU_embedded)

// predicted next pc
val pnpc = bpu.io.out.target
Expand Down Expand Up @@ -322,7 +322,7 @@ class IFU_inorder extends NutCoreModule with HasResetVector {
val pcUpdate = io.redirect.valid || io.imem.req.fire()
val snpc = Mux(pc(1), pc + 2.U, pc + 4.U) // sequential next pc

val bp1 = Module(new BPU3)
val bp1 = Module(new BPU_inorder)

val crosslineJump = bp1.io.crosslineJump
val crosslineJumpLatch = RegInit(false.B)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/top/TopMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ object TopMain extends App {
case "axu3cg" => Axu3cgSettings()
case "PXIe" => PXIeSettings()
} ) ++ ( core match {
case "seq" => InOrderSettings()
case "inorder" => InOrderSettings()
case "ooo" => OOOSettings()
case "small"=> EmbededSettings()
case "embedded"=> EmbededSettings()
} )
s.foreach{Settings.settings += _} // add and overwrite DefaultSettings
println("====== Settings = (" + board + ", " + core + ") ======")
Expand Down