Compare commits
20 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c8144787b0 | 4 months ago |
|
|
82fe15aa3e | 8 months ago |
|
|
6b950d2ea0 | 8 months ago |
|
|
a60237e7fd | 8 months ago |
|
|
6293d1cd89 | 8 months ago |
|
|
2f2f9e9b54 | 9 months ago |
|
|
6e3f2de95f | 9 months ago |
|
|
ee417a132c | 10 months ago |
|
|
98c42ca11b | 10 months ago |
|
|
abb03ef3c3 | 10 months ago |
|
|
80b1cd00f2 | 10 months ago |
|
|
b0832deab0 | 10 months ago |
|
|
43209019e7 | 10 months ago |
|
|
67a04e71d4 | 10 months ago |
|
|
8e6db9f912 | 10 months ago |
|
|
5c2305b0ed | 10 months ago |
|
|
c8b3c4a4a4 | 10 months ago |
|
|
6e65185521 | 10 months ago |
|
|
1a9fcc12b6 | 10 months ago |
|
|
c38ce0b538 | 11 months ago |
@ -1,3 +1,4 @@
|
||||
.vscode/
|
||||
.metals/
|
||||
.VSCodeCounter/
|
||||
.DS_Store
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
module top(
|
||||
input clock,
|
||||
input reset,
|
||||
// Interrupts
|
||||
input mei, // to PLIC
|
||||
input msi, // to CLINT
|
||||
input mti, // to CLINT
|
||||
input sei, // to PLIC
|
||||
// inst sram interface
|
||||
output inst_sram_en,
|
||||
output [ 3:0] inst_sram_wen,
|
||||
output [31:0] inst_sram_addr,
|
||||
output [31:0] inst_sram_wdata,
|
||||
input [31:0] inst_sram_rdata,
|
||||
// data sram interface
|
||||
output data_sram_en,
|
||||
output [ 7:0] data_sram_wen,
|
||||
output [31:0] data_sram_addr,
|
||||
output [63:0] data_sram_wdata,
|
||||
input [63:0] data_sram_rdata,
|
||||
// trace debug interface
|
||||
output debug_commit,
|
||||
output [63:0] debug_pc,
|
||||
output [4:0 ] debug_rf_wnum,
|
||||
output [63:0] debug_rf_wdata
|
||||
);
|
||||
|
||||
PuaCpu core(
|
||||
.clock (clock),
|
||||
.reset (reset),
|
||||
// interrupts
|
||||
.io_ext_int_mei (mei),
|
||||
.io_ext_int_mti (mti),
|
||||
.io_ext_int_msi (msi),
|
||||
// inst sram interface
|
||||
.io_inst_sram_en (inst_sram_en),
|
||||
.io_inst_sram_wen (inst_sram_wen),
|
||||
.io_inst_sram_addr (inst_sram_addr),
|
||||
.io_inst_sram_wdata (inst_sram_wdata),
|
||||
.io_inst_sram_rdata (inst_sram_rdata),
|
||||
// data sram interface
|
||||
.io_data_sram_en (data_sram_en),
|
||||
.io_data_sram_wen (data_sram_wen),
|
||||
.io_data_sram_addr (data_sram_addr),
|
||||
.io_data_sram_wdata (data_sram_wdata),
|
||||
.io_data_sram_rdata (data_sram_rdata),
|
||||
// debug
|
||||
.io_debug_pc (debug_pc),
|
||||
.io_debug_commit (debug_commit),
|
||||
.io_debug_rf_wnum (debug_rf_wnum),
|
||||
.io_debug_rf_wdata (debug_rf_wdata)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@ -1,68 +0,0 @@
|
||||
package gcd
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.Decoupled
|
||||
|
||||
class GcdInputBundle(val w: Int) extends Bundle {
|
||||
val value1 = UInt(w.W)
|
||||
val value2 = UInt(w.W)
|
||||
}
|
||||
|
||||
class GcdOutputBundle(val w: Int) extends Bundle {
|
||||
val value1 = UInt(w.W)
|
||||
val value2 = UInt(w.W)
|
||||
val gcd = UInt(w.W)
|
||||
}
|
||||
|
||||
/** Compute Gcd using subtraction method. Subtracts the smaller from the larger until register y is zero. value input
|
||||
* register x is then the Gcd. Unless first input is zero then the Gcd is y. Can handle stalls on the producer or
|
||||
* consumer side
|
||||
*/
|
||||
class DecoupledGcd(width: Int) extends Module {
|
||||
val input = IO(Flipped(Decoupled(new GcdInputBundle(width))))
|
||||
val output = IO(Decoupled(new GcdOutputBundle(width)))
|
||||
|
||||
val xInitial = Reg(UInt())
|
||||
val yInitial = Reg(UInt())
|
||||
val x = Reg(UInt())
|
||||
val y = Reg(UInt())
|
||||
val busy = RegInit(false.B)
|
||||
val resultValid = RegInit(false.B)
|
||||
|
||||
input.ready := !busy
|
||||
output.valid := resultValid
|
||||
output.bits := DontCare
|
||||
|
||||
when(busy) {
|
||||
when(x > y) {
|
||||
x := x - y
|
||||
}.otherwise {
|
||||
y := y - x
|
||||
}
|
||||
when(x === 0.U || y === 0.U) {
|
||||
when(x === 0.U) {
|
||||
output.bits.gcd := y
|
||||
}.otherwise {
|
||||
output.bits.gcd := x
|
||||
}
|
||||
|
||||
output.bits.value1 := xInitial
|
||||
output.bits.value2 := yInitial
|
||||
resultValid := true.B
|
||||
|
||||
when(output.ready && resultValid) {
|
||||
busy := false.B
|
||||
resultValid := false.B
|
||||
}
|
||||
}
|
||||
}.otherwise {
|
||||
when(input.valid) {
|
||||
val bundle = input.deq()
|
||||
x := bundle.value1
|
||||
y := bundle.value2
|
||||
xInitial := bundle.value1
|
||||
yInitial := bundle.value2
|
||||
busy := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,9 @@
|
||||
import cpu._
|
||||
import circt.stage._
|
||||
|
||||
object Elaborate extends App {
|
||||
val firtoolOptions = Array(
|
||||
"--lowering-options=" + List(
|
||||
// make yosys happy
|
||||
// see https://github.com/llvm/circt/blob/main/docs/VerilogGeneration.md
|
||||
"disallowLocalVariables",
|
||||
"disallowPackedArrays",
|
||||
"locationInfoStyle=wrapInAtSquareBracket"
|
||||
).reduce(_ + "," + _)
|
||||
)
|
||||
circt.stage.ChiselStage.emitSystemVerilogFile(new gcd.GCD(), args, firtoolOptions)
|
||||
}
|
||||
implicit val cpuConfig = new CpuConfig()
|
||||
def top = new PuaCpu()
|
||||
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
(new ChiselStage).execute(args, generator :+ CIRCTTargetAnnotation(CIRCTTarget.Verilog))
|
||||
}
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
package gcd
|
||||
|
||||
import chisel3._
|
||||
|
||||
/** Compute GCD using subtraction method. Subtracts the smaller from the larger until register y is zero. value in
|
||||
* register x is then the GCD
|
||||
*/
|
||||
class GCD extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val value1 = Input(UInt(16.W))
|
||||
val value2 = Input(UInt(16.W))
|
||||
val loadingValues = Input(Bool())
|
||||
val outputGCD = Output(UInt(16.W))
|
||||
val outputValid = Output(Bool())
|
||||
})
|
||||
|
||||
val x = Reg(UInt())
|
||||
val y = Reg(UInt())
|
||||
|
||||
when(x > y) { x := x - y }.otherwise { y := y - x }
|
||||
|
||||
when(io.loadingValues) {
|
||||
x := io.value1
|
||||
y := io.value2
|
||||
}
|
||||
|
||||
io.outputGCD := x
|
||||
io.outputValid := y === 0.U
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu._
|
||||
import cpu.defines._
|
||||
|
||||
class PuaCpu extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ext_int = Input(new ExtInterrupt())
|
||||
val inst_sram = new InstSram()
|
||||
val data_sram = new DataSram()
|
||||
val debug = new DEBUG()
|
||||
})
|
||||
|
||||
val core = Module(new Core())
|
||||
|
||||
io.ext_int <> core.io.interrupt
|
||||
io.inst_sram <> core.io.instSram
|
||||
io.data_sram <> core.io.dataSram
|
||||
io.debug <> core.io.debug
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package cpu.defines
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.CpuConfig
|
||||
|
||||
trait CoreParameter {
|
||||
def cpuConfig = new CpuConfig
|
||||
val XLEN = if (cpuConfig.isRV32) 32 else 64
|
||||
val VADDR_WID = if (cpuConfig.isRV32) 32 else 39
|
||||
val PADDR_WID = 32
|
||||
}
|
||||
|
||||
trait Constants extends CoreParameter {
|
||||
// 全局
|
||||
val PC_INIT = "h80000000".U(XLEN.W)
|
||||
|
||||
val INT_WID = 12
|
||||
val EXC_WID = 16
|
||||
|
||||
// inst rom
|
||||
val INST_WID = 32
|
||||
|
||||
// GPR RegFile
|
||||
val AREG_NUM = 32
|
||||
val REG_ADDR_WID = 5
|
||||
}
|
||||
|
||||
trait SRAMConst extends Constants {
|
||||
val SRAM_ADDR_WID = PADDR_WID // 32
|
||||
val DATA_SRAM_DATA_WID = XLEN
|
||||
val DATA_SRAM_WEN_WID = XLEN / 8
|
||||
val INST_SRAM_DATA_WID = INST_WID
|
||||
val INST_SRAM_WEN_WID = INST_WID / 8
|
||||
}
|
||||
object Const extends Constants with SRAMConst
|
||||
|
||||
object Instructions extends HasInstrType with CoreParameter {
|
||||
def NOP = 0x00000013.U
|
||||
val DecodeDefault = List(InstrN, FuType.alu, ALUOpType.add)
|
||||
def DecodeTable = RVIInstr.table
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package cpu.defines
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
object SignedExtend {
|
||||
def apply(a: UInt, len: Int) = {
|
||||
val aLen = a.getWidth
|
||||
val signBit = a(aLen - 1)
|
||||
if (aLen >= len) a(len - 1, 0) else Cat(Fill(len - aLen, signBit), a)
|
||||
}
|
||||
}
|
||||
|
||||
object ZeroExtend {
|
||||
def apply(a: UInt, len: Int) = {
|
||||
val aLen = a.getWidth
|
||||
if (aLen >= len) a(len - 1, 0) else Cat(0.U((len - aLen).W), a)
|
||||
}
|
||||
}
|
||||
|
||||
object LookupTree {
|
||||
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 =
|
||||
MuxLookup(key, default)(mapping.toSeq)
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cpu.defines
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
// 指令类型
|
||||
trait HasInstrType {
|
||||
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
|
||||
|
||||
// I、R、U、J类型的指令都需要写寄存器
|
||||
def isRegWen(instrType: UInt): Bool = instrType(2)
|
||||
}
|
||||
|
||||
// 功能单元类型 Function Unit Type
|
||||
object FuType {
|
||||
def num = 1
|
||||
def alu = 0.U // arithmetic logic unit
|
||||
def apply() = UInt(log2Up(num).W)
|
||||
}
|
||||
|
||||
// 功能单元操作类型 Function Unit Operation Type
|
||||
object FuOpType {
|
||||
def apply() = UInt(5.W) // 宽度与最大的功能单元操作类型宽度一致
|
||||
}
|
||||
|
||||
// 算术逻辑单元操作类型 Arithmetic Logic Unit Operation Type
|
||||
object ALUOpType {
|
||||
def add = "b00000".U
|
||||
// TODO: 定义更多的ALU操作类型
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class IfIdData extends Bundle {
|
||||
val inst = UInt(XLEN.W)
|
||||
val valid = Bool()
|
||||
val pc = UInt(XLEN.W)
|
||||
}
|
||||
|
||||
class FetchUnitDecodeUnit extends Bundle {
|
||||
val data = Output(new IfIdData())
|
||||
}
|
||||
|
||||
class DecodeStage extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val fetchUnit = Flipped(new FetchUnitDecodeUnit())
|
||||
val decodeUnit = new FetchUnitDecodeUnit()
|
||||
})
|
||||
|
||||
val data = RegInit(0.U.asTypeOf(new IfIdData()))
|
||||
|
||||
data := io.fetchUnit.data
|
||||
|
||||
io.decodeUnit.data := data
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
|
||||
class DecodeUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
// 输入
|
||||
val decodeStage = Flipped(new FetchUnitDecodeUnit())
|
||||
val regfile = new Src12Read()
|
||||
// 输出
|
||||
val executeStage = Output(new DecodeUnitExecuteUnit())
|
||||
})
|
||||
|
||||
// 译码阶段完成指令的译码操作以及源操作数的准备
|
||||
|
||||
val decoder = Module(new Decoder()).io
|
||||
decoder.in.inst := io.decodeStage.data.inst
|
||||
|
||||
val pc = io.decodeStage.data.pc
|
||||
val info = Wire(new Info())
|
||||
|
||||
info := decoder.out.info
|
||||
info.valid := io.decodeStage.data.valid
|
||||
|
||||
// TODO:完成寄存器堆的读取
|
||||
// io.regfile.src1.raddr :=
|
||||
// io.regfile.src2.raddr :=
|
||||
|
||||
// TODO: 完成DecodeUnit模块的逻辑
|
||||
// io.executeStage.data.pc :=
|
||||
// io.executeStage.data.info :=
|
||||
// io.executeStage.data.src_info.src1_data :=
|
||||
// io.executeStage.data.src_info.src2_data :=
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class IdExeData extends Bundle {
|
||||
val pc = UInt(XLEN.W)
|
||||
val info = new Info()
|
||||
val src_info = new SrcInfo()
|
||||
}
|
||||
|
||||
class DecodeUnitExecuteUnit extends Bundle {
|
||||
val data = new IdExeData()
|
||||
}
|
||||
|
||||
class ExecuteStage extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val decodeUnit = Input(new DecodeUnitExecuteUnit())
|
||||
val executeUnit = Output(new DecodeUnitExecuteUnit())
|
||||
})
|
||||
|
||||
val data = RegInit(0.U.asTypeOf(new IdExeData()))
|
||||
|
||||
// TODO: 完成ExecuteStage模块的逻辑
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.CpuConfig
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
|
||||
class ExecuteUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val executeStage = Input(new DecodeUnitExecuteUnit())
|
||||
val memoryStage = Output(new ExecuteUnitMemoryUnit())
|
||||
val dataSram = new DataSram()
|
||||
})
|
||||
|
||||
// 执行阶段完成指令的执行操作
|
||||
|
||||
val fu = Module(new Fu()).io
|
||||
fu.data.pc := io.executeStage.data.pc
|
||||
fu.data.info := io.executeStage.data.info
|
||||
fu.data.src_info := io.executeStage.data.src_info
|
||||
|
||||
io.dataSram <> fu.dataSram
|
||||
|
||||
// TODO: 完成ExecuteUnit模块的逻辑
|
||||
// io.memoryStage.data.pc :=
|
||||
// io.memoryStage.data.info :=
|
||||
// io.memoryStage.data.src_info :=
|
||||
// io.memoryStage.data.rd_info :=
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
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 dataSram = new DataSram()
|
||||
})
|
||||
|
||||
val alu = Module(new Alu()).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
|
||||
|
||||
io.data.rd_info.wdata := alu.result
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
|
||||
class Alu extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val result = Output(UInt(XLEN.W))
|
||||
})
|
||||
// TODO: 完成ALU模块的逻辑
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import cpu.defines._
|
||||
|
||||
class FetchUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val decodeStage = new FetchUnitDecodeUnit()
|
||||
val instSram = new InstSram()
|
||||
})
|
||||
|
||||
val boot :: send :: receive :: Nil = Enum(3)
|
||||
val state = RegInit(boot)
|
||||
|
||||
switch(state) {
|
||||
is(boot) {
|
||||
state := send
|
||||
}
|
||||
is(send) {
|
||||
state := receive
|
||||
}
|
||||
is(receive) {}
|
||||
}
|
||||
|
||||
// 取指阶段完成指令的取指操作
|
||||
|
||||
val pc = RegEnable(io.instSram.addr, (PC_INIT - 4.U), state =/= boot)
|
||||
|
||||
io.instSram.addr := pc + 4.U
|
||||
|
||||
io.decodeStage.data.valid := state === receive
|
||||
io.decodeStage.data.pc := pc
|
||||
io.decodeStage.data.inst := io.instSram.rdata
|
||||
|
||||
io.instSram.en := !reset.asBool
|
||||
io.instSram.wen := 0.U
|
||||
io.instSram.wdata := 0.U
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class ExeMemData extends Bundle {
|
||||
val pc = UInt(XLEN.W)
|
||||
val info = new Info()
|
||||
val rd_info = new RdInfo()
|
||||
val src_info = new SrcInfo()
|
||||
}
|
||||
|
||||
class ExecuteUnitMemoryUnit extends Bundle {
|
||||
val data = new ExeMemData()
|
||||
}
|
||||
|
||||
class MemoryStage extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val executeUnit = Input(new ExecuteUnitMemoryUnit())
|
||||
val memoryUnit = Output(new ExecuteUnitMemoryUnit())
|
||||
})
|
||||
|
||||
val data = RegInit(0.U.asTypeOf(new ExeMemData()))
|
||||
|
||||
// TODO: 完成MemoryStage模块的逻辑
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class MemoryUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val memoryStage = Input(new ExecuteUnitMemoryUnit())
|
||||
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
||||
})
|
||||
|
||||
// 访存阶段完成指令的访存操作
|
||||
|
||||
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
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class MemWbData extends Bundle {
|
||||
val pc = UInt(XLEN.W)
|
||||
val info = new Info()
|
||||
val rd_info = new RdInfo()
|
||||
}
|
||||
|
||||
class MemoryUnitWriteBackUnit extends Bundle {
|
||||
val data = new MemWbData()
|
||||
}
|
||||
class WriteBackStage extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val memoryUnit = Input(new MemoryUnitWriteBackUnit())
|
||||
val writeBackUnit = Output(new MemoryUnitWriteBackUnit())
|
||||
})
|
||||
|
||||
val data = RegInit(0.U.asTypeOf(new MemWbData()))
|
||||
|
||||
// TODO: 完成WriteBackStage模块的逻辑
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class WriteBackUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val writeBackStage = Input(new MemoryUnitWriteBackUnit())
|
||||
val regfile = Output(new RegWrite())
|
||||
val debug = new DEBUG()
|
||||
})
|
||||
|
||||
// 写回阶段完成数据的写回操作
|
||||
// 同时该阶段还负责差分测试的比对工作
|
||||
// TODO: 完成WriteBackUnit模块的逻辑
|
||||
}
|
||||
@ -1,68 +1,9 @@
|
||||
// See README.md for license details.
|
||||
|
||||
package gcd
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.BundleLiterals._
|
||||
import chisel3.simulator.EphemeralSimulator._
|
||||
import org.scalatest.freespec.AnyFreeSpec
|
||||
import org.scalatest.matchers.must.Matchers
|
||||
|
||||
/** This is a trivial example of how to run this Specification From within sbt use:
|
||||
* {{{
|
||||
* testOnly gcd.GCDSpec
|
||||
* }}}
|
||||
* From a terminal shell use:
|
||||
* {{{
|
||||
* sbt 'testOnly gcd.GCDSpec'
|
||||
* }}}
|
||||
* Testing from mill:
|
||||
* {{{
|
||||
* mill %NAME%.test.testOnly gcd.GCDSpec
|
||||
* }}}
|
||||
*/
|
||||
class GCDSpec extends AnyFreeSpec with Matchers {
|
||||
"Gcd should calculate proper greatest common denominator" in {
|
||||
simulate(new DecoupledGcd(16)) { dut =>
|
||||
val testValues = for {
|
||||
x <- 0 to 10
|
||||
y <- 0 to 10
|
||||
} yield (x, y)
|
||||
val inputSeq = testValues.map { case (x, y) => (new GcdInputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U) }
|
||||
val resultSeq = testValues.map { case (x, y) =>
|
||||
(new GcdOutputBundle(16)).Lit(_.value1 -> x.U, _.value2 -> y.U, _.gcd -> BigInt(x).gcd(BigInt(y)).U)
|
||||
}
|
||||
|
||||
dut.reset.poke(true.B)
|
||||
dut.clock.step()
|
||||
dut.reset.poke(false.B)
|
||||
dut.clock.step()
|
||||
|
||||
var sent, received, cycles: Int = 0
|
||||
while (sent != 100 && received != 100) {
|
||||
assert(cycles <= 1000, "timeout reached")
|
||||
|
||||
if (sent < 100) {
|
||||
dut.input.valid.poke(true.B)
|
||||
dut.input.bits.value1.poke(testValues(sent)._1.U)
|
||||
dut.input.bits.value2.poke(testValues(sent)._2.U)
|
||||
if (dut.input.ready.peek().litToBoolean) {
|
||||
sent += 1
|
||||
}
|
||||
}
|
||||
|
||||
if (received < 100) {
|
||||
dut.output.ready.poke(true.B)
|
||||
if (dut.output.valid.peekValue().asBigInt == 1) {
|
||||
dut.output.bits.gcd.expect(BigInt(testValues(received)._1).gcd(testValues(received)._2))
|
||||
received += 1
|
||||
}
|
||||
}
|
||||
|
||||
// Step the simulation forward.
|
||||
dut.clock.step()
|
||||
cycles += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// import cpu._
|
||||
// import circt.stage._
|
||||
|
||||
// object TestMain extends App {
|
||||
// implicit val cpuConfig = new CpuConfig()
|
||||
// def top = new Top()
|
||||
// val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
// (new ChiselStage).execute(args, generator :+ CIRCTTargetAnnotation(CIRCTTarget.Verilog))
|
||||
// }
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
*.vcd
|
||||
obj_dir
|
||||
|
||||
core/*
|
||||
!core/top_sram_wrapper.v
|
||||
|
||||
trace.*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue