Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6aa3592
feat: add some inst
Chrisqcwx Mar 19, 2023
6a5a383
feat: add branch inst
Chrisqcwx Mar 20, 2023
1562843
feat: add branch inst
Chrisqcwx Mar 20, 2023
53284e8
Merge branch 'main' of github.com:Invalid-Syntax-NSCSCC/invalid-cpu
Chrisqcwx Mar 20, 2023
20b2f67
Merge branch 'main' of github.com:Invalid-Syntax-NSCSCC/invalid-cpu i…
Chrisqcwx Mar 20, 2023
651dd92
feat: add branch inst
Chrisqcwx Mar 20, 2023
87b6016
fix: fix some bug in MulStage
Chrisqcwx Mar 20, 2023
4099b34
feat: add load store inst
Chrisqcwx Mar 20, 2023
b9592b2
feat: add load and store inst
Chrisqcwx Mar 21, 2023
f175e9e
Merge branch 'dev-yhy'
Chrisqcwx Mar 21, 2023
1cab7e2
fix: deal conflict
Chrisqcwx Mar 21, 2023
bae2228
fix: fix some bug in ExeStage
Chrisqcwx Mar 21, 2023
d240163
fix: add decoder fallback
Chrisqcwx Mar 21, 2023
dbfe974
delete temp issueStage
Chrisqcwx Mar 21, 2023
a1ab1a1
refactor: add insts in SimpleCpuSpec
Chrisqcwx Mar 22, 2023
aabdf2d
refactor: comments
Mar 22, 2023
7c3452c
fix: make bullshit in `IssueStage` smell better
Mar 22, 2023
8db4f3b
fix: when you are free to go, even you are still in blocking state, y…
Mar 22, 2023
9ce6d48
test some inst
Chrisqcwx Mar 22, 2023
a8d83f2
Merge branch 'dev-yhy' of github.com:Invalid-Syntax-NSCSCC/invalid-cp…
Chrisqcwx Mar 22, 2023
0f3eba8
fix: now it's not a mess in `IssueStage`
Mar 23, 2023
d7ea58c
Merge branch 'dev-yhy' of github.com:Invalid-Syntax-NSCSCC/invalid-cp…
Chrisqcwx Mar 23, 2023
9bb53df
refactor: refactor exeStage with state machine
Chrisqcwx Mar 23, 2023
ad419bf
refactor: alu
Chrisqcwx Mar 23, 2023
72a6c6a
refactor: reformat
Chrisqcwx Mar 24, 2023
1dc7725
feat: avoid recalculating mul and div in alu when stall
Chrisqcwx Mar 25, 2023
035f1c3
refactor: reformat
Chrisqcwx Mar 25, 2023
6a09062
deal with conflicts
Chrisqcwx Mar 25, 2023
02fde3c
deal with conflicts
Chrisqcwx Mar 25, 2023
31e519c
feat: add some inst
Chrisqcwx Mar 25, 2023
0d52bcd
refactor: reformat
Chrisqcwx Mar 25, 2023
f8f6b2b
feat: add mem stage
Chrisqcwx Mar 26, 2023
f77c9ee
refactor: rename MemLoadStoreNdPort -> MemLoadStoreInfoNdPort
Chrisqcwx Mar 26, 2023
2f84aaf
deal with conflicts
Chrisqcwx Mar 26, 2023
ddbca6c
Merge branch 'main' into dev-yhy
rewired-gh Mar 27, 2023
6b2c83c
refactor: modify some comment
Chrisqcwx Mar 27, 2023
0d3d633
Merge branch 'dev-yhy' of github.com:Invalid-Syntax-NSCSCC/invalid-cp…
Chrisqcwx Mar 27, 2023
1971768
deal with conflicts
Chrisqcwx Mar 27, 2023
97514d6
Merge branch 'main' of github.com:Invalid-Syntax-NSCSCC/invalid-cpu i…
Chrisqcwx Mar 27, 2023
e6cb6d4
refactor: refactor Mul module with booth algorithm and wallance tree.
Chrisqcwx Mar 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/src/pipeline/execution/ExeStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ExeStage(readNum: Int = Param.instRegReadNum) extends Module {

// TODO: Add `MemStage` in between
// `ExeStage` -> `WbStage` (next clock pulse)
val memLoadStoreInfoPort = Output(new MemLoadStoreInfoNdPort)
val memLoadStoreInfoPort = Output(new MemLoadStoreInfoNdPort)
val gprWritePort = Output(new RfWriteNdPort)
val wbDebugPassthroughPort = new PassThroughPort(new WbDebugNdPort)

Expand Down Expand Up @@ -118,10 +118,11 @@ class ExeStage(readNum: Int = Param.instRegReadNum) extends Module {
}
}

