parent
42b7355b45
commit
290f584dcc
|
@ -4,14 +4,13 @@ import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
|
||||||
trait HasInstrType {
|
trait HasInstrType {
|
||||||
def InstrN = "b0000".U
|
def InstrN = "b000".U
|
||||||
def InstrI = "b0100".U
|
def InstrI = "b100".U
|
||||||
def InstrR = "b0101".U
|
def InstrR = "b101".U
|
||||||
def InstrS = "b0010".U
|
def InstrS = "b010".U
|
||||||
def InstrB = "b0001".U
|
def InstrB = "b001".U
|
||||||
def InstrU = "b0110".U
|
def InstrU = "b110".U
|
||||||
def InstrJ = "b0111".U
|
def InstrJ = "b111".U
|
||||||
def InstrSA = "b1111".U // Atom Inst: SC
|
|
||||||
|
|
||||||
def isRegWen(instrType: UInt): Bool = instrType(2)
|
def isRegWen(instrType: UInt): Bool = instrType(2)
|
||||||
}
|
}
|
||||||
|
@ -24,10 +23,9 @@ object SrcType {
|
||||||
}
|
}
|
||||||
|
|
||||||
object FuType {
|
object FuType {
|
||||||
def num = 3
|
def num = 2
|
||||||
def alu = 0.U // arithmetic logic unit
|
def alu = 0.U // arithmetic logic unit
|
||||||
def mdu = 1.U // multiplication division unit
|
def mdu = 1.U // multiplication division unit
|
||||||
def lsu = 2.U // load store unit
|
|
||||||
def apply() = UInt(log2Up(num).W)
|
def apply() = UInt(log2Up(num).W)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,24 +56,6 @@ object ALUOpType {
|
||||||
def isAdd(func: UInt) = func(5)
|
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
|
// mul div unit
|
||||||
object MDUOpType {
|
object MDUOpType {
|
||||||
def mul = "b0000".U
|
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 {
|
object RV64IInstr extends HasInstrType {
|
||||||
def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011")
|
def ADDIW = BitPat("b???????_?????_?????_000_?????_0011011")
|
||||||
def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011")
|
def SLLIW = BitPat("b0000000_?????_?????_001_?????_0011011")
|
||||||
|
@ -102,14 +80,11 @@ object RV64IInstr extends HasInstrType {
|
||||||
SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw),
|
SRLW -> List(InstrR, FuType.alu, ALUOpType.srlw),
|
||||||
SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw),
|
SRAW -> List(InstrR, FuType.alu, ALUOpType.sraw),
|
||||||
ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
|
ADDW -> List(InstrR, FuType.alu, ALUOpType.addw),
|
||||||
SUBW -> List(InstrR, FuType.alu, ALUOpType.subw),
|
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)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
object RVIInstr extends CoreParameter {
|
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)
|
(if (XLEN == 64) RV64IInstr.table else Array.empty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ class Decoder extends Module with HasInstrType {
|
||||||
InstrI -> (SrcType.reg, SrcType.imm),
|
InstrI -> (SrcType.reg, SrcType.imm),
|
||||||
InstrR -> (SrcType.reg, SrcType.reg),
|
InstrR -> (SrcType.reg, SrcType.reg),
|
||||||
InstrS -> (SrcType.reg, SrcType.reg),
|
InstrS -> (SrcType.reg, SrcType.reg),
|
||||||
InstrSA -> (SrcType.reg, SrcType.reg),
|
|
||||||
InstrB -> (SrcType.reg, SrcType.reg),
|
InstrB -> (SrcType.reg, SrcType.reg),
|
||||||
InstrU -> (SrcType.pc, SrcType.imm),
|
InstrU -> (SrcType.pc, SrcType.imm),
|
||||||
InstrJ -> (SrcType.pc, SrcType.imm),
|
InstrJ -> (SrcType.pc, SrcType.imm),
|
||||||
|
@ -51,7 +50,6 @@ class Decoder extends Module with HasInstrType {
|
||||||
Seq(
|
Seq(
|
||||||
InstrI -> SignedExtend(inst(31, 20), XLEN),
|
InstrI -> SignedExtend(inst(31, 20), XLEN),
|
||||||
InstrS -> SignedExtend(Cat(inst(31, 25), inst(11, 7)), 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),
|
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),
|
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)
|
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 {
|
class Fu extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val data = new Bundle {
|
val data = new Bundle {
|
||||||
val pc = Input(UInt(XLEN.W))
|
val pc = Input(UInt(XLEN.W))
|
||||||
val info = Input(new Info())
|
val info = Input(new Info())
|
||||||
val src_info = Input(new SrcInfo())
|
val src_info = Input(new SrcInfo())
|
||||||
val rd_info = Output(new RdInfo())
|
val rd_info = Output(new RdInfo())
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataSram = new DataSram()
|
val dataSram = new DataSram()
|
||||||
|
@ -20,7 +20,11 @@ class Fu extends Module {
|
||||||
|
|
||||||
val alu = Module(new Alu()).io
|
val alu = Module(new Alu()).io
|
||||||
val mdu = Module(new Mdu()).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.info := io.data.info
|
||||||
alu.src_info := io.data.src_info
|
alu.src_info := io.data.src_info
|
||||||
|
@ -28,10 +32,6 @@ class Fu extends Module {
|
||||||
mdu.info := io.data.info
|
mdu.info := io.data.info
|
||||||
mdu.src_info := io.data.src_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 := DontCare
|
||||||
io.data.rd_info.wdata(FuType.alu) := alu.result
|
io.data.rd_info.wdata(FuType.alu) := alu.result
|
||||||
io.data.rd_info.wdata(FuType.mdu) := mdu.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 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.pc := io.memoryStage.data.pc
|
||||||
io.writeBackStage.data.info := io.memoryStage.data.info
|
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 := io.memoryStage.data.rd_info.wdata
|
||||||
io.writeBackStage.data.rd_info.wdata(FuType.lsu) := rdata
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue