diff --git a/npc/core/src/main/scala/ALU.scala b/npc/core/src/main/scala/ALU.scala index a16e64c..8a55719 100644 --- a/npc/core/src/main/scala/ALU.scala +++ b/npc/core/src/main/scala/ALU.scala @@ -9,10 +9,15 @@ class ALUControlInterface extends Bundle { val aOpAdd, aOpSub, aOpNot, aOpAnd, aOpOr, aOpXor, aOpSlt, aOpEq, aOpNop = Value } val op = Input(OpSelect()) + + type ctrlTypes = OpSelect.Type :: HNil + def ctrlBindPorts: ctrlTypes = { + op :: HNil + } } class ALU[T <: UInt](tpe: T) extends Module { - val control = new ALUControlInterface + val control = IO(new ALUControlInterface) val in = IO(new Bundle { val a = Input(tpe) val b = Input(tpe) @@ -33,7 +38,7 @@ class ALU[T <: UInt](tpe: T) extends Module { import control.OpSelect._ - out.result := MuxLookup(control.op, aOpNop.asUInt)(Seq( + out.result := MuxLookup(control.op, 0.U)(Seq( aOpAdd -> add, aOpSub -> sub, aOpNot -> not, @@ -43,15 +48,10 @@ class ALU[T <: UInt](tpe: T) extends Module { aOpSlt -> slt, aOpEq -> eq )) - - type ctrlTypes = control.OpSelect.Type :: HNil - def ctrlBindPorts: ctrlTypes = { - control.op :: HNil - } } object ALU { def apply[T <: UInt](tpe: T): ALU[T] = { - new ALU(tpe) + Module(new ALU(tpe)) } } diff --git a/npc/core/src/main/scala/Main.scala b/npc/core/src/main/scala/Main.scala index 685f801..efad2fe 100644 --- a/npc/core/src/main/scala/Main.scala +++ b/npc/core/src/main/scala/Main.scala @@ -16,7 +16,7 @@ import shapeless.ops.coproduct.Prepend object RV32Inst { private val bp = BitPat - val addi = this.bp("b??b?????_?????_?????_000_?????_00100_11") + val addi = this.bp("b???????_?????_?????_000_?????_00100_11") val inv = this.bp("b???????_?????_?????_???_?????_?????_??") } @@ -28,46 +28,57 @@ class PcControl(width: Int) extends Bundle { } -import flow.components.{ RegisterFile, ProgramCounter, ALU } +import flow.components.{ RegisterFile, RegFileInterface, ProgramCounter, ALU } +import flow.components.{ RegControl, PcControlInterface, ALUControlInterface } class Control(width: Int) extends Module { - val inst = Input(UInt(width.W)) - val reg = Flipped(RegisterFile(32, UInt(width.W), 2, 2)) - val pc = ProgramCounter(UInt(width.W)) - val alu = ALU(UInt(width.W)) + val inst = IO(Input(UInt(width.W))) - // TODO: Add .ctrlTypes together instead of write them by hand. - type T = Bool :: reg.control.WriteSelect.Type :: pc.SrcSelect.Type :: alu.control.OpSelect.Type :: HNil + val reg = IO(Flipped(new RegControl)) + val pc = IO(Flipped(new PcControlInterface)) + val alu = IO(Flipped(new ALUControlInterface)) + + + // TODO: Add .ctrlTypes together instead of writing them by hand. + type T = Bool :: reg.WriteSelect.Type :: pc.SrcSelect.Type :: alu.OpSelect.Type :: HNil val dst: T = reg.ctrlBindPorts ++ pc.ctrlBindPorts ++ alu.ctrlBindPorts - val dstList: List[Data] = dst.toList - val reversePrefixSum = dstList.scanLeft(0)(_ + _.getWidth).reverse - val slices = reversePrefixSum.zip(reversePrefixSum.tail) - - import reg.control.WriteSelect._ + import reg.WriteSelect._ import pc.SrcSelect._ - import alu.control.OpSelect._ + import alu.OpSelect._ import RV32Inst._ val ControlMapping: Array[(BitPat, T)] = Array( - // Regs :: PC :: Exe - // writeEnable :: writeSelect :: srcSelect :: - (addi, false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil) + // Regs :: PC :: Exe + // writeEnable :: writeSelect :: srcSelect :: + (addi, false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil) ) - def toBits(t: T): BitPat = { val list: List[Data] = t.toList - list.map(x => x.asUInt).map(x => BitPat(x)).reduce(_ ## _) + list.map(x => BitPat(x.litValue.toInt.U(x.getWidth.W))).reduce(_ ## _) } - val out = decoder(QMCMinimizer, inst, TruthTable( - ControlMapping.map(it => (it._1, toBits(it._2))), inv)) + val default = toBits(false.B :: rAluOut :: pStaticNpc :: aOpSlt:: HNil) + val out = decoder(QMCMinimizer, inst, TruthTable( + ControlMapping.map(it => (it._1, toBits(it._2))), default)) + + val dstList = dst.toList + val reversePrefixSum = dstList.scanLeft(0)(_ + _.getWidth).reverse + val slices = reversePrefixSum.zip(reversePrefixSum.tail) val srcList = slices.map(s => out(s._1 - 1, s._2)) - srcList.zip(dstList).foreach({ case (src, dst) => dst := src }) + + // 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) + }) } 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 control = new Control(32) + val control = Module(new Control(32)) // Instruction Fetch ram.readPorts(0).enable := true.B diff --git a/npc/core/src/main/scala/ProgramCounter.scala b/npc/core/src/main/scala/ProgramCounter.scala index 0f0adba..9b78cf3 100644 --- a/npc/core/src/main/scala/ProgramCounter.scala +++ b/npc/core/src/main/scala/ProgramCounter.scala @@ -4,30 +4,33 @@ import chisel3.util.{Valid, log2Ceil} import chisel3.util.MuxLookup import shapeless.{HNil, ::} -class ProgramCounter[T <: Data](tpe: T) extends Module { +class PcControlInterface extends Bundle { object SrcSelect extends ChiselEnum { val pStaticNpc, pBranchResult = Value } - val control = IO(new Bundle { - val srcSelect = Input(SrcSelect()) - }) - val in = IO(new Bundle { - val pcSrcs = Input(Vec(SrcSelect.all.length, tpe)) - }) - val out = Output(tpe) - - out := in.pcSrcs(control.srcSelect.asUInt) + val srcSelect = Input(SrcSelect()) type ctrlTypes = SrcSelect.Type :: HNil def ctrlBindPorts: ctrlTypes = { - control.srcSelect :: HNil + srcSelect :: HNil } } +class ProgramCounter[T <: Data](tpe: T) extends Module { + + val control = IO(new PcControlInterface) + val in = IO(new Bundle { + val pcSrcs = Input(Vec(control.SrcSelect.all.length, tpe)) + }) + val out = IO(Output(tpe)) + + out := in.pcSrcs(control.srcSelect.asUInt) +} + object ProgramCounter { def apply[T <: Data](tpe: T): ProgramCounter[T] = { - val pc = new ProgramCounter(tpe) + val pc = Module(new ProgramCounter(tpe)) pc } } diff --git a/npc/core/src/main/scala/RegisterFile.scala b/npc/core/src/main/scala/RegisterFile.scala index 9ba7b64..8fc77d0 100644 --- a/npc/core/src/main/scala/RegisterFile.scala +++ b/npc/core/src/main/scala/RegisterFile.scala @@ -13,6 +13,11 @@ class RegControl extends Bundle { val writeEnable = Input(Bool()) val writeSelect = Input(WriteSelect()) + + type ctrlTypes = Bool :: WriteSelect.Type :: HNil + def ctrlBindPorts: ctrlTypes = { + writeEnable :: writeSelect :: HNil + } } class RegFileData[T <: Data](size:Int, tpe: T, numReadPorts: Int, numWritePorts: Int) extends Bundle { @@ -29,11 +34,6 @@ 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) - - type ctrlTypes = Bool :: control.WriteSelect.Type :: HNil - def ctrlBindPorts: ctrlTypes = { - control.writeEnable :: control.writeSelect :: HNil - } } class RegisterFileCore[T <: Data](size: Int, tpe: T, numReadPorts: Int) extends Module { diff --git a/npc/core/src/test/scala/RegisterFile.scala b/npc/core/src/test/scala/RegisterFile.scala index 87be171..f79bbe3 100644 --- a/npc/core/src/test/scala/RegisterFile.scala +++ b/npc/core/src/test/scala/RegisterFile.scala @@ -5,7 +5,7 @@ import chiseltest._ import org.scalatest.freespec.AnyFreeSpec import chiseltest.simulator.WriteVcdAnnotation -import flowpc.components._ +import flow.components._ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester { "RegisterFileCore" - { "register 0 is always 0" in {