修改util
This commit is contained in:
parent
b75c49177e
commit
fe0aa71511
|
@ -3,13 +3,13 @@ package cpu.defines
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
|
||||||
object Util {
|
object SubwordModify {
|
||||||
def subwordModify(source: UInt, start: Int, md: UInt): UInt = {
|
def apply(source: UInt, start: Int, md: UInt): UInt = {
|
||||||
val ms = md.getWidth
|
val ms = md.getWidth
|
||||||
subwordModify(source, (start, start - ms + 1), md)
|
apply(source, (start, start - ms + 1), md)
|
||||||
}
|
}
|
||||||
|
|
||||||
def subwordModify(source: UInt, tuple: (Int, Int), md: UInt): UInt = {
|
def apply(source: UInt, tuple: (Int, Int), md: UInt): UInt = {
|
||||||
val ws = source.getWidth
|
val ws = source.getWidth
|
||||||
val ms = md.getWidth
|
val ms = md.getWidth
|
||||||
val start = tuple._1
|
val start = tuple._1
|
||||||
|
@ -23,42 +23,107 @@ object Util {
|
||||||
else if (start == ws - 1) Cat(md, source(end - 1, 0))
|
else if (start == ws - 1) Cat(md, source(end - 1, 0))
|
||||||
else Cat(source(ws - 1, start + 1), md, source(end - 1, 0))
|
else Cat(source(ws - 1, start + 1), md, source(end - 1, 0))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def listHasElement(list: Seq[UInt], element: UInt): Bool = {
|
object SignedExtend {
|
||||||
list.foldLeft(false.B)((r, e) => r || (e === element))
|
def apply(a: UInt, len: Int) = {
|
||||||
}
|
|
||||||
|
|
||||||
def MAXnBIT(m: Int): BigInt = BigInt(1) << m
|
|
||||||
|
|
||||||
def unsignedToSigned(s: BigInt, width: Int = 32): BigInt = {
|
|
||||||
val m = MAXnBIT(width - 1)
|
|
||||||
if (s >= m) s - 2 * m
|
|
||||||
else s
|
|
||||||
}
|
|
||||||
|
|
||||||
def signedExtend(a: UInt, len: Int) = {
|
|
||||||
val aLen = a.getWidth
|
val aLen = a.getWidth
|
||||||
val signBit = a(aLen - 1)
|
val signBit = a(aLen - 1)
|
||||||
if (aLen >= len) a(len - 1, 0) else Cat(Fill(len - aLen, signBit), a)
|
if (aLen >= len) a(len - 1, 0) else Cat(Fill(len - aLen, signBit), a)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
def zeroExtend(raw: UInt, to: Int = 32): UInt = {
|
|
||||||
zeroExtend(raw, raw.getWidth, to)
|
object ZeroExtend {
|
||||||
}
|
def apply(a: UInt, len: Int) = {
|
||||||
|
val aLen = a.getWidth
|
||||||
def zeroExtend(raw: UInt, from: Int, to: Int): UInt = {
|
if (aLen >= len) a(len - 1, 0) else Cat(0.U((len - aLen).W), a)
|
||||||
require(to > from && from >= 1)
|
}
|
||||||
Cat(Fill(to - from, 0.U), raw)
|
}
|
||||||
}
|
object LookupTree {
|
||||||
|
def apply[T <: Data](key: UInt, mapping: Iterable[(UInt, T)]): T =
|
||||||
object LookupTree {
|
Mux1H(mapping.map(p => (p._1 === key, p._2)))
|
||||||
def apply[T <: Data](key: UInt, mapping: Iterable[(UInt, T)]): T =
|
}
|
||||||
Mux1H(mapping.map(p => (p._1 === key, p._2)))
|
|
||||||
}
|
object LookupTreeDefault {
|
||||||
|
def apply[T <: Data](key: UInt, default: T, mapping: Iterable[(UInt, T)]): T =
|
||||||
object LookupTreeDefault {
|
MuxLookup(key, default)(mapping.toSeq)
|
||||||
def apply[T <: Data](key: UInt, default: T, mapping: Iterable[(UInt, T)]): T =
|
}
|
||||||
MuxLookup(key, default)(mapping.toSeq)
|
|
||||||
}
|
object MaskData {
|
||||||
|
def apply(oldData: UInt, newData: UInt, fullmask: UInt) = {
|
||||||
|
require(oldData.getWidth == newData.getWidth)
|
||||||
|
require(oldData.getWidth == fullmask.getWidth)
|
||||||
|
(newData & fullmask) | (oldData & ~fullmask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object RegMap {
|
||||||
|
def Unwritable = null
|
||||||
|
def apply(addr: Int, reg: UInt, wfn: UInt => UInt = (x => x)) = (addr, (reg, wfn))
|
||||||
|
def generate(
|
||||||
|
mapping: Map[Int, (UInt, UInt => UInt)],
|
||||||
|
raddr: UInt,
|
||||||
|
rdata: UInt,
|
||||||
|
waddr: UInt,
|
||||||
|
wen: Bool,
|
||||||
|
wdata: UInt,
|
||||||
|
wmask: UInt
|
||||||
|
): Unit = {
|
||||||
|
val chiselMapping = mapping.map { case (a, (r, w)) => (a.U, r, w) }
|
||||||
|
rdata := LookupTree(raddr, chiselMapping.map { case (a, r, w) => (a, r) })
|
||||||
|
chiselMapping.map {
|
||||||
|
case (a, r, w) =>
|
||||||
|
if (w != null) when(wen && waddr === a) { r := w(MaskData(r, wdata, wmask)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def generate(
|
||||||
|
mapping: Map[Int, (UInt, UInt => UInt)],
|
||||||
|
addr: UInt,
|
||||||
|
rdata: UInt,
|
||||||
|
wen: Bool,
|
||||||
|
wdata: UInt,
|
||||||
|
wmask: UInt
|
||||||
|
): Unit = generate(mapping, addr, rdata, addr, wen, wdata, wmask)
|
||||||
|
}
|
||||||
|
|
||||||
|
object MaskedRegMap extends CoreParameter {
|
||||||
|
def Unwritable = null
|
||||||
|
def NoSideEffect: UInt => UInt = (x => x)
|
||||||
|
def WritableMask = Fill(XLEN, true.B)
|
||||||
|
def UnwritableMask = 0.U(XLEN.W)
|
||||||
|
def apply(
|
||||||
|
addr: Int,
|
||||||
|
reg: UInt,
|
||||||
|
wmask: UInt = WritableMask,
|
||||||
|
wfn: UInt => UInt = (x => x),
|
||||||
|
rmask: UInt = WritableMask
|
||||||
|
) = (addr, (reg, wmask, wfn, rmask))
|
||||||
|
def generate(
|
||||||
|
mapping: Map[Int, (UInt, UInt, UInt => UInt, UInt)],
|
||||||
|
raddr: UInt,
|
||||||
|
rdata: UInt,
|
||||||
|
waddr: UInt,
|
||||||
|
wen: Bool,
|
||||||
|
wdata: UInt
|
||||||
|
): Unit = {
|
||||||
|
val chiselMapping = mapping.map { case (a, (r, wm, w, rm)) => (a.U, r, wm, w, rm) }
|
||||||
|
rdata := LookupTree(raddr, chiselMapping.map { case (a, r, wm, w, rm) => (a, r & rm) })
|
||||||
|
chiselMapping.map {
|
||||||
|
case (a, r, wm, w, rm) =>
|
||||||
|
if (w != null && wm != UnwritableMask) when(wen && waddr === a) { r := w(MaskData(r, wdata, wm)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def isIllegalAddr(mapping: Map[Int, (UInt, UInt, UInt => UInt, UInt)], addr: UInt): Bool = {
|
||||||
|
val illegalAddr = Wire(Bool())
|
||||||
|
val chiselMapping = mapping.map { case (a, (r, wm, w, rm)) => (a.U, r, wm, w, rm) }
|
||||||
|
illegalAddr := LookupTreeDefault(addr, true.B, chiselMapping.map { case (a, r, wm, w, rm) => (a, false.B) })
|
||||||
|
illegalAddr
|
||||||
|
}
|
||||||
|
def generate(
|
||||||
|
mapping: Map[Int, (UInt, UInt, UInt => UInt, UInt)],
|
||||||
|
addr: UInt,
|
||||||
|
rdata: UInt,
|
||||||
|
wen: Bool,
|
||||||
|
wdata: UInt
|
||||||
|
): Unit = generate(mapping, addr, rdata, addr, wen, wdata)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import cpu.defines.Const._
|
||||||
import cpu.{BranchPredictorConfig, CpuConfig}
|
import cpu.{BranchPredictorConfig, CpuConfig}
|
||||||
import cpu.pipeline.execute.DecoderUnitExecuteUnit
|
import cpu.pipeline.execute.DecoderUnitExecuteUnit
|
||||||
import cpu.pipeline.fetch.BufferUnit
|
import cpu.pipeline.fetch.BufferUnit
|
||||||
|
import cpu.pipeline.execute
|
||||||
|
|
||||||
class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle {
|
class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle {
|
||||||
val allow_to_go = Output(Vec(config.decoderNum, Bool()))
|
val allow_to_go = Output(Vec(config.decoderNum, Bool()))
|
||||||
|
@ -24,21 +25,13 @@ class DataForwardToDecoderUnit extends Bundle {
|
||||||
val mem = new RegWrite()
|
val mem = new RegWrite()
|
||||||
}
|
}
|
||||||
|
|
||||||
class CsrDecoderUnit extends Bundle {
|
|
||||||
val access_allowed = Bool()
|
|
||||||
val kernel_mode = Bool()
|
|
||||||
val intterupt_allowed = Bool()
|
|
||||||
val cause_ip = UInt(8.W)
|
|
||||||
val status_im = UInt(8.W)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExceptionNO {
|
class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExceptionNO {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
// 输入
|
// 输入
|
||||||
val instFifo = new InstFifoDecoderUnit()
|
val instFifo = new InstFifoDecoderUnit()
|
||||||
val regfile = Vec(config.decoderNum, new Src12Read())
|
val regfile = Vec(config.decoderNum, new Src12Read())
|
||||||
val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit()))
|
val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit()))
|
||||||
val csr = Input(new CsrDecoderUnit())
|
val csr = Input(new execute.CsrDecoderUnit())
|
||||||
// 输出
|
// 输出
|
||||||
val fetchUnit = new Bundle {
|
val fetchUnit = new Bundle {
|
||||||
val branch = Output(Bool())
|
val branch = Output(Bool())
|
||||||
|
@ -121,12 +114,13 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti
|
||||||
io.executeStage.inst0.ex.int.zip(int.asBools).map { case (x, y) => x := y }
|
io.executeStage.inst0.ex.int.zip(int.asBools).map { case (x, y) => x := y }
|
||||||
val hasInt = int.orR
|
val hasInt = int.orR
|
||||||
|
|
||||||
|
io.executeStage.inst0.valid := !io.instFifo.info.empty
|
||||||
io.executeStage.inst0.pc := pc(0)
|
io.executeStage.inst0.pc := pc(0)
|
||||||
io.executeStage.inst0.inst_info := inst_info(0)
|
io.executeStage.inst0.inst_info := inst_info(0)
|
||||||
io.executeStage.inst0.src_info.src1_data := Mux(
|
io.executeStage.inst0.src_info.src1_data := Mux(
|
||||||
inst_info(0).reg1_ren,
|
inst_info(0).reg1_ren,
|
||||||
forwardCtrl.out.inst(0).src1.rdata,
|
forwardCtrl.out.inst(0).src1.rdata,
|
||||||
Util.signedExtend(pc(0), INST_ADDR_WID)
|
SignedExtend(pc(0), INST_ADDR_WID)
|
||||||
)
|
)
|
||||||
io.executeStage.inst0.src_info.src2_data := Mux(
|
io.executeStage.inst0.src_info.src2_data := Mux(
|
||||||
inst_info(0).reg2_ren,
|
inst_info(0).reg2_ren,
|
||||||
|
@ -145,12 +139,13 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti
|
||||||
io.executeStage.inst0.jb_info.branch_target := io.bpu.branch_target
|
io.executeStage.inst0.jb_info.branch_target := io.bpu.branch_target
|
||||||
io.executeStage.inst0.jb_info.update_pht_index := io.bpu.update_pht_index
|
io.executeStage.inst0.jb_info.update_pht_index := io.bpu.update_pht_index
|
||||||
if (config.decoderNum == 2) {
|
if (config.decoderNum == 2) {
|
||||||
|
io.executeStage.inst1.valid := !io.instFifo.info.almost_empty
|
||||||
io.executeStage.inst1.pc := pc(1)
|
io.executeStage.inst1.pc := pc(1)
|
||||||
io.executeStage.inst1.inst_info := inst_info(1)
|
io.executeStage.inst1.inst_info := inst_info(1)
|
||||||
io.executeStage.inst1.src_info.src1_data := Mux(
|
io.executeStage.inst1.src_info.src1_data := Mux(
|
||||||
inst_info(1).reg1_ren,
|
inst_info(1).reg1_ren,
|
||||||
forwardCtrl.out.inst(1).src1.rdata,
|
forwardCtrl.out.inst(1).src1.rdata,
|
||||||
Util.signedExtend(pc(1), INST_ADDR_WID)
|
SignedExtend(pc(1), INST_ADDR_WID)
|
||||||
)
|
)
|
||||||
io.executeStage.inst1.src_info.src2_data := Mux(
|
io.executeStage.inst1.src_info.src2_data := Mux(
|
||||||
inst_info(1).reg2_ren,
|
inst_info(1).reg2_ren,
|
||||||
|
@ -161,8 +156,7 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti
|
||||||
io.executeStage.inst1.ex.excode(illegalInstr) := !decoder(1).io.out.inst_info.inst_valid &&
|
io.executeStage.inst1.ex.excode(illegalInstr) := !decoder(1).io.out.inst_info.inst_valid &&
|
||||||
!hasInt && !io.instFifo.info.almost_empty
|
!hasInt && !io.instFifo.info.almost_empty
|
||||||
io.executeStage.inst1.ex.excode(instrAccessFault) := io.instFifo.inst(1).acc_err
|
io.executeStage.inst1.ex.excode(instrAccessFault) := io.instFifo.inst(1).acc_err
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
io.executeStage.inst1 := DontCare
|
io.executeStage.inst1 := DontCare
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
(io.memoryUnit.in.mem_sel(0) && !io.memoryUnit.in.ex(0).flush_req ||
|
(io.memoryUnit.in.mem_sel(0) && !io.memoryUnit.in.ex(0).flush_req ||
|
||||||
io.memoryUnit.in.mem_sel(1) && !io.memoryUnit.in.ex(0).flush_req && !io.memoryUnit.in.ex(1).flush_req)
|
io.memoryUnit.in.mem_sel(1) && !io.memoryUnit.in.ex(0).flush_req && !io.memoryUnit.in.ex(1).flush_req)
|
||||||
io.dataMemory.out.addr := mem_addr
|
io.dataMemory.out.addr := mem_addr
|
||||||
val rdata = Util.LookupTree(
|
val rdata = LookupTree(
|
||||||
mem_addr(2, 0),
|
mem_addr(2, 0),
|
||||||
List(
|
List(
|
||||||
"b000".U -> mem_rdata(63, 0),
|
"b000".U -> mem_rdata(63, 0),
|
||||||
|
@ -57,19 +57,19 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
"b111".U -> mem_rdata(63, 56)
|
"b111".U -> mem_rdata(63, 56)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
io.memoryUnit.out.rdata := Util.LookupTree(
|
io.memoryUnit.out.rdata := LookupTree(
|
||||||
op,
|
op,
|
||||||
List(
|
List(
|
||||||
LSUOpType.lb -> Util.signedExtend(rdata(7, 0), XLEN),
|
LSUOpType.lb -> SignedExtend(rdata(7, 0), XLEN),
|
||||||
LSUOpType.lh -> Util.signedExtend(rdata(15, 0), XLEN),
|
LSUOpType.lh -> SignedExtend(rdata(15, 0), XLEN),
|
||||||
LSUOpType.lw -> Util.signedExtend(rdata(31, 0), XLEN),
|
LSUOpType.lw -> SignedExtend(rdata(31, 0), XLEN),
|
||||||
LSUOpType.lbu -> Util.zeroExtend(rdata(7, 0), XLEN),
|
LSUOpType.lbu -> ZeroExtend(rdata(7, 0), XLEN),
|
||||||
LSUOpType.lhu -> Util.zeroExtend(rdata(15, 0), XLEN),
|
LSUOpType.lhu -> ZeroExtend(rdata(15, 0), XLEN),
|
||||||
LSUOpType.lwu -> Util.zeroExtend(rdata(31, 0), XLEN)
|
LSUOpType.lwu -> ZeroExtend(rdata(31, 0), XLEN)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def genWdata(data: UInt, sizeEncode: UInt): UInt = {
|
def genWdata(data: UInt, sizeEncode: UInt): UInt = {
|
||||||
Util.LookupTree(
|
LookupTree(
|
||||||
sizeEncode,
|
sizeEncode,
|
||||||
List(
|
List(
|
||||||
"b00".U -> Fill(8, data(7, 0)),
|
"b00".U -> Fill(8, data(7, 0)),
|
||||||
|
@ -81,7 +81,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
}
|
}
|
||||||
io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0))
|
io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0))
|
||||||
def genWmask(addr: UInt, sizeEncode: UInt): UInt = {
|
def genWmask(addr: UInt, sizeEncode: UInt): UInt = {
|
||||||
Util.LookupTree(
|
LookupTree(
|
||||||
sizeEncode,
|
sizeEncode,
|
||||||
List(
|
List(
|
||||||
"b00".U -> 0x1.U, //0001 << addr(2:0)
|
"b00".U -> 0x1.U, //0001 << addr(2:0)
|
||||||
|
|
Loading…
Reference in New Issue