feat(npc): implement all riscv32i intructions (untested)
This commit is contained in:
parent
50f7d4d7b9
commit
8500df8a6e
7 changed files with 396 additions and 91 deletions
|
@ -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
|
|
@ -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
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 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???????_?????_?????_???_?????_?????_??")
|
||||
}
|
||||
|
||||
class PcControl(width: Int) extends Bundle {
|
||||
object SrcSelect extends ChiselEnum {
|
||||
val pPC, pExeResult = Value
|
||||
import flow.components.{RegControl, PcControlInterface, ALUControlInterface}
|
||||
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])
|
||||
}
|
||||
val srcSelect = Output(SrcSelect())
|
||||
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
|
||||
}
|
||||
|
||||
import flow.components.{RegControl, PcControlInterface, ALUControlInterface}
|
||||
class Control(width: Int) extends Module {
|
||||
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)
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue