fix(npc): fix branch, load memory and slt related instructions

This commit is contained in:
xinyangli 2024-04-12 14:08:52 +08:00
parent 9f64a88f8d
commit 8665aaf7d2
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
11 changed files with 105 additions and 63 deletions

View file

@ -2,6 +2,8 @@ import "DPI-C" function int pmem_read(input int addr);
import "DPI-C" function void pmem_write(input int waddr, input int wdata, input byte wmask);
module RamDpi (
input clock,
input reset,
input writeEnable,
input valid,
input [31:0] writeAddr,

View file

@ -6,13 +6,13 @@ import shapeless.{HNil, ::}
class ALUControlInterface extends Bundle {
object OpSelect extends ChiselEnum {
val aOpAdd, aOpSub, aOpNot, aOpAnd, aOpOr, aOpXor, aOpSlt, aOpSll, aOpSrl, aOpSra = Value
val aOpAdd, aOpSub, aOpNot, aOpAnd, aOpOr, aOpXor, aOpSlt, aOpSltu, aOpSll, aOpSrl, aOpSra = Value
}
object SrcASelect extends ChiselEnum {
val aSrcARs1, aSrcAPc, aSrcAZero = Value
}
object SrcBSelect extends ChiselEnum {
val aSrcBRs2, aSrcBImmI, aSrcBImmJ, aSrcBImmB, aSrcBImmS, aSrcBImmU = Value
val aSrcBRs2, aSrcBImmI, aSrcBImmJ, aSrcBImmS, aSrcBImmU = Value
}
val op = Input(OpSelect())
val srcASelect = Input(SrcASelect())
@ -45,7 +45,8 @@ class ALU[T <: UInt](tpe: T) extends Module {
val not = ~a
val or = a | b
val xor = a ^ b
val slt = a < b
val slt = a.asSInt < b.asSInt
val sltu = 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)
@ -61,6 +62,7 @@ class ALU[T <: UInt](tpe: T) extends Module {
aOpOr -> or,
aOpXor -> xor,
aOpSlt -> slt,
aOpSltu -> sltu,
aOpSll -> sll,
aOpSrl -> srl,
aOpSra -> sra.asUInt

View file

@ -23,6 +23,8 @@ class RamControlInterface(addrWidth: Int) extends Bundle {
* We need a way to merge two bundles together
*/
class RamInterface[T <: Data](tpe: T, addrWidth: Int) extends RamControlInterface(addrWidth) {
val clock = Input(Clock())
val reset = Input(Reset())
val writeAddr = Input(UInt(addrWidth.W))
val writeData = Input(tpe)
val readAddr = Input(UInt(addrWidth.W))

View file

@ -152,33 +152,33 @@ class Control(width: Int) extends RawModule {
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(true.B) :: r(pStaticNpc) ::
r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: 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(true.B) :: r(pStaticNpc) ::
r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: 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(true.B) :: r(pStaticNpc) ::
r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: 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(true.B) :: r(pStaticNpc) ::
r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: 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(true.B) :: r(pStaticNpc) ::
r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBRs2) :: 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(true.B) :: r(pStaticNpc) ::
r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) ::
r(false.B) :: l(UInt(4.W)) :: r(false.B) :: HNil)),
// ---- Memory Access Instructions ----
@ -186,32 +186,42 @@ class Control(width: Int) extends RawModule {
(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)),
r(true.B) :: r(1.U(4.W)) :: r(false.B) :: HNil)),
(lh , (r(true.B) :: r(rMemOut) ::
(lbu , (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)),
r(true.B) :: r(0.U(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) :: r(3.U(4.W)) :: r(false.B) :: HNil)),
(lhu , (r(true.B) :: r(rMemOut) ::
r(false.B) :: r(pStaticNpc) ::
r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmI) :: l(Bool()) ::
r(true.B) :: r(2.U(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)),
r(true.B) :: r(14.U(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)),
r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmS) :: l(Bool()) ::
r(true.B) :: r(1.U(4.W)) :: r(true.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)),
r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmS) :: l(Bool()) ::
r(true.B) :: r(3.U(4.W)) :: r(true.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)),
r(aOpAdd) :: r(aSrcARs1) :: r(aSrcBImmS) :: l(Bool()) ::
r(true.B) :: r(15.U(4.W)) :: r(true.B) :: HNil)),
// ---- Integer Computational Instructions ---
@ -227,7 +237,7 @@ class Control(width: Int) extends RawModule {
(sltiu , (r(true.B) :: r(rAluOut) ::
r(false.B) :: r(pStaticNpc) ::
r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(false.B) ::
r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBImmI) :: r(false.B) ::
r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)),
(xori , (r(true.B) :: r(rAluOut) ::
@ -282,7 +292,7 @@ class Control(width: Int) extends RawModule {
(sltu , (r(true.B) :: r(rAluOut) ::
r(false.B) :: r(pStaticNpc) ::
r(aOpSlt) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) ::
r(aOpSltu) :: r(aSrcARs1) :: r(aSrcBRs2) :: r(false.B) ::
r(false.B) :: l(UInt(4.W)):: r(false.B) :: HNil)),
(xor , (r(true.B) :: r(rAluOut) ::
@ -328,8 +338,6 @@ class Control(width: Int) extends RawModule {
.foreach({ case (src, dst) =>
dst.toOption.get := src.asTypeOf(dst.toOption.get)
})
pc.useImmB := DontCare
}
import flow.components.{RegisterFile, ProgramCounter, ALU, RamDpi}
@ -355,37 +363,60 @@ class Flow extends Module {
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))
pc.in.immB := Cat(Fill(20, inst(31)), inst(7), inst(30, 25), inst(11, 8), 0.U(1.W))
control.inst := inst
reg.control <> control.reg
// FIXME: Probably optimizable with bulk connection
pc.control <> control.pc
pc.control.useImmB := control.pc.useImmB
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
val branchResult = Mux(branchInvertResult, !_branchResult, _branchResult)
pc.control.useImmB := control.pc.useImmB && branchResult
// printf(cf"_branchResult = ${_branchResult}, branchResult = ${branchResult}\n")
// printf(cf"pcin.useImmB = ${pc.control.useImmB}, control.out.useImmB = ${control.pc.useImmB} \n")
import control.reg.WriteSelect._
reg.in.writeData(lit(rAluOut)) := alu.out.result
// TODO: Read address in load command goes here
reg.in.writeData(lit(rMemOut)) := ram.io.readData
val maskedData = ram.io.readData & Cat(
Fill(8, ram.io.writeMask(3)),
Fill(8, ram.io.writeMask(2)),
Fill(8, ram.io.writeMask(1)),
"b11111111".U)
val doSignExt = control.ram.writeMask(0)
val signExt16 = control.ram.writeMask(1)
when(!doSignExt) {
reg.in.writeData(lit(rMemOut)) := maskedData
// printf(cf"!doSignExt\n")
}.elsewhen(signExt16) {
reg.in.writeData(lit(rMemOut)) := Cat(Fill(16, maskedData(15)), maskedData(15, 0))
// printf(cf"elsewhen\n")
}.otherwise {
reg.in.writeData(lit(rMemOut)) := Cat(Fill(24, maskedData(7)), maskedData(7, 0))
// printf(cf"otherwise\n")
}
// printf(cf"maskedData = ${maskedData}, writeData = ${reg.in.writeData(lit(rMemOut))}\n")
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
// TODO: Bulk connection here
// FIXME: The following 2 lines won't compile with bloop
ram.io.clock := clock
ram.io.reset := reset
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.valid := control.ram.valid
ram.io.readAddr := alu.out.result
import control.alu.SrcASelect._
@ -398,11 +429,9 @@ class Flow extends Module {
// alu.in.b(lit(aSrcBImmI)) := inst(31, 20).pad(aSrcBImmI.getWidth)
alu.in.b(lit(aSrcBImmI)) := Cat(Fill(20, inst(31)), inst(31, 20))
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)
alu.in.b(lit(aSrcBImmS)) := Cat(Fill(20, inst(31)), inst(31), inst(30, 25), inst(11, 8), inst(7))
alu.in.b(lit(aSrcBImmU)) := Cat(inst(31, 12), 0.U(12.W))
printf(cf"inst = $inst\n");
Trace.traceName(pc.out);
Trace.traceName(pc.out)
dontTouch(control.out)
}