diff --git a/npc/core/src/main/resources/RamDpi.v b/npc/core/src/main/resources/RamDpi.v index d6e3c98..c9f8b7c 100644 --- a/npc/core/src/main/resources/RamDpi.v +++ b/npc/core/src/main/resources/RamDpi.v @@ -8,7 +8,9 @@ module RamDpi ( input [31:0] writeData, input [3:0] writeMask, input reg [31:0] readAddr, - output reg [31:0] readData + output reg [31:0] readData, + input reg [31:0] pc, + output reg [31:0] inst ); always @(*) begin if (valid) begin // 有读写请求时 @@ -20,5 +22,6 @@ module RamDpi ( else begin readData = 0; end + inst = pmem_read(pc); end endmodule \ No newline at end of file diff --git a/npc/core/src/main/scala/components/ALU.scala b/npc/core/src/main/scala/components/ALU.scala index 9a0b0f9..0c22b15 100644 --- a/npc/core/src/main/scala/components/ALU.scala +++ b/npc/core/src/main/scala/components/ALU.scala @@ -6,41 +6,50 @@ import shapeless.{HNil, ::} class ALUControlInterface extends Bundle { object OpSelect extends ChiselEnum { - val aOpAdd, aOpSub, aOpNot, aOpAnd, aOpOr, aOpXor, aOpSlt, aOpEq, aOpNop = Value + val aOpAdd, aOpSub, aOpNot, aOpAnd, aOpOr, aOpXor, aOpSlt, aOpSll, aOpSrl, aOpSra = Value } - object SrcSelect extends ChiselEnum { - val aSrcRs2, aSrcImm = Value + object SrcASelect extends ChiselEnum { + val aSrcARs1, aSrcAPc, aSrcAZero = Value + } + object SrcBSelect extends ChiselEnum { + val aSrcBRs2, aSrcBImmI, aSrcBImmJ, aSrcBImmB, aSrcBImmS = Value } val op = Input(OpSelect()) - val src = Input(SrcSelect()) + val srcASelect = Input(SrcASelect()) + val srcBSelect = Input(SrcBSelect()) + val signExt = Input(Bool()) - type CtrlTypes = OpSelect.Type :: SrcSelect.Type :: HNil - def ctrlBindPorts: CtrlTypes = { - op :: src :: HNil + def ctrlBindPorts = { + op :: srcASelect :: srcBSelect :: signExt :: HNil } } class ALU[T <: UInt](tpe: T) extends Module { val control = IO(new ALUControlInterface) val in = IO(new Bundle { - val a = Input(Vec(control.SrcSelect.all.length, tpe)) - val b = Input(tpe) + val a = Input(Vec(control.SrcASelect.all.length, tpe)) + val b = Input(Vec(control.SrcBSelect.all.length, tpe)) }) val out = IO(new Bundle { + val eq = Output(Bool()) val result = Output(tpe) }) - val a = in.a(control.src.asUInt) + val a = in.a(control.srcASelect.asUInt) + val b = in.b(control.srcBSelect.asUInt) // val adder_b = (Fill(tpe.getWidth, io.op(0)) ^ io.b) + io.op(0) // take (-b) if sub - val add = a + in.b - val sub = a - in.b - val and = a & in.b + val add = a + b + val sub = a - b + val and = a & b val not = ~a - val or = a | in.b - val xor = a ^ in.b - val slt = a < in.b - val eq = a === in.b + val or = a | b + val xor = a ^ b + val slt = a < b + val sll = a << b(log2Ceil(tpe.getWidth), 0) + val srl = a >> b(log2Ceil(tpe.getWidth), 0) + val sra = a.asSInt >> b(log2Ceil(tpe.getWidth), 0) + out.eq := a === b import control.OpSelect._ @@ -52,7 +61,9 @@ class ALU[T <: UInt](tpe: T) extends Module { aOpOr -> or, aOpXor -> xor, aOpSlt -> slt, - aOpEq -> eq + aOpSll -> sll, + aOpSrl -> srl, + aOpSra -> sra.asUInt )) } diff --git a/npc/core/src/main/scala/components/Mem.scala b/npc/core/src/main/scala/components/Mem.scala index 6634edb..7562730 100644 --- a/npc/core/src/main/scala/components/Mem.scala +++ b/npc/core/src/main/scala/components/Mem.scala @@ -6,19 +6,32 @@ import chisel3.util.HasBlackBoxResource import chisel3.util.log2Ceil import chisel3.experimental.noPrefix import scala.collection.SeqMap -import javax.swing.plaf.synth.SynthRadioButtonMenuItemUI +import flow.components +import shapeless.{HNil, ::} -class RamInterface[T <: Data](tpe: T, addrWidth: Int) extends Bundle { +class RamControlInterface(addrWidth: Int) extends Bundle { val valid = Input(Bool()) + val writeMask = Input(UInt((addrWidth / 8).W)) val writeEnable = Input(Bool()) + def ctrlBindPorts = { + valid :: writeMask :: writeEnable :: HNil + } + +} + +/* FIXME: Extends here might not be the best solution. + * We need a way to merge two bundles together + */ +class RamInterface[T <: Data](tpe: T, addrWidth: Int) extends RamControlInterface(addrWidth) { val writeAddr = Input(UInt(addrWidth.W)) val writeData = Input(tpe) - val writeMask = Input(UInt((addrWidth / 8).W)) val readAddr = Input(UInt(addrWidth.W)) val readData = Output(tpe) + val pc = Input(UInt(addrWidth.W)) + val inst = Output(tpe) } class RamDpi extends BlackBox with HasBlackBoxResource { - val io = IO(new RamInterface(UInt(32.W), 32)) + val io = IO((new RamInterface(UInt(32.W), 32))) addResource("/RamDpi.v") } diff --git a/npc/core/src/main/scala/components/ProgramCounter.scala b/npc/core/src/main/scala/components/ProgramCounter.scala index bfb3e1b..01ac115 100644 --- a/npc/core/src/main/scala/components/ProgramCounter.scala +++ b/npc/core/src/main/scala/components/ProgramCounter.scala @@ -6,33 +6,42 @@ import shapeless.{HNil, ::} class PcControlInterface extends Bundle { object SrcSelect extends ChiselEnum { - val pStaticNpc, pBranchResult = Value + val pStaticNpc, pExeOut = Value } + val useImmB = Input(Bool()) val srcSelect = Input(SrcSelect()) - type CtrlTypes = SrcSelect.Type :: HNil - def ctrlBindPorts: CtrlTypes = { - srcSelect :: HNil + def ctrlBindPorts = { + useImmB :: srcSelect :: HNil } } -class ProgramCounter[T <: Data](tpe: T) extends Module { +class ProgramCounter[T <: UInt](tpe: T) extends Module { val control = IO(new PcControlInterface) val in = IO(new Bundle { - val pcSrcs = Input(Vec(control.SrcSelect.all.length, tpe)) + val immB = Input(tpe) + val exeOut = Input(tpe) }) val out = IO(Output(tpe)) - private val pc = RegInit(0x80000000L.U) + private val pc_reg = RegInit(0x80000000L.U) - pc := in.pcSrcs(control.srcSelect.asUInt) - out := pc +// pc := in.pcSrcs(control.srcSelect.asUInt) + import control.SrcSelect._ + when( control.useImmB === true.B ) { + pc_reg := pc_reg + in.immB + }. elsewhen( control.srcSelect === pStaticNpc) { + pc_reg := pc_reg + 4.U + }. elsewhen( control.srcSelect === pExeOut) { + pc_reg := in.exeOut + } + out := pc_reg } object ProgramCounter { - def apply[T <: Data](tpe: T): ProgramCounter[T] = { + def apply[T <: UInt](tpe: T): ProgramCounter[T] = { val pc = Module(new ProgramCounter(tpe)) pc } diff --git a/npc/core/src/main/scala/components/RegisterFile.scala b/npc/core/src/main/scala/components/RegisterFile.scala index 9b50375..b5d1b63 100644 --- a/npc/core/src/main/scala/components/RegisterFile.scala +++ b/npc/core/src/main/scala/components/RegisterFile.scala @@ -5,18 +5,17 @@ import chisel3.util.log2Ceil import chisel3.util.UIntToOH import chisel3.util.MuxLookup import chisel3.experimental.Trace._ -import shapeless.{ HNil, :: } +import shapeless.{ HList, HNil, :: } class RegControl extends Bundle { object WriteSelect extends ChiselEnum { - val rAluOut, rMemOut = Value + val rAluOut, rMemOut, rNpc = Value } val writeEnable = Input(Bool()) val writeSelect = Input(WriteSelect()) - type CtrlTypes = Bool :: WriteSelect.Type :: HNil - def ctrlBindPorts: CtrlTypes = { + def ctrlBindPorts = { writeEnable :: writeSelect :: HNil } traceName(writeEnable) @@ -40,7 +39,8 @@ class RegisterFile[T <: Data](tpe: T, regCount: Int, numReadPorts: Int) extends val writeAddrOH = UIntToOH(in.writeAddr) for ((reg, i) <- regFile.zipWithIndex.tail) { - reg := Mux(writeAddrOH(i.U(log2Ceil(regCount).W)) && control.writeEnable, in.writeData(control.writeSelect.asUInt), reg) + reg := Mux( + writeAddrOH(i.U(log2Ceil(regCount).W)) && control.writeEnable, in.writeData(control.writeSelect.asUInt), reg) } regFile(0) := 0.U diff --git a/npc/core/src/main/scala/top/FlowMain.scala b/npc/core/src/main/scala/top/FlowMain.scala index 73df9ed..899783c 100644 --- a/npc/core/src/main/scala/top/FlowMain.scala +++ b/npc/core/src/main/scala/top/FlowMain.scala @@ -2,12 +2,8 @@ package flow import scala.reflect.runtime.universe._ import chisel3._ -import chisel3.util.{MuxLookup, Fill, Decoupled, Counter, Queue, Reverse} -import chisel3.util.{SRAM} import chisel3.util.experimental.decode.{decoder, TruthTable} -import chisel3.util.log2Ceil -import chisel3.util.BitPat -import chisel3.util.Enum +import chisel3.util._ import chisel3.experimental.Trace._ import shapeless.{HNil, ::} import shapeless.HList @@ -15,68 +11,322 @@ import shapeless.ops.coproduct.Prepend import chisel3.util.{ BinaryMemoryFile, HexMemoryFile } import chisel3.experimental.Trace +import scala.collection.IndexedSeqView +import shapeless.Poly1 +import flow.components.RamControlInterface object RV32Inst { private val bp = BitPat - val addi = this.bp("b???????_?????_?????_000_?????_00100_11") - val inv = this.bp("b???????_?????_?????_???_?????_?????_??") -} -class PcControl(width: Int) extends Bundle { - object SrcSelect extends ChiselEnum { - val pPC, pExeResult = Value - } - val srcSelect = Output(SrcSelect()) + val lui = this.bp("b???????_?????_?????_???_?????_01101_11") + val auipc = this.bp("b???????_?????_?????_???_?????_00101_11") + + val jal = this.bp("b???????_?????_?????_???_?????_11011_11") + val jalr = this.bp("b???????_?????_?????_???_?????_11001_11") + val beq = this.bp("b???????_?????_?????_000_?????_11000_11") + val bne = this.bp("b???????_?????_?????_001_?????_11000_11") + val blt = this.bp("b???????_?????_?????_100_?????_11000_11") + val bge = this.bp("b???????_?????_?????_101_?????_11000_11") + val bltu = this.bp("b???????_?????_?????_110_?????_11000_11") + val bgeu = this.bp("b???????_?????_?????_111_?????_11000_11") + + val lb = this.bp("b???????_?????_?????_000_?????_00000_11") + val lh = this.bp("b???????_?????_?????_001_?????_00000_11") + val lw = this.bp("b???????_?????_?????_010_?????_00000_11") + val lbu = this.bp("b???????_?????_?????_100_?????_00000_11") + val lhu = this.bp("b???????_?????_?????_101_?????_00000_11") + val sb = this.bp("b???????_?????_?????_000_?????_01000_11") + val sh = this.bp("b???????_?????_?????_001_?????_01000_11") + val sw = this.bp("b???????_?????_?????_010_?????_01000_11") + + val addi = this.bp("b???????_?????_?????_000_?????_00100_11") + val slti = this.bp("b???????_?????_?????_010_?????_00100_11") + val sltiu = this.bp("b???????_?????_?????_011_?????_00100_11") + val xori = this.bp("b???????_?????_?????_100_?????_00100_11") + val ori = this.bp("b???????_?????_?????_110_?????_00100_11") + val andi = this.bp("b???????_?????_?????_111_?????_00100_11") + val slli = this.bp("b0000000_?????_?????_001_?????_00100_11") + val srli = this.bp("b0000000_?????_?????_101_?????_00100_11") + val srai = this.bp("b0100000_?????_?????_101_?????_00100_11") + val add = this.bp("b0000000_?????_?????_000_?????_01100_11") + val sub = this.bp("b0100000_?????_?????_000_?????_01100_11") + val sll = this.bp("b0000000_?????_?????_001_?????_01100_11") + val slt = this.bp("b0000000_?????_?????_010_?????_01100_11") + val sltu = this.bp("b0000000_?????_?????_011_?????_01100_11") + val xor = this.bp("b0000000_?????_?????_100_?????_01100_11") + val srl = this.bp("b0000000_?????_?????_101_?????_01100_11") + val sra = this.bp("b0100000_?????_?????_101_?????_01100_11") + val or = this.bp("b0000000_?????_?????_110_?????_01100_11") + val and = this.bp("b0000000_?????_?????_111_?????_01100_11") + + val ebreak = this.bp("b0000000_00001_00000_000_00000_11100_11") + + + val mul = this.bp("b0000001_?????_?????_000_?????_01100_11") + val mulh = this.bp("b0000001_?????_?????_001_?????_01100_11") + val mulhsu = this.bp("b0000001_?????_?????_010_?????_01100_11") + val mulhu = this.bp("b0000001_?????_?????_011_?????_01100_11") + val div = this.bp("b0000001_?????_?????_100_?????_01100_11") + val divu = this.bp("b0000001_?????_?????_101_?????_01100_11") + val rem = this.bp("b0000001_?????_?????_110_?????_01100_11") + val remu = this.bp("b0000001_?????_?????_111_?????_01100_11") + + val inv = this.bp("b???????_?????_?????_???_?????_?????_??") } import flow.components.{RegControl, PcControlInterface, ALUControlInterface} -class Control(width: Int) extends Module { +class Control(width: Int) extends RawModule { + // Helpers + class WrapList[T](vl: T) { type Type = T; val v = vl} + object wrap extends Poly1 { + implicit def default[A] = at[A](Right(_).withLeft[Int]) + } + def lit(x: Element) = { x.litValue.toInt } + def toBits(t: dst.Type): BitPat = { + val list = t.toList + list.map(e => e match { + case Right(x) => BitPat(lit(x).U(x.getWidth.W)) + case Left(x) => BitPat.dontCare(x) + }).reduceLeft(_ ## _) + } + val r = Right + def l[T <: Any](x: T) = x match { + case x: ChiselEnum => Left(log2Ceil(x.all.length)) + case x: Data => Left(x.getWidth) + case _ => throw new IllegalArgumentException + } + val inst = IO(Input(UInt(width.W))) val reg = IO(Flipped(new RegControl)) val pc = IO(Flipped(new PcControlInterface)) val alu = IO(Flipped(new ALUControlInterface)) + val ram = IO(Flipped(new RamControlInterface(32))) - // TODO: Add .ctrlTypes together instead of writing them by hand. - type T = - Bool :: reg.WriteSelect.Type :: pc.SrcSelect.Type :: alu.OpSelect.Type :: alu.SrcSelect.Type :: HNil - val dst: T = reg.ctrlBindPorts ++ pc.ctrlBindPorts ++ alu.ctrlBindPorts + val dst = new WrapList(( + reg.ctrlBindPorts ++ + pc.ctrlBindPorts ++ + alu.ctrlBindPorts ++ + ram.ctrlBindPorts).map(wrap)) - val dstList = dst.toList - val reversePrefixSum = dstList.scanLeft(0)(_ + _.getWidth).reverse - val slices = reversePrefixSum.zip(reversePrefixSum.tail) + val dstList = dst.v.toList + val controlWidth = dstList.map(_.toOption.get.getWidth).reduce(_ + _) + val reversePrefixSum = dstList.scanLeft(0)(_ + _.toOption.get.getWidth) + val sliceIndex = reversePrefixSum.map(controlWidth - _) + val slices = sliceIndex.map(_ - 1).zip(sliceIndex.tail) import reg.WriteSelect._ + import reg._ import pc.SrcSelect._ + import pc._ import alu.OpSelect._ - import alu.SrcSelect._ + import alu.SrcASelect._ + import alu.SrcBSelect._ + import pc._ import RV32Inst._ - val ControlMapping: Array[(BitPat, T)] = Array( - // Regs :: PC :: Exe - // writeEnable :: writeSelect :: srcSelect :: - (addi, true.B :: rAluOut :: pStaticNpc :: aOpAdd :: aSrcImm :: HNil), - ) - val default = BitPat.dontCare(dstList.map(_.getWidth).reduce(_ + _)) + val ControlMapping: Array[(BitPat, dst.Type)] = Array( + // Regs | writeEnable :: writeSelect :: HNil + // PC | useImmB :: srcSelect :: HNil + // Exe | op :: srcASelect :: srcBSelect :: signExt :: HNil + // Mem | valid :: writeMask :: writeEnable :: HNil - def toBits(t: T): BitPat = { - val list: List[Data] = t.toList - list.map(x => BitPat(x.litValue.toInt.U(x.getWidth.W))).reduceLeft(_ ## _) - } + // ---- Control Transfer Instructions ---- + (jal , (r(true.B) :: r(rNpc) :: + r(false.B) :: r(pExeOut) :: + r(aOpAdd) :: r(aSrcAPc) :: r(aSrcBImmJ) :: r(false.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (jalr , (r(true.B) :: r(rNpc) :: + r(false.B) :: r(pExeOut) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmJ) :: r(false.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (beq , (r(false.B) :: l(WriteSelect) :: + r(true.B) :: r(pExeOut) :: + r(aOpSlt) :: r(aSrcAPc) :: r(aSrcBImmB) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (bne , (r(false.B) :: l(WriteSelect) :: + r(true.B) :: r(pExeOut) :: + r(aOpSlt) :: r(aSrcAPc) :: r(aSrcBImmB) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (blt , (r(false.B) :: l(WriteSelect) :: + r(true.B) :: r(pExeOut) :: + r(aOpSlt) :: r(aSrcAPc) :: r(aSrcBImmB) :: r(true.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (bge , (r(false.B) :: l(WriteSelect) :: + r(true.B) :: r(pExeOut) :: + r(aOpSlt) :: r(aSrcAPc) :: r(aSrcBImmB) :: r(true.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (bltu , (r(false.B) :: l(WriteSelect):: + r(true.B) :: r(pExeOut) :: + r(aOpSlt) :: r(aSrcAPc) :: r(aSrcBImmB) :: r(false.B) :: + r(false.B) :: l(UInt(4.W)) :: r(false.B) :: HNil)), + + (bgeu , (r(false.B) :: l(WriteSelect):: + r(true.B) :: r(pExeOut) :: + r(aOpSlt) :: r(aSrcAPc) :: r(aSrcBImmB) :: r(false.B) :: + r(false.B) :: l(UInt(4.W)) :: r(false.B) :: HNil)), + + // ---- Memory Access Instructions ---- + + (lb , (r(true.B) :: r(rMemOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(true.B) :: l(UInt(4.W)) :: r(false.B) :: HNil)), + + (lh , (r(true.B) :: r(rMemOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(true.B) :: l(UInt(4.W)) :: r(false.B) :: HNil)), + + (lw , (r(true.B) :: r(rMemOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(true.B) :: l(UInt(4.W)) :: r(false.B) :: HNil)), + + (sb , (r(false.B) :: l(WriteSelect):: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(true.B) :: r(1.U(4.W)) :: r(false.B) :: HNil)), + + (sh , (r(false.B) :: l(WriteSelect):: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(true.B) :: r(3.U(4.W)) :: r(false.B) :: HNil)), + + (sw , (r(false.B) :: l(WriteSelect):: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(true.B) :: r(15.U(4.W)) :: r(false.B) :: HNil)), + + // ---- Integer Computational Instructions --- + + (addi , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (slti , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(true.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (sltiu , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(false.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (xori , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpOr) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (ori , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpXor) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (andi , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAnd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (slli , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSll) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (srli , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSrl) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (srai , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSra) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (add , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (sub , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSub) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (sll , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSll) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (slt , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(true.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (sltu , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (xor , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpXor) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (srl , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSrl) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (sra , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpSra) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (or , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpOr) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + + (and , (r(true.B) :: r(rAluOut) :: + r(false.B) :: r(pStaticNpc) :: + r(aOpAnd) :: r(aSrcARs1) :: r(aSrcBRs2) :: l(Bool()) :: + r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)), + ) + + val default = BitPat(0.U(controlWidth.W)) + +// println(s"ControlMapping = ${ControlMapping.map(it => (it._1 -> toBits(it._2))).foreach(x => println(x._2))}\n") val out = decoder( inst, TruthTable(ControlMapping.map(it => (it._1 -> toBits(it._2))), default)) - val srcList = slices.map(s => out(s._1 - 1, s._2)) + val srcList = slices.map(s => out(s._1, s._2)) + assert(out != default) + println(s"out = $out, default = $default\n") + println(s"dstList = ${dstList}\n") + println(s"srcList = ${srcList}\n") srcList - .zip(dstList.reverse) + .zip(dstList) .foreach({ case (src, dst) => - dst := src.asTypeOf(dst) + dst.toOption.get := src.asTypeOf(dst.toOption.get) }) + + pc.useImmB := DontCare } import flow.components.{RegisterFile, ProgramCounter, ALU, RamDpi} import chisel3.util.experimental.loadMemoryFromFileInline class Flow extends Module { + def lit(x: Data) = { x.litValue.toInt } + val dataType = UInt(32.W) val ram = Module(new RamDpi) val control = Module(new Control(32)) @@ -84,42 +334,61 @@ class Flow extends Module { val pc = Module(new ProgramCounter(dataType)) val alu = Module(new ALU(dataType)) - ram.io.readAddr := pc.out - val inst = ram.io.readData + // TODO: Switch to Decoupled and Arbiter later + ram.io.pc := pc.out + val inst = ram.io.inst dontTouch(reg.control.writeEnable) import control.pc.SrcSelect._ - pc.in.pcSrcs(pStaticNpc.litValue.toInt) := pc.out + 4.U - pc.in.pcSrcs(pBranchResult.litValue.toInt) := alu.out.result + val npc = Wire(dataType) + npc := pc.out + 4.U + pc.in.exeOut := alu.out.result + pc.in.immB := Cat(Fill(20, inst(31)), inst(7), inst(30, 25), inst(11, 8), inst(0)) control.inst := inst reg.control <> control.reg + // FIXME: Probably optimizable with bulk connection pc.control <> control.pc alu.control <> control.alu + val branchUseSlt = Wire(Bool()) + val branchInvertResult = Wire(Bool()) + branchUseSlt := inst(14) + branchInvertResult := inst(12) + val _branchResult = Mux(branchUseSlt, alu.out.result(0), alu.out.eq) + val branchResult = Mux(branchInvertResult, _branchResult, !_branchResult) + pc.control.useImmB := control.pc.useImmB && _branchResult import control.reg.WriteSelect._ - reg.in.writeData(rAluOut.litValue.toInt) := alu.out.result - + reg.in.writeData(lit(rAluOut)) := alu.out.result // TODO: Read address in load command goes here - reg.in.writeData(rMemOut.litValue.toInt) := DontCare + reg.in.writeData(lit(rMemOut)) := ram.io.readData + reg.in.writeData(lit(rNpc)) := npc reg.in.writeAddr := inst(11, 7) reg.in.rs(0) := inst(19, 15) // rs1 reg.in.rs(1) := inst(24, 20) // rs2 // TODO: Memory write goes here - ram.io.writeAddr := DontCare - ram.io.writeData := DontCare - ram.io.writeMask := DontCare - ram.io.writeEnable := false.B + ram.io.writeAddr := alu.out.result + ram.io.writeData := reg.out.src(1) + ram.io.writeMask := control.ram.writeMask + ram.io.writeEnable := control.ram.writeEnable ram.io.valid := true.B + ram.io.readAddr := alu.out.result - import control.alu.SrcSelect._ - alu.in.a(aSrcRs2.litValue.toInt) := reg.out.src(1) - alu.in.a(aSrcImm.litValue.toInt) := inst(31, 20) - alu.in.b := reg.out.src(0) + import control.alu.SrcASelect._ + import control.alu.SrcBSelect._ + alu.in.a(lit(aSrcARs1)) := reg.out.src(0) + alu.in.a(lit(aSrcAPc)) := pc.out + alu.in.a(lit(aSrcAZero)) := 0.U + + alu.in.b(lit(aSrcBRs2)) := reg.out.src(1) + alu.in.b(lit(aSrcBImmI)) := inst(31, 20).pad(aSrcBImmI.getWidth) + alu.in.b(lit(aSrcBImmJ)) := Cat(Fill(12, inst(31)), inst(19, 12), inst(20), inst(30, 25), inst(24, 21), 0.U(1.W)) + alu.in.b(lit(aSrcBImmB)) := Cat(Fill(20, inst(31)), inst(7), inst(30, 25), inst(11, 8), inst(0)) + alu.in.b(lit(aSrcBImmS)) := Cat(inst(31), inst(19, 12), inst(20), inst(30, 25), inst(24, 21), 0.U(1.W)).pad(aSrcBImmS.getWidth) Trace.traceName(pc.out); dontTouch(control.out) diff --git a/npc/core/src/main/scala/top/Main.scala b/npc/core/src/main/scala/top/Main.scala index 3c02ff3..6de6893 100644 --- a/npc/core/src/main/scala/top/Main.scala +++ b/npc/core/src/main/scala/top/Main.scala @@ -34,7 +34,7 @@ object VerilogMain extends App { } val annos = (new ChiselStage).execute( - Array("--target-dir", opt.targetDir.toString, "--target", "systemverilog", "--split-verilog"), + Array("--target-dir", opt.targetDir.toString, "--target", "systemverilog", "--split-verilog", "--full-stacktrace"), Seq( ) ++ (if(config.traceConfig.enable) Seq(ChiselGeneratorAnnotation(() => new Flow)) else Seq()) @@ -56,9 +56,9 @@ object VerilogMain extends App { .foreach( ct => println(s"""TOP.${ct.circuit}.${ct.path.map { case (Instance(i), _) => i }.mkString(".")}.${ct.tokens.collectFirst { case Ref(r) => r - }.get}""") + }.get}""") ) - + val verilatorConfigWriter = new PrintWriter(new File(opt.targetDir, opt.verilatorConfigFileOut.toString())) verilatorConfigWriter.write("`verilator_config\n") try {