【问题标题】:Simulating a CPU design written in Chisel模拟用 Chisel 编写的 CPU 设计
【发布时间】:2019-08-30 10:26:20
【问题描述】:

我在 Chisel3 中编写了一个单周期 CPU,它实现了大部分 RV32I 指令(CSR、Fence、ECALL/BREAK、LB/SB 除外,这些指令可能稍后会包含在内)。指令当前被硬编码在指令存储器中,但我将更改它,以便它从文件中读取指令。我遇到了如何实际模拟我的设计的麻烦。这是我将所有组件“粘合”在一起的代码。

class Core extends Module {
  val io = IO(new Bundle {
    val dc = Input(Bool())
})
io := DontCare

val pc          = RegInit(0.U)
val pcSelect    = Module(new PcSelect())
val pcPlusFour  = Module(new Adder())
val alu         = Module(new ALU())
val aluControl  = Module(new AluControl())
val control     = Module(new Control())
val immGen      = Module(new ImmGen())
val branchLogic = Module(new BranchLogic())
val branchUnit  = Module(new Adder())
val jumpReg     = Module(new JumpReg())
val regFile     = Module(new RegFile())
val jumpAdder   = Module(new Adder())
val dataMem     = Module(new DataMemory())
val instrMem    = Module(new InstructionMemory())

// Mux from data memory
val dataMux    = Mux(control.io.memToReg, dataMem.io.readDataOutput, alu.io.result)

// Mux to register file
val regFileMux = Mux(control.io.writeSrc, pcPlusFour.io.result, dataMux)

// PC + 4
pcPlusFour.io.in1 := pc
pcPlusFour.io.in2 := 4.U 

// Instruction memory
instrMem.io.address := pc
val instruction = instrMem.io.instruction
val opcode      = instruction(6, 0)

// Control
control.io.opcode := opcode

// Register file
regFile.io.readReg1  := instruction(19, 15) // rs1
regFile.io.readReg2  := instruction(24, 20) // rs2
regFile.io.writeReg  := instruction(11, 7)  // rd
regFile.io.regWrite  := control.io.regWrite
regFile.io.writeData := regFileMux

// ALU
val aluMux1 = Mux(control.io.aluSrc1, immGen.io.extendedU, regFile.io.readData1)
alu.io.in1 := aluMux1
val src = control.io.aluSrc2
val aluMux2 = Mux(src === 1.U, immGen.io.extendedI, Mux(src === 2.U, immGen.io.extendedS, Mux(src === 3.U, pc, regFile.io.readData2)))
alu.io.in2 := aluMux2
alu.io.aluOp := aluControl.io.output

// ALU control
aluControl.io.aluOp  := control.io.aluOp
aluControl.io.funct7 := instruction(31, 25)
aluControl.io.funct3 := instruction(14, 12) 

// Data Memory
dataMem.io.readAddress := alu.io.result
dataMem.io.writeData   := regFile.io.readData2
dataMem.io.memWrite    := control.io.memWrite
dataMem.io.memRead     := control.io.memRead

// Immediate generator
immGen.io.instr := instruction

// Branch logic
branchLogic.io.reg1 := regFile.io.readData1
branchLogic.io.reg2 := regFile.io.readData2
branchLogic.io.branch := control.io.branch
branchLogic.io.funct3 := instruction(14, 12)

// Jump reg
jumpReg.io.reg1 := regFile.io.readData1
jumpReg.io.imm  := immGen.io.extendedI

// Jump
jumpAdder.io.in1 := pc
jumpAdder.io.in2 := immGen.io.extendedJ

// Branch
branchUnit.io.in1 := pc
branchUnit.io.in2 := immGen.io.extendedB

// PC-select
pcSelect.io.pcPlus4      := pcPlusFour.io.result
pcSelect.io.branch       := branchUnit.io.result
pcSelect.io.jump         := jumpAdder.io.result
pcSelect.io.jalr         := jumpReg.io.output
pcSelect.io.branchSignal := branchLogic.io.result
pcSelect.io.jumpSignal   := control.io.jump
pcSelect.io.jalrSignal   := control.io.jumpReg 

pc := pcSelect.io.output
}

所以我的问题是:

  1. 如何模拟此设计以查看它是否正确执行所有指令?
  2. 我想在它上面运行基准“dhrystone”来衡量性能。我该怎么做(有可能吗?)?如果需要,我不确定如何处理系统调用。

提前致谢!

【问题讨论】:

    标签: simulation hdl riscv chisel


    【解决方案1】:

    好问题:有很多方法可以解决这个问题。

    一种常见的方法是从 Chisel 获取生成的 Verilog,并编写您自己的测试工具来实例化您的设计。此测试工具可以用 C++、Verilog、SystemVerilog 或您喜欢的其他测试工具/胶水语言编写。

    这种方法被 Sodor (https://github.com/ucb-bar/riscv-sodor) 和 Rocket-Chip (https://github.com/freechipsproject/rocket-chip) 使用,最外层的测试工具代码是用 C++ 编写的,但能够与 Verilog 模拟器(如 Verilator 和 VCS)交互。 C++ 测试逻辑允许用户通过命令行传入测试二进制文件,然后通过某种“魔法”将二进制文件加载到测试内存中。这种魔法可能是一个外部调试接口、一个 Tether 串行接口,或者它可能是一个提供的外部 RAM 模型,可以由测试工具加载(可以是您自己编写的简单的东西,也可以是像 dramsim2 这样复杂的东西)。

    这东西相当复杂,所以我建议从简单开始;一种选择是在 Chisel 中创建一个黑盒内存,该内存由一个简单的内存支持,该内存使用 readmemh 进行自我初始化。这里的好功能是您无需重新编译代码即可运行新的二进制文件,只需将要加载到测试内存中的文件换出即可。

    Chisel 还提供了自己的独立测试器,因此也许您可以完全在 Scala 中完成测试工具,但我还没有看到像核心这样复杂的东西这样做过,它非常依赖外部刺激和需求与外界交流。

    【讨论】:

      【解决方案2】:

      凿子设计Risc-V cpu

      https://fatalfeel.blogspot.com/2013/12/chisel-design-ic-for-risc-v.html

      使用rocket-chip作为cpu核心,可以在~/XiangShan/rocket-chip那里找到

      模拟器运行c++编译器,你可以使用Vivado运行模拟器

      也可以在intellij IDE中调试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-22
        • 2014-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多