// MemLoadStore
// MemLoadStoreInfo
io.memLoadStoreInfoPort.exeOp := io.exeInstPort.exeOp
// store : the data to write
// preld, dbar, ibar : hint
io.memLoadStoreInfoPort.data := io.exeInstPort.rightOperand
io.memLoadStoreInfoPort.vaddr := (io.exeInstPort.leftOperand + io.exeInstPort.loadStoreImm)

}
114 changes: 91 additions & 23 deletions src/src/pipeline/execution/Mul.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,114 @@ import spec._
import chisel3.internal.firrtl.DefRegInit
import pipeline.execution.bundles.MulDivInstNdPort

// 花费一周期完成
// it takes 2 cycles
class Mul extends Module {

val io = IO(new Bundle {
val mulInst = Flipped(Decoupled(new MulDivInstNdPort))
val mulResult = Decoupled(UInt(doubleWordLength.W))
// val isRunning = (Output(Bool()))
})

val op = WireDefault(io.mulInst.bits.op)
val lop = WireDefault(io.mulInst.bits.leftOperand)
val rop = WireDefault(io.mulInst.bits.rightOperand)

// // 是否为有符号乘法
// val isSigned = WireDefault(VecInit(
// ExeInst.Op.mul,
// ExeInst.Op.mulh
// ).contains(op)
// )
val allSign = VecInit(
ExeInst.Op.mul,
ExeInst.Op.mulh
// 是否为无符号乘法
val isUnsigned = WireDefault(
VecInit(
ExeInst.Op.mulhu
).contains(op)
)

val isSignedWoWire = allSign.contains(op)
val isSigned = WireDefault(isSignedWoWire)
// Booth
val boothWeights = Wire(Vec(16, SInt(4.W)))
boothWeights.zipWithIndex.foreach {
case (weight, index) =>
val shiftNum = 2 * index
val a3 = Wire(UInt(4.W))
a3 := rop(shiftNum + 1).asUInt
val a2 = Wire(UInt(4.W))
a2 := rop(shiftNum).asUInt
val a1 = Wire(UInt(4.W))
if (index != 0) {
a1 := rop(shiftNum - 1).asUInt
} else {
a1 := 0.U
}
weight := ((a1.asSInt + a2.asSInt + -(a3.asSInt << 1)))
if (index == 15) {
when(isUnsigned) {
weight := ((a1.asSInt + a2.asSInt + (a3.asSInt << 1)))
}
}
}

val result = RegInit(0.U(doubleWordLength.W))
val boothResults = Wire(Vec(16, UInt(doubleWordLength.W)))
boothResults.lazyZip(boothWeights).zipWithIndex.foreach {
case ((result, weight), index) =>
val shiftNum = 2 * index
val resultSInt = Wire(SInt(doubleWordLength.W))
resultSInt := ((lop.asSInt * weight) << shiftNum)
when(isUnsigned) {
resultSInt := ((Cat(false.B, lop).asSInt * weight) << shiftNum)
}
result := resultSInt.asUInt
}

val outValid = RegNext(io.mulInst.valid, false.B)
// wallance
def s(a: UInt, b: UInt, c: UInt): UInt = {
a ^ b ^ c
}

result := Mux(
isSigned,
(lop.asSInt * rop.asSInt).asUInt,
lop * rop
)
def c(a: UInt, b: UInt, c: UInt): UInt = {
((a & b) | (a & c) | (b & c)) << 1
}

val wallance1 = Wire(Vec(11, UInt(doubleWordLength.W)))
val wallance2 = Wire(Vec(8, UInt(doubleWordLength.W)))
val wallance3 = Wire(Vec(6, UInt(doubleWordLength.W)))
val wallance4 = Wire(Vec(4, UInt(doubleWordLength.W)))
val wallance5 = Wire(Vec(3, UInt(doubleWordLength.W)))
val wallance6 = Wire(Vec(2, UInt(doubleWordLength.W)))

wallance6(0) := s(wallance5(0), wallance5(1), wallance5(2))
wallance6(1) := c(wallance5(0), wallance5(1), wallance5(2))

wallance5(0) := s(wallance4(0), wallance4(1), wallance4(2))
wallance5(1) := c(wallance4(0), wallance4(1), wallance4(2))
wallance5(2) := wallance4(3)

Seq.range(0, 2).foreach { index =>
wallance4(index * 2) := s(wallance3(index * 3), wallance3(index * 3 + 1), wallance3(index * 3 + 2))
wallance4(index * 2 + 1) := c(wallance3(index * 3), wallance3(index * 3 + 1), wallance3(index * 3 + 2))
}

Seq.range(0, 2).foreach { index =>
wallance3(index * 2) := s(wallance2(index * 3), wallance2(index * 3 + 1), wallance2(index * 3 + 2))
wallance3(index * 2 + 1) := c(wallance2(index * 3), wallance2(index * 3 + 1), wallance2(index * 3 + 2))
}
wallance3(4) := wallance2(6)
wallance3(5) := wallance2(7)

Seq.range(0, 3).foreach { index =>
wallance2(index * 2) := s(wallance1(index * 3), wallance1(index * 3 + 1), wallance1(index * 3 + 2))
wallance2(index * 2 + 1) := c(wallance1(index * 3), wallance1(index * 3 + 1), wallance1(index * 3 + 2))
}
wallance2(6) := wallance1(9)
wallance2(7) := wallance1(10)

Seq.range(0, 5).foreach { index =>
wallance1(index * 2) := s(boothResults(index * 3), boothResults(index * 3 + 1), boothResults(index * 3 + 2))
wallance1(index * 2 + 1) := c(boothResults(index * 3), boothResults(index * 3 + 1), boothResults(index * 3 + 2))
}
wallance1(10) := boothResults(15)

val resultReg = RegInit(0.U(doubleWordLength.W))
resultReg := (wallance6(0) + wallance6(1))
io.mulResult.bits := resultReg

val outValid = RegNext(io.mulInst.valid, false.B)

io.mulInst.ready := ~outValid
io.mulResult.valid := outValid
io.mulResult.bits := result
// io.isRunning := io.mulInst.valid

}
2 changes: 1 addition & 1 deletion src/src/pipeline/mem/MemStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MemStage extends Module {
val stallRequest = Output(Bool())
// `MemStage` -> ?Ram
val memLoadStorePort = Flipped(new MemLoadStorePort)

val wbDebugPassthroughPort = new PassThroughPort(new WbDebugNdPort)
})

