forked from ppg69fuwb/riscv-lab
Compare commits
11 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
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 |
@ -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
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue