parent
42b7355b45
commit
290f584dcc
|
@ -4,14 +4,13 @@ import chisel3._
|
|||
import chisel3.util._
|
||||
|
||||
trait HasInstrType {
|
||||
def InstrN = "b0000".U
|
||||
def InstrI = "b0100".U
|
||||
def InstrR = "b0101".U
|
||||
def InstrS = "b0010".U
|
||||
def InstrB = "b0001".U
|
||||
def InstrU = "b0110".U
|
||||
def InstrJ = "b0111".U
|
||||
def InstrSA = "b1111".U // Atom Inst: SC
|
||||
def InstrN = "b000".U
|
||||
def InstrI = "b100".U
|
||||
def InstrR = "b101".U
|
||||
def InstrS = "b010".U
|
||||
def InstrB = "b001".U
|
||||
def InstrU = "b110".U
|
||||
def InstrJ = "b111".U
|
||||
|
||||
def isRegWen(instrType: UInt): Bool = instrType(2)
|
||||
}
|
||||
|
@ -24,10 +23,9 @@ object SrcType {
|
|||
}
|
||||
|
||||
object FuType {
|
||||
def num = 3
|
||||
def num = 2
|
||||
def alu = 0.U // arithmetic logic unit
|
||||
def mdu = 1.U // multiplication division unit
|
||||
def lsu = 2.U // load store unit
|
||||
def apply() = UInt(log2Up(num).W)
|
||||
}
|
||||
|
||||
|
@ -58,24 +56,6 @@ object ALUOpType {
|
|||
def isAdd(func: UInt) = func(5)
|
||||
}
|
||||
|
||||
// load store unit
|
||||
object LSUOpType {
|
||||
def lb = "b0000".U
|
||||
def lh = "b0001".U
|
||||
def lw = "b0010".U
|
||||
def ld = "b0011".U
|
||||
def lbu = "b0100".U
|
||||
def lhu = "b0101".U
|
||||
def lwu = "b0110".U
|
||||
def sb = "b1000".U
|
||||
def sh = "b1001".U
|
||||
def sw = "b1010".U
|
||||
def sd = "b1011".U
|
||||
|
||||
def isStore(func: UInt): Bool = func(3)
|
||||
def isLoad(func: UInt): Bool = !isStore(func)
|
||||
}
|
||||
|
||||
// mul div unit
|
||||
object MDUOpType {
|
||||
def mul = "b0000".U
|
||||
|
|
|
@ -56,28 +56,6 @@ object RV32I_ALUInstr extends HasInstrType with CoreParameter {
|
|||
)
|
||||
}
|
||||
|
||||
object RV32I_LSUInstr extends HasInstrType {
|
||||
def LB = BitPat("b????????????_?????_000_?????_0000011")
|
||||
def LH = BitPat("b????????????_?????_001_?????_0000011")
|
||||
def LW = BitPat("b????????????_?????_010_?????_0000011")
|
||||
def LBU = BitPat("b????????????_?????_100_?????_0000011")
|
||||
def LHU = BitPat("b????????????_?????_101_?????_0000011")
|
||||
def SB = BitPat("b???????_?????_?????_000_?????_0100011")
|
||||
def SH = BitPat("b???????_?????_?????_001_?????_0100011")
|
||||
def SW = BitPat("b???????_?????_?????_010_?????_0100011")
|
||||
|
||||
val table = Array(
|
||||
LB -> List(InstrI, FuType.lsu, LSUOpType.lb),
|
||||
LH -> List(InstrI, FuType.lsu, LSUOpType.lh),
|
||||
LW -> List(InstrI, FuType.lsu, LSUOpType.lw),
|
||||
LBU -> List(InstrI, FuType.lsu, LSUOpType.lbu),
|
||||
LHU -> List(InstrI, FuType.lsu, LSUOpType.lhu),
|
||||
SB -> List(InstrS, FuType.lsu, LSUOpType.sb),
|
||||
SH -> List(InstrS, FuType.lsu, LSUOpType.sh),
|
||||
SW -> List(InstrS, FuType.lsu, LSUOpType.sw)
|
||||
)
|
||||
}
|
||||
|
||||
object RV64IInstr extends HasInstrType {
|
||||
def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011")
|
||||
def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011")
|
||||
|
@ -102,14 +80,11 @@ object RV64IInstr extends HasInstrType {
|
|||
SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw),
|
||||
SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw),
|
||||
ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
|
||||
SUBW -> List(InstrR, FuType.alu, ALUOpType.subw),
|
||||
LWU -> List(InstrI, FuType.lsu, LSUOpType.lwu),
|
||||
LD -> List(InstrI, FuType.lsu, LSUOpType.ld),
|
||||
SD -> List(InstrS, FuType.lsu, LSUOpType.sd)
|
||||
SUBW -> List(InstrR, FuType.alu, ALUOpType.subw)
|
||||
)
|
||||
}
|
||||
|
||||
object RVIInstr extends CoreParameter {
|
||||
val table = RV32I_ALUInstr.table ++ RV32I_LSUInstr.table ++
|
||||
val table = RV32I_ALUInstr.table ++
|
||||
(if (XLEN == 64) RV64IInstr.table else Array.empty)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ class Decoder extends Module with HasInstrType {
|
|||
InstrI -> (SrcType.reg, SrcType.imm),
|
||||
InstrR -> (SrcType.reg, SrcType.reg),
|
||||
InstrS -> (SrcType.reg, SrcType.reg),
|
||||
InstrSA -> (SrcType.reg, SrcType.reg),
|
||||
InstrB -> (SrcType.reg, SrcType.reg),
|
||||
InstrU -> (SrcType.pc, SrcType.imm),
|
||||
InstrJ -> (SrcType.pc, SrcType.imm),
|
||||
|
@ -51,7 +50,6 @@ class Decoder extends Module with HasInstrType {
|
|||
Seq(
|
||||
InstrI -> SignedExtend(inst(31, 20), XLEN),
|
||||
InstrS -> SignedExtend(Cat(inst(31, 25), inst(11, 7)), XLEN),
|
||||
InstrSA -> SignedExtend(Cat(inst(31, 25), inst(11, 7)), XLEN),
|
||||
InstrB -> SignedExtend(Cat(inst(31), inst(7), inst(30, 25), inst(11, 8), 0.U(1.W)), XLEN),
|
||||
InstrU -> SignedExtend(Cat(inst(31, 12), 0.U(12.W)), XLEN),
|
||||
InstrJ -> SignedExtend(Cat(inst(31), inst(19, 12), inst(20), inst(30, 21), 0.U(1.W)), XLEN)
|
||||
|
|
|
@ -9,10 +9,10 @@ import cpu.CpuConfig
|
|||
class Fu extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val data = new Bundle {
|
||||
val pc = Input(UInt(XLEN.W))
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val rd_info = Output(new RdInfo())
|
||||
val pc = Input(UInt(XLEN.W))
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val rd_info = Output(new RdInfo())
|
||||
}
|
||||
|
||||
val dataSram = new DataSram()
|
||||
|
@ -20,7 +20,11 @@ class Fu extends Module {
|
|||
|
||||
val alu = Module(new Alu()).io
|
||||
val mdu = Module(new Mdu()).io
|
||||
val lsu = Module(new Lsu()).io
|
||||
|
||||
io.dataSram.en := false.B
|
||||
io.dataSram.addr := DontCare
|
||||
io.dataSram.wdata := DontCare
|
||||
io.dataSram.wen := 0.U
|
||||
|
||||
alu.info := io.data.info
|
||||
alu.src_info := io.data.src_info
|
||||
|
@ -28,10 +32,6 @@ class Fu extends Module {
|
|||
mdu.info := io.data.info
|
||||
mdu.src_info := io.data.src_info
|
||||
|
||||
lsu.info := io.data.info
|
||||
lsu.src_info := io.data.src_info
|
||||
lsu.dataSram <> io.dataSram
|
||||
|
||||
io.data.rd_info.wdata := DontCare
|
||||
io.data.rd_info.wdata(FuType.alu) := alu.result
|
||||
io.data.rd_info.wdata(FuType.mdu) := mdu.result
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
|
||||
class Lsu extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val dataSram = new DataSram()
|
||||
})
|
||||
|
||||
def genWmask(addr: UInt, sizeEncode: UInt): UInt = {
|
||||
LookupTree(
|
||||
sizeEncode,
|
||||
List(
|
||||
"b00".U -> 0x1.U, //0001 << addr(2:0)
|
||||
"b01".U -> 0x3.U, //0011
|
||||
"b10".U -> 0xf.U, //1111
|
||||
"b11".U -> 0xff.U //11111111
|
||||
)
|
||||
) << addr(2, 0)
|
||||
}
|
||||
def genWdata(data: UInt, sizeEncode: UInt): UInt = {
|
||||
LookupTree(
|
||||
sizeEncode,
|
||||
List(
|
||||
"b00".U -> Fill(8, data(7, 0)),
|
||||
"b01".U -> Fill(4, data(15, 0)),
|
||||
"b10".U -> Fill(2, data(31, 0)),
|
||||
"b11".U -> data
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
def genWmask32(addr: UInt, sizeEncode: UInt): UInt = {
|
||||
LookupTree(
|
||||
sizeEncode,
|
||||
List(
|
||||
"b00".U -> 0x1.U, //0001 << addr(1:0)
|
||||
"b01".U -> 0x3.U, //0011
|
||||
"b10".U -> 0xf.U //1111
|
||||
)
|
||||
) << addr(1, 0)
|
||||
}
|
||||
def genWdata32(data: UInt, sizeEncode: UInt): UInt = {
|
||||
LookupTree(
|
||||
sizeEncode,
|
||||
List(
|
||||
"b00".U -> Fill(4, data(7, 0)),
|
||||
"b01".U -> Fill(2, data(15, 0)),
|
||||
"b10".U -> data
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val valid = io.info.valid && io.info.fusel === FuType.lsu
|
||||
val op = io.info.op
|
||||
val is_load = valid && LSUOpType.isLoad(op)
|
||||
val is_store = valid && LSUOpType.isStore(op)
|
||||
val addr = io.src_info.src1_data + io.info.imm
|
||||
val wdata = io.src_info.src2_data
|
||||
val size = op(1, 0)
|
||||
val req_addr = if (XLEN == 32) SignedExtend(addr, XLEN) else addr
|
||||
val req_wdata = if (XLEN == 32) genWdata32(wdata, size) else genWdata(wdata, size)
|
||||
val req_wmask = if (XLEN == 32) genWmask32(addr, size) else genWmask(addr, size)
|
||||
val rdata = io.dataSram.rdata
|
||||
|
||||
val mem_op = Wire(FuOpType())
|
||||
val mem_addr = Wire(UInt(XLEN.W))
|
||||
val mem_partial_load = !LSUOpType.isStore(mem_op) && (mem_op =/= LSUOpType.ld)
|
||||
|
||||
val rdata64 = LookupTree(
|
||||
mem_addr(2, 0),
|
||||
List(
|
||||
"b000".U -> rdata(63, 0),
|
||||
"b001".U -> rdata(63, 8),
|
||||
"b010".U -> rdata(63, 16),
|
||||
"b011".U -> rdata(63, 24),
|
||||
"b100".U -> rdata(63, 32),
|
||||
"b101".U -> rdata(63, 40),
|
||||
"b110".U -> rdata(63, 48),
|
||||
"b111".U -> rdata(63, 56)
|
||||
)
|
||||
)
|
||||
val rdata32 = LookupTree(
|
||||
mem_addr(1, 0),
|
||||
List(
|
||||
"b00".U -> rdata(31, 0),
|
||||
"b01".U -> rdata(31, 8),
|
||||
"b10".U -> rdata(31, 16),
|
||||
"b11".U -> rdata(31, 24)
|
||||
)
|
||||
)
|
||||
val rdata_result = if (XLEN == 32) rdata32 else rdata64
|
||||
val rdata_partial_result = LookupTree(
|
||||
mem_op,
|
||||
List(
|
||||
LSUOpType.lb -> SignedExtend(rdata_result(7, 0), XLEN),
|
||||
LSUOpType.lh -> SignedExtend(rdata_result(15, 0), XLEN),
|
||||
LSUOpType.lw -> SignedExtend(rdata_result(31, 0), XLEN),
|
||||
LSUOpType.lbu -> ZeroExtend(rdata_result(7, 0), XLEN),
|
||||
LSUOpType.lhu -> ZeroExtend(rdata_result(15, 0), XLEN),
|
||||
LSUOpType.lwu -> ZeroExtend(rdata_result(31, 0), XLEN)
|
||||
)
|
||||
)
|
||||
val addr_aligned = LookupTree(
|
||||
op(1, 0),
|
||||
List(
|
||||
"b00".U -> true.B, //b
|
||||
"b01".U -> (addr(0) === 0.U), //h
|
||||
"b10".U -> (addr(1, 0) === 0.U), //w
|
||||
"b11".U -> (addr(2, 0) === 0.U) //d
|
||||
)
|
||||
)
|
||||
|
||||
io.dataSram.en := valid && addr_aligned
|
||||
io.dataSram.wen := req_wmask & Fill(8, is_store)
|
||||
io.dataSram.addr := req_addr // 在mem被阻塞时,保持原先的读地址不变
|
||||
io.dataSram.wdata := req_wdata
|
||||
|
||||
val result = Wire(UInt(XLEN.W))
|
||||
result := Mux(mem_partial_load, rdata_partial_result, rdata_result)
|
||||
BoringUtils.addSource(result, "mem_lsu_rdata")
|
||||
BoringUtils.addSink(mem_op, "mem_lsu_op")
|
||||
BoringUtils.addSink(mem_addr, "mem_lsu_addr")
|
||||
}
|
|
@ -13,17 +13,7 @@ class MemoryUnit extends Module {
|
|||
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
||||
})
|
||||
|
||||
val rdata = Wire(UInt(XLEN.W))
|
||||
val op = Wire(FuOpType())
|
||||
val addr = Wire(UInt(XLEN.W))
|
||||
op := io.memoryStage.data.info.op
|
||||
addr := io.memoryStage.data.src_info.src1_data + io.memoryStage.data.info.imm
|
||||
BoringUtils.addSink(rdata, "mem_lsu_rdata")
|
||||
BoringUtils.addSource(op, "mem_lsu_op")
|
||||
BoringUtils.addSource(addr, "mem_lsu_addr")
|
||||
|
||||
io.writeBackStage.data.pc := io.memoryStage.data.pc
|
||||
io.writeBackStage.data.info := io.memoryStage.data.info
|
||||
io.writeBackStage.data.rd_info.wdata := io.memoryStage.data.rd_info.wdata
|
||||
io.writeBackStage.data.rd_info.wdata(FuType.lsu) := rdata
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue