mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
[not tested] lab2 codes updated:
- added environment instruction tests - removed useless classes in CLINT.scala - rename and comments
This commit is contained in:
@@ -18,7 +18,7 @@ import chisel3._
|
||||
import chisel3.util.MuxLookup
|
||||
import riscv.Parameters
|
||||
|
||||
object InterruptStatus {
|
||||
object InterruptCode {
|
||||
val None = 0x0.U(8.W)
|
||||
val Timer0 = 0x1.U(8.W)
|
||||
val Ret = 0xFF.U(8.W)
|
||||
@@ -28,18 +28,6 @@ object InterruptEntry {
|
||||
val Timer0 = 0x4.U(8.W)
|
||||
}
|
||||
|
||||
object InterruptState {
|
||||
val Idle = 0x0.U
|
||||
val SyncAssert = 0x1.U
|
||||
val AsyncAssert = 0x2.U
|
||||
val MRET = 0x3.U
|
||||
}
|
||||
|
||||
object CSRState {
|
||||
val Idle = 0x0.U
|
||||
val Traping = 0x1.U
|
||||
val Mret = 0x2.U
|
||||
}
|
||||
|
||||
class CSRDirectAccessBundle extends Bundle {
|
||||
val mstatus = Input(UInt(Parameters.DataWidth))
|
||||
@@ -88,20 +76,14 @@ class CLINT extends Module {
|
||||
io.csr_bundle.direct_write_enable :=
|
||||
io.interrupt_assert :=
|
||||
io.interrupt_handler_address :=
|
||||
}.elsewhen(io.instruction === InstructionsRet.mret) {
|
||||
io.csr_bundle.mstatus_write_data :=
|
||||
io.csr_bundle.mepc_write_data :=
|
||||
io.csr_bundle.mcause_write_data :=
|
||||
io.csr_bundle.direct_write_enable :=
|
||||
io.interrupt_assert :=
|
||||
io.interrupt_handler_address :=
|
||||
}
|
||||
.elsewhen(io.instruction === InstructionsEnv.ebreak || io.instruction === InstructionsEnv.ecall) {
|
||||
......
|
||||
}
|
||||
.elsewhen(io.instruction === InstructionsRet.mret) {
|
||||
......
|
||||
}.otherwise {
|
||||
io.csr_bundle.mstatus_write_data :=
|
||||
io.csr_bundle.mepc_write_data :=
|
||||
io.csr_bundle.mcause_write_data :=
|
||||
io.csr_bundle.direct_write_enable :=
|
||||
io.interrupt_assert :=
|
||||
io.interrupt_handler_address :=
|
||||
......
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ import chisel3._
|
||||
import chiseltest._
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import riscv.{Parameters, TestAnnotations}
|
||||
import riscv.core.{ALUOp1Source, ALUOp2Source, CLINT, CSR, CSRRegister, InstructionDecode, InstructionsNop, InstructionsRet}
|
||||
import riscv.core.{ALUOp1Source, ALUOp2Source, CLINT, CSR, CSRRegister, InstructionDecode, InstructionsNop, InstructionsRet, InstructionsEnv}
|
||||
import riscv.core.InterruptCode
|
||||
|
||||
class CLINTCSRTestTopModule extends Module {
|
||||
val io = IO( new Bundle{
|
||||
@@ -63,10 +64,9 @@ class CLINTCSRTestTopModule extends Module {
|
||||
|
||||
class CLINTCSRTest extends AnyFlatSpec with ChiselScalatestTester{
|
||||
behavior of "CLINTCSRTest of Single Cycle CPU"
|
||||
it should "process " in {
|
||||
it should "handle external interrupt" in {
|
||||
test(new CLINTCSRTestTopModule).withAnnotations(TestAnnotations.annos) { c =>
|
||||
|
||||
//
|
||||
c.io.jump_flag.poke(false.B)
|
||||
c.io.csr_regs_write_enable.poke(false.B)
|
||||
c.io.interrupt_flag.poke(0.U)
|
||||
@@ -79,15 +79,18 @@ class CLINTCSRTest extends AnyFlatSpec with ChiselScalatestTester{
|
||||
c.io.csr_regs_write_data.poke(0x1888L.U)
|
||||
c.clock.step()
|
||||
c.io.csr_regs_write_enable.poke(false.B)
|
||||
|
||||
|
||||
// handle interrupt when not jumping
|
||||
c.io.jump_flag.poke(false.B)
|
||||
c.io.instruction_address.poke(0x1900L.U)
|
||||
c.io.instruction.poke(InstructionsNop.nop)
|
||||
c.io.interrupt_flag.poke(1.U)
|
||||
c.io.interrupt_flag.poke(InterruptCode.Timer0)
|
||||
|
||||
c.io.interrupt_assert.expect(true.B)
|
||||
c.io.interrupt_handler_address.expect(0x1144L.U)
|
||||
c.clock.step()
|
||||
c.io.interrupt_flag.poke(0.U)
|
||||
c.io.interrupt_flag.poke(InterruptCode.None)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MEPC)
|
||||
c.io.csr_regs_debug_read_data.expect(0x1904L.U)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MCAUSE)
|
||||
@@ -112,7 +115,7 @@ class CLINTCSRTest extends AnyFlatSpec with ChiselScalatestTester{
|
||||
c.io.interrupt_assert.expect(true.B)
|
||||
c.io.interrupt_handler_address.expect(0x1144L.U)
|
||||
c.clock.step()
|
||||
c.io.interrupt_flag.poke(0.U)
|
||||
c.io.interrupt_flag.poke(InterruptCode.None)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MEPC)
|
||||
c.io.csr_regs_debug_read_data.expect(0x1990L.U)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MCAUSE)
|
||||
@@ -139,4 +142,60 @@ class CLINTCSRTest extends AnyFlatSpec with ChiselScalatestTester{
|
||||
c.io.interrupt_assert.expect(false.B)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
it should "handle environmental instructions" in {
|
||||
test(new CLINTCSRTestTopModule).withAnnotations(TestAnnotations.annos) { c =>
|
||||
val interrupt_entry = 0x1144L.U
|
||||
|
||||
c.io.jump_flag.poke(false.B)
|
||||
c.io.csr_regs_write_enable.poke(true.B)
|
||||
c.io.csr_regs_write_address.poke(CSRRegister.MSTATUS)
|
||||
c.io.csr_regs_write_data.poke(0x1888L.U) // write mstatus MIE = 1, MPIE = 1
|
||||
c.clock.step()
|
||||
c.io.csr_regs_write_address.poke(CSRRegister.MTVEC)
|
||||
c.io.csr_regs_write_data.poke(interrupt_entry) // write mtvec to 0x1144
|
||||
c.clock.step()
|
||||
c.io.csr_regs_write_enable.poke(false.B)
|
||||
|
||||
// ecall
|
||||
c.io.instruction.poke(InstructionsEnv.ecall)
|
||||
c.io.instruction_address.poke(0x2000L.U)
|
||||
c.io.interrupt_flag.poke(InterruptCode.None)
|
||||
c.clock.step() // poking ecall instruction at address 0x2000, expect CLINT to handle it
|
||||
|
||||
c.io.interrupt_assert.expect(true.B)
|
||||
c.io.interrupt_handler_address.expect(interrupt_entry)
|
||||
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MEPC)
|
||||
c.io.csr_regs_debug_read_data.expect(0x2004L.U)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MCAUSE)
|
||||
c.io.csr_regs_debug_read_data.expect(0x0000_000BL.U) // ecall from M-mode
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MSTATUS)
|
||||
c.io.csr_regs_debug_read_data.expect(0x1880L.U)
|
||||
|
||||
// mret from ecall handler
|
||||
c.io.instruction.poke(InstructionsRet.mret)
|
||||
c.io.interrupt_assert.expect(true.B)
|
||||
c.io.interrupt_handler_address.expect(0x2004L.U)
|
||||
c.clock.step()
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MSTATUS)
|
||||
c.io.csr_regs_debug_read_data.expect(0x1888L.U)
|
||||
|
||||
// ebreak
|
||||
c.clock.step()
|
||||
c.io.instruction.poke(InstructionsEnv.ebreak)
|
||||
c.io.instruction_address.poke(0x2004L.U)
|
||||
c.clock.step()
|
||||
|
||||
c.io.interrupt_assert.expect(true.B)
|
||||
c.io.interrupt_handler_address.expect(interrupt_entry)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MEPC)
|
||||
c.io.csr_regs_debug_read_data.expect(0x2008L.U)
|
||||
c.io.csr_regs_debug_read_address.poke(CSRRegister.MCAUSE)
|
||||
c.io.csr_regs_debug_read_data.expect(0x0000_0003L.U) // breakpoint
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user