Skip to content

Commit

Permalink
And the refactoring is going again
Browse files Browse the repository at this point in the history
  • Loading branch information
HidetaroTanaka committed Jan 29, 2024
1 parent c345dc4 commit b0acf72
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 671 deletions.
16 changes: 8 additions & 8 deletions src/main/scala/hajime/simple4Stage/Core.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class debugIO(implicit params: HajimeCoreParams) extends Bundle {
})
val debugAbiMap = new debug_map_physical_to_abi()
val vrfMap = if(params.useVector) Some(Vec(32, UInt(params.vlen.W))) else None
// val ID_EX_Reg = Valid(new ID_EX_IO())
// val ID_EX_Reg = Valid(new idExIo())
}

object debugIO {
Expand Down Expand Up @@ -121,7 +121,7 @@ class VectorDataSignals(implicit params: HajimeCoreParams) extends Bundle {
val vd = UInt(5.W)
}

class ID_EX_IO(implicit params: HajimeCoreParams) extends Bundle {
class idExIo(implicit params: HajimeCoreParams) extends Bundle {
val dataSignals = new ID_EX_dataSignals()
val ctrlSignals = new BasicCtrlSignals()
val exceptionSignals = new Valid(UInt(params.xprlen.W))
Expand All @@ -130,7 +130,7 @@ class ID_EX_IO(implicit params: HajimeCoreParams) extends Bundle {
val debug = if(params.debug) Some(new Debug_Info()) else None
}

class EX_WB_IO(implicit params: HajimeCoreParams) extends Bundle {
class exWbIo(implicit params: HajimeCoreParams) extends Bundle {
val dataSignals = new EX_WB_dataSignals()
val ctrlSignals = new BasicCtrlSignals()
val exceptionSignals = new Valid(UInt(params.xprlen.W))
Expand All @@ -139,7 +139,7 @@ class EX_WB_IO(implicit params: HajimeCoreParams) extends Bundle {
val debug = if(params.debug) Some(new Debug_Info()) else None
}

class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpConstants with VectorOpConstants {
class Cpu(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpConstants with VectorOpConstants {
// val io = IO(new CpuIo())
io := DontCare

Expand Down Expand Up @@ -190,8 +190,8 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons

val decodedInst = Wire(new InstBundle())
decodedInst := io.frontend.resp.bits.inst
val idExReg = Reg(Valid(new ID_EX_IO()))
val exWbReg = Reg(Valid(new EX_WB_IO()))
val idExReg = Reg(Valid(new idExIo()))
val exWbReg = Reg(Valid(new exWbIo()))
// io.debugIo.get.ID_EX_Reg := idExReg

// EXステージがvalidであり,かつEXステージが破棄できない場合,またはIDステージで必要なレジスタ値を取得できない場合,またはfence命令がある場合にreadyを下げる
Expand Down Expand Up @@ -518,6 +518,6 @@ class CPU(implicit params: HajimeCoreParams) extends CpuModule with ScalarOpCons
}
}

object CPU extends App {
def apply(implicit params: HajimeCoreParams): CPU = new CPU()
object Cpu extends App {
def apply(implicit params: HajimeCoreParams): Cpu = new Cpu()
}
359 changes: 180 additions & 179 deletions src/main/scala/hajime/vectormodules/VectorCpu.scala

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main/scala/hajime/vectormodules/VectorExecUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class VectorExecUnitIO(implicit params: HajimeCoreParams) extends Bundle {
val signalIn = Flipped(DecoupledIO(new VectorExecUnitSignalIn()))
val readVrf = Flipped(new VecRegFileReadIO())
val dataOut = Output(new VectorExecUnitDataOut())
val toExWbReg = Output(Valid(new EX_WB_IO()))
val toExWbReg = Output(Valid(new exWbIo()))
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/hajime/vectormodules/VectorLdstUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class VectorLdstUnitIO(implicit params: HajimeCoreParams) extends Bundle {
val scalarResp = ValidIO(new LDSTResp())
val vectorResp = Output(new VectorExecUnitDataOut())
val dcache = new AXI4liteIO(addrWidth = params.xprlen, dataWidth = params.xprlen)
val toExWbReg = Output(Valid(new EX_WB_IO()))
val toExWbReg = Output(Valid(new exWbIo()))
}

// TODO: VtypeのSEWと異なるEEWをillegalにする
Expand Down
364 changes: 0 additions & 364 deletions src/test/scala/hajime/publicmodules/ALUTest.scala

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import scala.io._

// 命令キャッシュと異なりマスター側のreadyが下がることは無いので,出力のストールは考えない
// TODO: FPGA用に例えばledへの出力を追加する,正常終了フラグや例外終了フラグなど
class Dcache_for_Verilator(dcacheBaseAddr: Int, tohost: Int, memsize: Int = 0x2000) extends Module with ChecksAxiReadResp with ChecksAxiWriteResp{
class DcacheForVerilator(dcacheBaseAddr: Int, tohost: Int, memsize: Int = 0x2000) extends Module with ChecksAxiReadResp with ChecksAxiWriteResp{
require(memsize % 8 == 0, s"memsize $memsize is not multiple of 8")

val io = IO(Flipped(new AXI4liteIO(addrWidth = 64, dataWidth = 64)))
Expand Down Expand Up @@ -55,17 +55,17 @@ class Dcache_for_Verilator(dcacheBaseAddr: Int, tohost: Int, memsize: Int = 0x20
io.r.valid := RegNext(io.ar.valid && io.ar.ready)

// write
val writeData_asVec = Wire(Vec(8, UInt(8.W)))
val writeDataAsVec = Wire(Vec(8, UInt(8.W)))
val shiftedData = MuxLookup(internalWriteAddr(2,0), io.w.bits.data)(
(0 until 8).map(
i => i.U -> (io.w.bits.data << (i*8).U).asUInt
)
)
for((w,i) <- writeData_asVec.zipWithIndex) {
for((w,i) <- writeDataAsVec.zipWithIndex) {
w := shiftedData(8*i+7, 8*i)
}
when(io.aw.valid && io.w.valid && internalWriteAddr < 0x00001FFF.U) {
mem.write(internalWriteAddr.head(61), writeData_asVec, MuxLookup(internalWriteAddr(2,0), io.w.bits.strb)(
mem.write(internalWriteAddr.head(61), writeDataAsVec, MuxLookup(internalWriteAddr(2,0), io.w.bits.strb)(
(0 until 8).map(
i => i.U -> (io.w.bits.strb << i.U).asUInt(7,0)
)
Expand All @@ -78,7 +78,7 @@ class Dcache_for_Verilator(dcacheBaseAddr: Int, tohost: Int, memsize: Int = 0x20
io.b.bits.resp := W_OKEY.U
}

object Dcache_for_Verilator extends App {
def apply(dcacheBaseAddr: Int = 0x00004000, tohost: Int = 0x10000000, memsize: Int = 0x2000): Dcache_for_Verilator = new Dcache_for_Verilator(dcacheBaseAddr, tohost, memsize)
ChiselStage.emitSystemVerilogFile(Dcache_for_Verilator(dcacheBaseAddr = 0x00004000, tohost = 0x10000000, memsize = 8192), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS)
object DcacheForVerilator extends App {
def apply(dcacheBaseAddr: Int = 0x00004000, tohost: Int = 0x10000000, memsize: Int = 0x2000): DcacheForVerilator = new DcacheForVerilator(dcacheBaseAddr, tohost, memsize)
ChiselStage.emitSystemVerilogFile(DcacheForVerilator(dcacheBaseAddr = 0x00004000, tohost = 0x10000000, memsize = 8192), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.scalatest.flatspec._
import scala.io._

// Should I check unaligned exception in Core or Cache?
class Icache_for_Verilator(memsize: Int = 0x2000) extends Module {
class IcacheForVerilator(memsize: Int = 0x2000) extends Module {
val io = IO(Flipped(new AXI4liteIO(addrWidth = 64, dataWidth = 32)))
// AR channel
io.ar.ready := true.B
Expand All @@ -33,50 +33,50 @@ class Icache_for_Verilator(memsize: Int = 0x2000) extends Module {
readDataFromMem.data := Cat(mem.read(io.ar.bits.addr.head(62)).reverse)
readDataFromMem.resp := 0.U

val r_channel_bits_reg = Reg(chiselTypeOf(io.r.bits))
val r_channel_valid_reg = Reg(Bool())
val r_stall = io.r.valid && !io.r.ready
val retain_r_channel = RegNext(r_stall)
when(r_stall) {
r_channel_bits_reg := io.r.bits
r_channel_valid_reg := io.r.valid
val rChannelBitsReg = Reg(chiselTypeOf(io.r.bits))
val rChannelValidReg = Reg(Bool())
val rStall = io.r.valid && !io.r.ready
val retainRchannel = RegNext(rStall)
when(rStall) {
rChannelBitsReg := io.r.bits
rChannelValidReg := io.r.valid
io.ar.ready := false.B
}.otherwise {
r_channel_bits_reg := readDataFromMem
r_channel_valid_reg := RegNext(io.ar.valid && io.ar.ready)
rChannelBitsReg := readDataFromMem
rChannelValidReg := RegNext(io.ar.valid && io.ar.ready)
}

io.r.bits := Mux(retain_r_channel, r_channel_bits_reg, readDataFromMem)
io.r.valid := Mux(retain_r_channel, r_channel_valid_reg, RegNext(io.ar.valid && io.ar.ready))
io.r.bits := Mux(retainRchannel, rChannelBitsReg, readDataFromMem)
io.r.valid := Mux(retainRchannel, rChannelValidReg, RegNext(io.ar.valid && io.ar.ready))

// write
io.b.bits.resp := 0.U
val b_valid = RegInit(false.B)
val b_resp = RegInit(0.U(3.W))
val writeData_asVec = Wire(Vec(4, UInt(8.W)))
for((w,i) <- writeData_asVec.zipWithIndex) {
val bValid = RegInit(false.B)
val bResp = RegInit(0.U(3.W))
val writeDataAsVec = Wire(Vec(4, UInt(8.W)))
for((w,i) <- writeDataAsVec.zipWithIndex) {
w := io.w.bits.data(8*i+7, 8*i)
}
when(io.aw.valid && io.w.valid) {
mem.write(io.aw.bits.addr.head(62), writeData_asVec, io.w.bits.strb.asBools)
b_valid := true.B
b_resp := 0.U
mem.write(io.aw.bits.addr.head(62), writeDataAsVec, io.w.bits.strb.asBools)
bValid := true.B
bResp := 0.U
} .otherwise {
b_valid := false.B
b_resp := 0.U
bValid := false.B
bResp := 0.U
}
io.b.valid := b_valid
io.b.bits.resp := b_resp
io.b.valid := bValid
io.b.bits.resp := bResp
}

object Icache_for_Verilator extends App {
def apply(memsize: Int = 8192): Icache_for_Verilator = new Icache_for_Verilator(memsize)
ChiselStage.emitSystemVerilogFile(Icache_for_Verilator(memsize = 8192), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS)
object IcacheForVerilator extends App {
def apply(memsize: Int = 8192): IcacheForVerilator = new IcacheForVerilator(memsize)
ChiselStage.emitSystemVerilogFile(IcacheForVerilator(memsize = 8192), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS)
}

class Icache_for_VerilatorSpec extends AnyFlatSpec with ChiselScalatestTester {
class IcacheForVerilatorSpec extends AnyFlatSpec with ChiselScalatestTester {
it should "write and read correctly" in {
test(Icache_for_Verilator(memsize = 1024)).withAnnotations(Seq(WriteVcdAnnotation, VerilatorBackendAnnotation)) { dut =>
test(IcacheForVerilator(memsize = 1024)).withAnnotations(Seq(WriteVcdAnnotation, VerilatorBackendAnnotation)) { dut =>
dut.io.ar.bits.addr.poke(0.U)
dut.io.ar.bits.prot.poke(0.U)
dut.io.ar.valid.poke(false.B)
Expand Down
36 changes: 18 additions & 18 deletions src/test/scala/hajime/publicmodules/MultiplierTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import org.scalatest.flatspec._
import scala.util.Random

object Functions {
def generate_Int64RandomHexString(): String = {
def generateInt64RandomHexString(): String = {
IndexedSeq.fill(16)(Random.nextInt(16).toHexString).reduce(_ + _)
}

def generate_Int64RandomHexString(n: Int): String = {
def generateInt64RandomHexString(n: Int): String = {
val number_of_zeros = 16 - n
(0 until 16).map(i => if(i < number_of_zeros) "0" else Random.nextInt(16).toHexString).reduce(_ + _)
}
Expand All @@ -25,18 +25,18 @@ import hajime.publicmodules.Functions._

class MultiplierTest extends AnyFlatSpec with ChiselScalatestTester {
Random.setSeed(0)
val multiplicand_array = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generate_Int64RandomHexString(), 16))
// multiplicand_array.foreach(x => println(x))
val multiplier_array = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generate_Int64RandomHexString(), 16))
// multiplier_array.foreach(x => println(x))
val answer_array = (multiplicand_array zip multiplier_array).map{
val multiplicandArray = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generateInt64RandomHexString(), 16))
// multiplicandArray.foreach(x => println(x))
val multiplierArray = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generateInt64RandomHexString(), 16))
// multiplierArray.foreach(x => println(x))
val answerArray = (multiplicandArray zip multiplierArray).map{
case (num1, num2) => num1 * num2
}
var result_array: IndexedSeq[BigInt] = IndexedSeq()
var result_tag_array: IndexedSeq[BigInt] = IndexedSeq()
var resultArray: IndexedSeq[BigInt] = IndexedSeq()
var resultTagArray: IndexedSeq[BigInt] = IndexedSeq()
it should s"perform pipelined multiplication" in {
test(Multiplier(HajimeCoreParams())).withAnnotations(Seq(WriteVcdAnnotation)) { dut =>
for (((num1, num2), i) <- (multiplicand_array zip multiplier_array).zipWithIndex) {
for (((num1, num2), i) <- (multiplicandArray zip multiplierArray).zipWithIndex) {
dut.io.req.valid.poke(true.B)
dut.io.req.bits.multiplicand.bits.poke(num1.U(64.W))
// dut.io.out.bits.multiplicand.signed.poke(false.B)
Expand All @@ -46,8 +46,8 @@ class MultiplierTest extends AnyFlatSpec with ChiselScalatestTester {
dut.io.resp.ready.poke(true.B)
dut.clock.step()
if(dut.io.resp.valid.peekBoolean()) {
result_array :+= dut.io.resp.bits.result.peekInt()
result_tag_array :+= dut.io.resp.bits.tag.peekInt()
resultArray :+= dut.io.resp.bits.result.peekInt()
resultTagArray :+= dut.io.resp.bits.tag.peekInt()
}
}
dut.io.req.valid.poke(false.B)
Expand All @@ -56,10 +56,10 @@ class MultiplierTest extends AnyFlatSpec with ChiselScalatestTester {
dut.io.req.bits.tag.poke(0.U)
while(dut.io.resp.valid.peekBoolean()) {
dut.clock.step()
result_array :+= dut.io.resp.bits.result.peekInt()
result_tag_array :+= dut.io.resp.bits.tag.peekInt()
resultArray :+= dut.io.resp.bits.result.peekInt()
resultTagArray :+= dut.io.resp.bits.tag.peekInt()
}
result_tag_array.lazyZip(result_array.map(bigIntToString32format)).lazyZip(answer_array.map(bigIntToString32format)).toIndexedSeq.foreach {
resultTagArray.lazyZip(resultArray.map(bigIntToString32format)).lazyZip(answerArray.map(bigIntToString32format)).toIndexedSeq.foreach {
case (tag, result, answer) => {
println(s"tag: $tag, result: 0x$result, answer: 0x$answer")
assert(result == answer)
Expand All @@ -71,11 +71,11 @@ class MultiplierTest extends AnyFlatSpec with ChiselScalatestTester {

class NonPipelinedMultiplierSpec extends AnyFlatSpec with ChiselScalatestTester {
Random.setSeed(0)
val multiplicand_array = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generate_Int64RandomHexString(Random.nextInt(16)), 16))
val multiplier_array = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generate_Int64RandomHexString(Random.nextInt(16)), 16))
val multiplicandArray = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generateInt64RandomHexString(Random.nextInt(16)), 16))
val multiplierArray = (0 until HajimeCoreParams().robEntries).map(_ => BigInt("0000000000000000" + generateInt64RandomHexString(Random.nextInt(16)), 16))
it should s"perform multiplication" in {
test(NonPipelinedMultiplier(HajimeCoreParams())).withAnnotations(Seq(WriteVcdAnnotation)) { dut =>
for((num1, num2, i) <- (multiplicand_array zip multiplier_array).zipWithIndex.map {
for((num1, num2, i) <- (multiplicandArray zip multiplierArray).zipWithIndex.map {
case ((num1, num2), i) => (num1, num2, i)
}) {
dut.io.req.valid.poke(true.B)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,45 @@ import hajime.common._
import hajime.publicmodules._
import hajime.vectormodules.VectorCpu

class Core_and_cache[T <: CpuModule](icache_memsize: Int = 8192, dcache_memsize: Int = 8192, tohost: Int = 0x10000000, useVector: Boolean = false, cpu: Class[T]) extends Module {
class CoreAndCache[T <: CpuModule](iCacheMemsize: Int = 8192, dCacheMemsize: Int = 8192, tohost: Int = 0x10000000, useVector: Boolean = false, cpu: Class[T]) extends Module {
implicit val params = HajimeCoreParams(useException = true, useVector = if(cpu == classOf[VectorCpu] && !useVector) throw new Exception("useVector is false") else useVector)
val io = IO(new Bundle{
val reset_vector = Input(UInt(64.W))
val resetVector = Input(UInt(64.W))
val hartid = Input(UInt(64.W))
val toHost = ValidIO(UInt(64.W))
val debug_io = Output(new debugIO())
val icache_initialising = Input(Bool())
val dcache_initialising = Input(Bool())
val imem_initialiseAXI = Flipped(new AXI4liteIO(addrWidth = 64, dataWidth = 32))
val debugIO = Output(new debugIO())
val iCacheInitialising = Input(Bool())
val dCacheInitialising = Input(Bool())
val iMemInitialiseAxi = Flipped(new AXI4liteIO(addrWidth = 64, dataWidth = 32))
val dmem_initialiseAXI = Flipped(new AXI4liteIO(addrWidth = 64, dataWidth = 64))
})

val core = withReset(io.icache_initialising || io.dcache_initialising || reset.asBool) {
val core = withReset(io.iCacheInitialising || io.dCacheInitialising || reset.asBool) {
Module(new Core(cpu))
}
val icache = Module(Icache_for_Verilator(memsize = icache_memsize))
val dcache = Module(Dcache_for_Verilator(dcacheBaseAddr = 0x00004000, tohost = tohost, memsize = dcache_memsize))
val icache = Module(IcacheForVerilator(memsize = iCacheMemsize))
val dcache = Module(DcacheForVerilator(dcacheBaseAddr = 0x00004000, tohost = tohost, memsize = dCacheMemsize))

icache.io := DontCare
io.imem_initialiseAXI := DontCare
io.iMemInitialiseAxi := DontCare
core.io.iCacheAxi4Lite := DontCare
dcache.io := DontCare
io.dmem_initialiseAXI := DontCare
core.io.dCacheAxi4Lite := DontCare

when(io.icache_initialising) {
icache.io <> io.imem_initialiseAXI
when(io.iCacheInitialising) {
icache.io <> io.iMemInitialiseAxi
core.io.iCacheAxi4Lite.ar.ready := false.B
core.io.iCacheAxi4Lite.aw.ready := false.B
core.io.iCacheAxi4Lite.w.ready := false.B
} .otherwise {
icache.io <> core.io.iCacheAxi4Lite
io.imem_initialiseAXI.ar.ready := false.B
io.imem_initialiseAXI.aw.ready := false.B
io.imem_initialiseAXI.w.ready := false.B
io.iMemInitialiseAxi.ar.ready := false.B
io.iMemInitialiseAxi.aw.ready := false.B
io.iMemInitialiseAxi.w.ready := false.B
}

when(io.dcache_initialising) {
when(io.dCacheInitialising) {
dcache.io <> io.dmem_initialiseAXI
core.io.dCacheAxi4Lite.ar.ready := false.B
core.io.dCacheAxi4Lite.aw.ready := false.B
Expand All @@ -58,13 +58,13 @@ class Core_and_cache[T <: CpuModule](icache_memsize: Int = 8192, dcache_memsize:
io.dmem_initialiseAXI.w.ready := false.B
}

core.io.resetVector := io.reset_vector
core.io.resetVector := io.resetVector
core.io.hartid := io.hartid
io.toHost := dcache.debug
io.debug_io := core.io.debugIo.get
io.debugIO := core.io.debugIo.get
}

object Core_and_cache extends App {
def apply[T <: CpuModule](icache_memsize: Int, dcache_memsize: Int, tohost: Int, useVector: Boolean = false, cpu: Class[T]): Core_and_cache[T] = new Core_and_cache(icache_memsize, dcache_memsize, tohost, useVector, cpu)
ChiselStage.emitSystemVerilogFile(apply(icache_memsize = 8192, dcache_memsize = 8192, tohost = 0x10000000, useVector = false, classOf[CPU]), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS)
object CoreAndCache extends App {
def apply[T <: CpuModule](icache_memsize: Int, dcache_memsize: Int, tohost: Int, useVector: Boolean = false, cpu: Class[T]): CoreAndCache[T] = new CoreAndCache(icache_memsize, dcache_memsize, tohost, useVector, cpu)
ChiselStage.emitSystemVerilogFile(apply(icache_memsize = 8192, dcache_memsize = 8192, tohost = 0x10000000, useVector = false, classOf[Cpu]), firtoolOpts = COMPILE_CONSTANTS.FIRTOOLOPS)
}
Loading

0 comments on commit b0acf72

Please sign in to comment.