diff --git a/npc/core/src/main/scala/ALU.scala b/npc/core/src/main/scala/ALU.scala index 8a55719..b391c3a 100644 --- a/npc/core/src/main/scala/ALU.scala +++ b/npc/core/src/main/scala/ALU.scala @@ -10,8 +10,8 @@ class ALUControlInterface extends Bundle { } val op = Input(OpSelect()) - type ctrlTypes = OpSelect.Type :: HNil - def ctrlBindPorts: ctrlTypes = { + type CtrlTypes = OpSelect.Type :: HNil + def ctrlBindPorts: CtrlTypes = { op :: HNil } } diff --git a/npc/core/src/main/scala/Main.scala b/npc/core/src/main/scala/Main.scala index efad2fe..0dc0c8d 100644 --- a/npc/core/src/main/scala/Main.scala +++ b/npc/core/src/main/scala/Main.scala @@ -28,7 +28,6 @@ class PcControl(width: Int) extends Bundle { } -import flow.components.{ RegisterFile, RegFileInterface, ProgramCounter, ALU } import flow.components.{ RegControl, PcControlInterface, ALUControlInterface } class Control(width: Int) extends Module { val inst = IO(Input(UInt(width.W))) @@ -65,23 +64,43 @@ class Control(width: Int) extends Module { val slices = reversePrefixSum.zip(reversePrefixSum.tail) val srcList = slices.map(s => out(s._1 - 1, s._2)) - // def m[T <: Data](src: UInt, dst: T) = dst match { - // case dst: EnumType => dst := src.asTypeOf(chiselTypeOf(dst)) - // case dst: Data => dst := src - // } - srcList.zip(dstList).foreach({ case (src, dst) => dst := src.asTypeOf(dst) }) } +import flow.components.{ RegisterFile, RegFileInterface, ProgramCounter, ALU } class Flow extends Module { - val io = IO(new Bundle { }) - val ram = SRAM(size=128*1024*1024, tpe=UInt(32.W), numReadPorts=2, numWritePorts=1,numReadwritePorts=0) + val dataType = UInt(32.W) + + val ram = SRAM(size=128*1024*1024, tpe=dataType, numReadPorts=2, numWritePorts=1,numReadwritePorts=0) val control = Module(new Control(32)) + val reg = RegisterFile(32, dataType, 2, 2) + val pc = Module(new ProgramCounter(dataType)) + val alu = Module(new ALU(dataType)) - // Instruction Fetch ram.readPorts(0).enable := true.B - val instruction = ram.readPorts(0).address + ram.readPorts(0).address := pc.out + val inst = ram.readPorts(0).data + control.inst := inst + reg.control <> control.reg + pc.control <> control.pc + alu.control <> control.alu + + import control.reg.WriteSelect._ + import control.pc.SrcSelect._ + import control.alu.OpSelect._ + + reg.in.writeData(rAluOut.litValue.toInt) := alu.out.result + // TODO: Read address in load command goes here + ram.readPorts(1).enable := false.B + ram.readPorts(1).address := 0.U + reg.in.writeData(rMemOut.litValue.toInt) := ram.readPorts(1).data + reg.in.writeAddr := inst(11, 7) + reg.in.rs(0) := inst(19, 15) + reg.in.rs(1) := inst(24, 20) + + alu.in.a := reg.out.src(0) + alu.in.b := reg.out.src(1) } diff --git a/npc/core/src/main/scala/ProgramCounter.scala b/npc/core/src/main/scala/ProgramCounter.scala index 9b78cf3..bfb3e1b 100644 --- a/npc/core/src/main/scala/ProgramCounter.scala +++ b/npc/core/src/main/scala/ProgramCounter.scala @@ -11,8 +11,8 @@ class PcControlInterface extends Bundle { val srcSelect = Input(SrcSelect()) - type ctrlTypes = SrcSelect.Type :: HNil - def ctrlBindPorts: ctrlTypes = { + type CtrlTypes = SrcSelect.Type :: HNil + def ctrlBindPorts: CtrlTypes = { srcSelect :: HNil } } @@ -25,7 +25,10 @@ class ProgramCounter[T <: Data](tpe: T) extends Module { }) val out = IO(Output(tpe)) - out := in.pcSrcs(control.srcSelect.asUInt) + private val pc = RegInit(0x80000000L.U) + + pc := in.pcSrcs(control.srcSelect.asUInt) + out := pc } object ProgramCounter { diff --git a/npc/core/src/main/scala/RegisterFile.scala b/npc/core/src/main/scala/RegisterFile.scala index 8fc77d0..00bf529 100644 --- a/npc/core/src/main/scala/RegisterFile.scala +++ b/npc/core/src/main/scala/RegisterFile.scala @@ -14,8 +14,8 @@ class RegControl extends Bundle { val writeEnable = Input(Bool()) val writeSelect = Input(WriteSelect()) - type ctrlTypes = Bool :: WriteSelect.Type :: HNil - def ctrlBindPorts: ctrlTypes = { + type CtrlTypes = Bool :: WriteSelect.Type :: HNil + def ctrlBindPorts: CtrlTypes = { writeEnable :: writeSelect :: HNil } } @@ -33,7 +33,15 @@ class RegFileData[T <: Data](size:Int, tpe: T, numReadPorts: Int, numWritePorts: class RegFileInterface[T <: Data](size: Int, tpe: T, numReadPorts: Int, numWritePorts: Int) extends Bundle { val control = new RegControl - val data = new RegFileData(size, tpe, numReadPorts, numWritePorts) + // val data = new RegFileData(size, tpe, numReadPorts, numWritePorts) + val in = new Bundle { + val writeAddr = Input(UInt(size.W)) + val writeData = Input(Vec(numWritePorts, tpe)) + val rs = Input(Vec(numReadPorts, UInt(size.W))) + } + val out = new Bundle { + val src = Output(Vec(numReadPorts, tpe)) + } } class RegisterFileCore[T <: Data](size: Int, tpe: T, numReadPorts: Int) extends Module { @@ -66,13 +74,11 @@ object RegisterFile { val _out = Wire(new RegFileInterface(size, tpe, numReadPorts, numWritePorts)) val clock = core.clock for (i <- 0 until numReadPorts) { - core.readPorts(i).addr := _out.data.read(i).rs - _out.data.read(i).src := core.readPorts(i).data + core.readPorts(i).addr := _out.in.rs(i) + _out.out.src(i) := core.readPorts(i).data } - core.writePort.addr := _out.data.write.addr - core.writePort.data := MuxLookup(_out.control.writeSelect, 0.U)( - _out.control.WriteSelect.all.map(x => (x -> _out.data.write.data(x.asUInt).asUInt)) - ) + core.writePort.addr := _out.in.writeAddr + core.writePort.data := _out.in.writeData(_out.control.writeSelect.asUInt) core.writePort.enable := _out.control.writeEnable _out } diff --git a/npc/core/src/test/scala/RegisterFile.scala b/npc/core/src/test/scala/RegisterFile.scala index f79bbe3..ebc59ee 100644 --- a/npc/core/src/test/scala/RegisterFile.scala +++ b/npc/core/src/test/scala/RegisterFile.scala @@ -1,4 +1,4 @@ -package flowpc +package flow import chisel3._ import chiseltest._ @@ -41,22 +41,40 @@ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester { } } "RegisterInterface" - { - "worked" in { - class Top extends Module { - val io = IO(new RegFileInterface(32, UInt(32.W), 2, 2)) - val rf = RegisterFile(32, UInt(32.W), 2, 2) - io :<>= rf - } + class Top extends Module { + val io = IO(new RegFileInterface(32, UInt(32.W), 2, 2)) + val rf = RegisterFile(32, UInt(32.W), 2, 2) + io :<>= rf + } + "write" in { test(new Top).withAnnotations(Seq(WriteVcdAnnotation)) { c => import c.io.control.WriteSelect._ val writePort = rAluOut.litValue.toInt c.io.control.writeEnable.poke(true) c.io.control.writeSelect.poke(rAluOut) - c.io.data.write.addr.poke(5) - c.io.data.write.data(writePort).poke(0xcdef) - c.io.data.read(0).rs.poke(5) + c.io.in.writeAddr.poke(5) + c.io.in.writeData(writePort).poke(0xcdef) + c.io.in.rs(0).poke(5) c.clock.step(1) - c.io.data.read(0).src.expect(0xcdef) + c.io.out.src(0).expect(0xcdef) + } + } + "no data is written when not enabled" in { + test(new Top).withAnnotations(Seq(WriteVcdAnnotation)) { c => + import c.io.control.WriteSelect._ + val writePort = rAluOut.litValue.toInt + c.io.control.writeEnable.poke(true) + c.io.control.writeSelect.poke(rAluOut) + c.io.in.writeAddr.poke(5) + c.io.in.writeData(writePort).poke(0xcdef) + c.io.in.rs(0).poke(5) + c.clock.step(1) + + c.io.control.writeEnable.poke(false) + c.io.in.writeData(writePort).poke(0x1234) + c.clock.step(1) + + c.io.out.src(0).expect(0xcdef) } } }