Skip to content

Commit

Permalink
fix critical path
Browse files Browse the repository at this point in the history
  • Loading branch information
Bohan Hu committed Nov 30, 2020
1 parent a3af963 commit 8c57119
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 18 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
verilog:
mill chiselModule.runMain sim.SimTop --output-file SimTop.v
copy: verilog
cat SimTop.v > ../Sim_Workspace/verilog/top.v
50 changes: 50 additions & 0 deletions build.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import mill._, scalalib._
import coursier.maven.MavenRepository

object CustomZincWorkerModule extends ZincWorkerModule {
def repositories() = super.repositories ++ Seq(
MavenRepository("https://oss.sonatype.org/content/repositories/releases"),
MavenRepository("https://oss.sonatype.org/content/repositories/snapshots")
)
}

/**
* Scala 2.12 module that is source-compatible with 2.11.
* This is due to Chisel's use of structural types. See
* https://github.com/freechipsproject/chisel3/issues/606
*/
trait HasXsource211 extends ScalaModule {
override def scalacOptions = T {
super.scalacOptions() ++ Seq(
"-deprecation",
"-unchecked",
"-Xsource:2.11"
)
}
}

trait HasChisel3 extends ScalaModule {
override def ivyDeps = Agg(
ivy"edu.berkeley.cs::chisel3:3.3.2"
)
}

trait HasChiselTests extends CrossSbtModule {
object test extends Tests {
override def ivyDeps = Agg(ivy"org.scalatest::scalatest:3.0.4", ivy"edu.berkeley.cs::chisel-iotesters:1.2+")
def testFrameworks = Seq("org.scalatest.tools.Framework")
}
}

trait HasMacroParadise extends ScalaModule {
// Enable macro paradise for @chiselName et al
val macroPlugins = Agg(ivy"org.scalamacros:::paradise:2.1.0")
def scalacPluginIvyDeps = macroPlugins
def compileIvyDeps = macroPlugins
}

object chiselModule extends CrossSbtModule with HasChisel3 with HasChiselTests with HasXsource211 with HasMacroParadise {
def zincWorker = CustomZincWorkerModule
def crossScalaVersion = "2.11.12"
}

28 changes: 19 additions & 9 deletions src/main/scala/bus/axiInterface.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package bus
import core._
import chisel3._
import chisel3.util._
import chisel3.stage.ChiselStage

class CPUInstReq extends Bundle {
val req = Bool()
val addr = UInt(64.W)
Expand Down Expand Up @@ -77,12 +79,13 @@ class BridgeIO extends Bundle {
val instResp = Output(new CPUInstResp)
val dataReq = Input(new CPUDataReq)
val dataResp = Output(new CPUDataResp)
val toClint = Flipped(new MEMCLINT)
val axiMaster = new AXIMaster
}

class AXIBridge extends Module {
val io = IO(new BridgeIO)
val sIDLE :: sSEND_RADDR_IREQ :: sWAIT_RDATA_IREQ :: sSEND_RADDR_DREQ :: sWAIT_RDATA_DREQ :: sSEND_WADDR_DREQ :: sSEND_WDATA_DREQ :: sWAIT_WRESP_DREQ :: Nil = Enum(8)
val sIDLE :: sSEND_RADDR_IREQ :: sWAIT_RDATA_IREQ :: sSEND_RADDR_DREQ :: sWAIT_RDATA_DREQ :: sSEND_WADDR_DREQ :: sSEND_WDATA_DREQ :: sWAIT_WRESP_DREQ :: sREAD_CLINT :: sWRITE_CLINT :: Nil = Enum(10)
io.axiMaster.arvalid := io.instReq.req | io.dataReq.req
io.axiMaster.arid := Mux(io.dataReq.req, 1.U, 0.U) // Data requst has higher priority than inst request
io.axiMaster.araddr := Mux(io.dataReq.req, io.dataReq.addr, io.instReq.addr)
Expand All @@ -100,26 +103,33 @@ class AXIBridge extends Module {
io.axiMaster.awprot := 0.U
io.axiMaster.wid := 0.U

val isClint = io.dataReq.addr >= 0x38000000L.U && io.dataReq.addr < 0x40000000L.U
// 8 Bytes in one transfer(Two instructions)
val instReqArSz = WireInit("b011".U)
// Data transfer should depend on the Mem Op
val state = RegInit(sIDLE)
// State Transfer Logic
io.instResp.valid := io.axiMaster.rvalid && io.axiMaster.rlast && state === sWAIT_RDATA_IREQ
io.instResp.inst := Mux(io.instReq.addr(2), io.axiMaster.rdata(63, 32), io.axiMaster.rdata(31, 0))
io.dataResp.valid := io.axiMaster.rvalid && io.axiMaster.rlast && state === sWAIT_RDATA_DREQ
io.dataResp.rdata := io.axiMaster.rdata
io.dataResp.write_done := io.axiMaster.bvalid && state === sWAIT_WRESP_DREQ
io.dataResp.valid := ( io.axiMaster.rvalid && io.axiMaster.rlast && state === sWAIT_RDATA_DREQ ) | state === sREAD_CLINT
io.dataResp.rdata := Mux(isClint, io.toClint.rdata, io.axiMaster.rdata)
io.dataResp.write_done := (io.axiMaster.bvalid && state === sWAIT_WRESP_DREQ) | state === sWRITE_CLINT
switch(state) {
is(sIDLE) {
when(io.dataReq.req && io.dataReq.isWrite) {
state := sSEND_WADDR_DREQ
state := Mux(isClint, sWRITE_CLINT, sSEND_WADDR_DREQ)
}.elsewhen(io.dataReq.req && ~io.dataReq.isWrite) {
state := sSEND_RADDR_DREQ
state := Mux(isClint, sREAD_CLINT, sSEND_RADDR_DREQ)
}.elsewhen(io.instReq.req) {
state := sSEND_RADDR_IREQ
}
}
is(sWRITE_CLINT) {
state := sIDLE
}
is(sREAD_CLINT) {
state := sIDLE
}
is(sSEND_RADDR_IREQ) {
when(io.axiMaster.arready) {
state := sWAIT_RDATA_IREQ
Expand Down Expand Up @@ -173,11 +183,11 @@ class AXIBridge extends Module {

switch(state) {
is(sIDLE) {
when(io.dataReq.req && io.dataReq.isWrite) {
when(io.dataReq.req && io.dataReq.isWrite && ~isClint) {
io.axiMaster.awaddr := io.dataReq.addr
io.axiMaster.awsize := io.dataReq.size
io.axiMaster.awvalid := true.B
}.elsewhen(io.dataReq.req && ~io.dataReq.isWrite) {
}.elsewhen(io.dataReq.req && ~io.dataReq.isWrite && ~isClint) {
io.axiMaster.araddr := io.dataReq.addr
io.axiMaster.arvalid := true.B
io.axiMaster.arsize := io.dataReq.size
Expand Down Expand Up @@ -221,4 +231,4 @@ class AXIBridge extends Module {
object AXIBridge extends App {
val stage = new ChiselStage
stage.emitVerilog(new AXIBridge)
}
}
26 changes: 17 additions & 9 deletions src/main/scala/core/mem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ class MEM extends Module {
val accessVAddr = io.baseAddr + io.imm

// TODO:
val readClint = io.mem2dmem.memAddr >= 0x38000000L.U && io.mem2dmem.memAddr <= 0x00010000L.U + 0x38000000L.U
val readClint = accessVAddr >= 0x38000000L.U && accessVAddr <= 0x00010000L.U + 0x38000000L.U
io.exceInfoOut := io.exceInfoIn
io.toclint.data := io.R2Val
io.toclint.addr := io.mem2dmem.memAddr
io.toclint.addr := accessVAddr
// TODO Ends
val dataSize = MuxLookup(io.MemType, 8.U,
Array(
Expand All @@ -159,17 +159,20 @@ class MEM extends Module {
SZ_BU -> 1.U
)
)

val dataSizeReg = Reg(UInt(4.W))
dataSizeReg := dataSize
val signExt = io.MemType === SZ_B || io.MemType === SZ_H || io.MemType === SZ_W
val dataFromMem = WireInit(io.mem2dmem.memRdata)
val memRdataRaw = MuxLookup(dataSize, dataFromMem, // Including Word Select
val memRdataRaw = MuxLookup(dataSizeReg, dataFromMem, // Including Word Select
Array( // Byte, Addressed by addr[2:0]
1.U -> dataFromMem.asTypeOf(DataTypesUtils.Bytes)(accessVAddr(2, 0)),
2.U -> dataFromMem.asTypeOf(DataTypesUtils.HalfWords)(accessVAddr(2, 1)),
4.U -> dataFromMem.asTypeOf(DataTypesUtils.Words)(accessVAddr(2)),
8.U -> dataFromMem
)
)
val memRdataRawExt = MuxLookup(dataSize, dataFromMem, // Including Word Select
val memRdataRawExt = MuxLookup(dataSizeReg, dataFromMem, // Including Word Select
Array( // Byte, Addressed by addr[2:0]
1.U -> dataFromMem.asTypeOf(DataTypesUtils.Bytes)(accessVAddr(2, 0)),
2.U -> dataFromMem.asTypeOf(DataTypesUtils.HalfWords)(accessVAddr(2, 1)),
Expand Down Expand Up @@ -204,8 +207,8 @@ class MEM extends Module {
io.mem2mmu.reqReady := false.B
io.mem2mmu.reqVAddr := accessVAddr
val rDataReg = Reg(UInt(64.W))
val amoSrc1 = Mux(dataSize === 4.U, io.R2Val(31,0), io.R2Val)
val amoSrc2 = Mux(dataSize === 4.U, Mux(accessVAddr(2),rDataReg(63,32) ,rDataReg(31,0)), rDataReg)
val amoSrc1 = Mux(dataSizeReg === 4.U, io.R2Val(31,0), io.R2Val)
val amoSrc2 = Mux(dataSizeReg === 4.U, Mux(accessVAddr(2),rDataReg(63,32) ,rDataReg(31,0)), rDataReg)
val amoWData = MuxLookup(io.fuOp, amoSrc2,
Array(
LSU_ASWAP -> amoSrc1,
Expand All @@ -220,8 +223,8 @@ class MEM extends Module {
)
)
io.mem2dmem.memAddr := translatedPAddr
io.mem2dmem.memWdata := DataTypesUtils.WDataGen(dataSize, accessVAddr, Mux(isAMO && !isSC, amoWData, io.R2Val))
io.mem2dmem.memWmask := DataTypesUtils.Byte2BitMask(DataTypesUtils.ByteMaskGen(dataSize, accessVAddr))
io.mem2dmem.memWdata := DataTypesUtils.WDataGen(dataSizeReg, accessVAddr, Mux(isAMO && !isSC, amoWData, io.R2Val))
io.mem2dmem.memWmask := DataTypesUtils.Byte2BitMask(DataTypesUtils.ByteMaskGen(dataSizeReg, accessVAddr))
io.mem2dmem.memWen := false.B
io.mem2dmem.memRreq := false.B
io.memResult := Mux(signExt, memRdataRawExt, memRdataRaw)
Expand All @@ -231,11 +234,16 @@ class MEM extends Module {
}.elsewhen(isSC & scSuccessReg === 1.U) {
io.memResult := 1.U
}
when(readClint) {
io.memResult := io.toclint.rdata
}
io.pauseReq := false.B
io.toclint.wen := io.mem2dmem.memAddr >= 0x38000000L.U && io.mem2dmem.memAddr <= 0x00010000L.U + 0x38000000L.U && io.isMemOp && io.MemOp === MEM_WRITE && state === sWAIT_WR // TODO: Notice: It's an ugly patch!!!!
val MemTypeReg = RegInit(SZ_B)
switch(state) {
is(sIDLE) {
scSuccessReg := 1.U
MemTypeReg := io.MemType // Fix the timing problem
when(addrMisaligned & io.isMemOp & !io.exceInfoIn.valid) {
io.exceInfoOut.valid := true.B
io.exceInfoOut.cause := Mux(isLoad, ExceptionNo.loadAddrMisaligned.U, ExceptionNo.storeAddrMisaligned.U)
Expand Down Expand Up @@ -312,7 +320,7 @@ class MEM extends Module {
}
val isUART = 0x40600000L.U <= io.mem2dmem.memAddr & (0x40600000L+10L).U >= io.mem2dmem.memAddr
when( isStore && isUART ) {
printf("%c", io.R2Val(7,0))
printf("%c", io.R2Val(7,0))
}

// MMIO Flag
Expand Down

0 comments on commit 8c57119

Please sign in to comment.