Expand Down
62 changes: 31 additions & 31 deletions src/test/src/SimpleCpuSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,34 @@ import frontend.InstQueue
import pipeline.dispatch.bundles.InstInfoBundle
import utest._

object SimpleCpuSpec extends ChiselUtestTester {
val tests = Tests {
test("Test instructions") {
testCircuit(new CoreCpuTop, Seq(WriteVcdAnnotation)) { cpu =>
val instSeq = Seq(
"0000001010_000000000011_00000_00001", // addi $1, $0, 3
"0000001010_000000110011_00000_00100", // addi $4, $0, 51
"0000001010_000000000010_00001_00010", // addi $2, $1, 2
// "0000001010_000000000010_00001_00010", // addi $2, $1, 2
// "00000000001000000_00001_00100_00110", // div $6, $4, $1
"00000000000100100_00010_00001_00011", // slt $3, $1, $2
// "00000000000111000_00001_00100_00101", // mul $5, $4, $1
// "00000000001000000_00001_00100_00110", // div $6, $4, $1
"00000000000111000_00001_00100_00101", // mul $5, $4, $1
"00000000001000000_00001_00100_00110", // div $6, $4, $1
"00000000001000001_00001_00100_00111", // mod $7, $4, $1
)
cpu.io.intrpt.poke(0.U)
cpu.io.axi.arready.poke(true.B)
cpu.io.axi.rvalid.poke(true.B)
instSeq.foreach { inst =>
cpu.io.axi.rdata.poke(("b" + inst).U)
cpu.clock.step(5)
}
cpu.clock.step(15)
cpu.io.axi.rvalid.poke(false.B)
cpu.clock.step(15)
}
}
}
}
// object SimpleCpuSpec extends ChiselUtestTester {
// val tests = Tests {
// test("Test instructions") {
// testCircuit(new CoreCpuTop, Seq(WriteVcdAnnotation)) { cpu =>
// val instSeq = Seq(
// "0000001010_000000000011_00000_00001", // addi $1, $0, 3
// "0000001010_000000110011_00000_00100", // addi $4, $0, 51
// "0000001010_000000000010_00001_00010", // addi $2, $1, 2
// // "0000001010_000000000010_00001_00010", // addi $2, $1, 2
// // "00000000001000000_00001_00100_00110", // div $6, $4, $1
// "00000000000100100_00010_00001_00011", // slt $3, $1, $2
// // "00000000000111000_00001_00100_00101", // mul $5, $4, $1
// // "00000000001000000_00001_00100_00110", // div $6, $4, $1
// "00000000000111000_00001_00100_00101", // mul $5, $4, $1
// "00000000001000000_00001_00100_00110", // div $6, $4, $1
// "00000000001000001_00001_00100_00111", // mod $7, $4, $1
// )
// cpu.io.intrpt.poke(0.U)
// cpu.io.axi.arready.poke(true.B)
// cpu.io.axi.rvalid.poke(true.B)
// instSeq.foreach { inst =>
// cpu.io.axi.rdata.poke(("b" + inst).U)
// cpu.clock.step(5)
// }
// cpu.clock.step(15)
// cpu.io.axi.rvalid.poke(false.B)
// cpu.clock.step(15)
// }
// }
// }
// }
88 changes: 44 additions & 44 deletions src/test/src/testExeStage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,51 +13,51 @@ import pipeline.execution.ExeStage
import spec.ExeInst
import pipeline.dispatch.bundles.ExeInstNdPort

object ExeStageSpec extends ChiselUtestTester {
val tests = Tests {
test("Test exe stage module") {
testCircuit(new ExeStage, Seq(WriteVcdAnnotation)) { exeStage =>
val ops = Seq(
ExeInst.Op.add,
ExeInst.Op.slt,
ExeInst.Op.mul,
ExeInst.Op.div,
ExeInst.Op.sub,
ExeInst.Op.mod,
ExeInst.Op.add,
ExeInst.Op.nop
)
val sel = ExeInst.Sel.arithmetic
val lop = 472;
val rop = 5;
exeStage.io.exeInstPort.poke(ExeInstNdPort.default)
exeStage.io.pipelineControlPort.poke(PipelineControlNDPort.default)
def instPort = exeStage.io.exeInstPort
// object ExeStageSpec extends ChiselUtestTester {
// val tests = Tests {
// test("Test exe stage module") {
// testCircuit(new ExeStage, Seq(WriteVcdAnnotation)) { exeStage =>
// val ops = Seq(
// ExeInst.Op.add,
// ExeInst.Op.slt,
// ExeInst.Op.mul,
// ExeInst.Op.div,
// ExeInst.Op.sub,
// ExeInst.Op.mod,
// ExeInst.Op.add,
// ExeInst.Op.nop
// )
// val sel = ExeInst.Sel.arithmetic
// val lop = 472;
// val rop = 5;
// exeStage.io.exeInstPort.poke(ExeInstNdPort.default)
// exeStage.io.pipelineControlPort.poke(PipelineControlNDPort.default)
// def instPort = exeStage.io.exeInstPort

instPort.gprWritePort.en.poke(true.B)
instPort.gprWritePort.addr.poke(7.U)
for (i <- 0 until ops.length) {
instPort.exeOp.poke(ops(i))
instPort.exeSel.poke(sel)
instPort.leftOperand.poke(lop.U)
instPort.rightOperand.poke(rop.U)
// instPort.gprWritePort.en.poke(true.B)
// instPort.gprWritePort.addr.poke(7.U)
// for (i <- 0 until ops.length) {
// instPort.exeOp.poke(ops(i))
// instPort.exeSel.poke(sel)
// instPort.leftOperand.poke(lop.U)
// instPort.rightOperand.poke(rop.U)

println(exeStage.io.stallRequest.peek().litValue)
while (exeStage.io.stallRequest.peek().litValue == 1) {
print("*")
exeStage.clock.step(1)
instPort.exeOp.poke(0.U)
instPort.exeSel.poke(0.U)
instPort.leftOperand.poke(0.U)
instPort.rightOperand.poke(0.U)
// println(exeStage.io.stallRequest.peek().litValue)
// while (exeStage.io.stallRequest.peek().litValue == 1) {
// print("*")
// exeStage.clock.step(1)
// instPort.exeOp.poke(0.U)
// instPort.exeSel.poke(0.U)
// instPort.leftOperand.poke(0.U)
// instPort.rightOperand.poke(0.U)

}
// }

exeStage.clock.step(1)
println()
}
exeStage.clock.step(10)
}
}
}
}
// exeStage.clock.step(1)
// println()
// }
// exeStage.clock.step(10)
// }
// }
// }
// }
Loading