|
mini risc mcu源码 这个帖子 中模拟了一个risc mcu硬件,并且基本上进行了行注释,很好理解。现在要做的是如何模拟写bin文件到硬件的flash中,并且如何模拟上电并运行程序,所以下面的代码就是要做这样的事情:
class RiscTester(m:Risc) extends PeekPokeTester(m) {
def wr(addr:BigInt,data:BigInt) = { //写
poke(m.io.isWr,1) //isWr 写启动赋1
poke(m.io.wrAddr,addr) //写地址
poke(m.io.wrData,data) //待写的数据
step(1)
}
def boot() = { //上电boot
poke(m.io.isWr,0) //写启动复位
poke(m.io.boot,1) //boot置1
step(1)
}
def tick() = { //非写、非boot 表示正常工作状态,此时不需要isWr写flash也不需要boot 每时钟周期模拟一个芯片硬件中的tick
poke(m.io.isWr,0)
poke(m.io.boot,0)
step(1)
}
/*
def I (op: UInt, rc: Int, ra: Int, rb: Int) =
Cat(op, UInt(rc, 8), UInt(ra, 8), UInt(rb, 8))
*/
def I(op:UInt,rc:Int,ra:Int,rb:Int) = {
((op.litValue() & 1) << 24) | ((rc & Integer.parseInt("FF",16)) << 16) | ((ra & Integer.parseInt("FF",16)) << 8) | (rb & Integer.parseInt("FF",16))
//最高8位 16进制形式次高8位 16进制形式中8位 16进制形式低8位
}
//app用来表示.bin文件内容
val app = Array(I(m.imm_op,1,0,1), // r1 <- 1
I(m.add_op,1,1,1), //r1 <- r1 + r1
I(m.add_op,1,1,1), //r1 <- r1 + r1
I(m.add_op,255,1,0)) //rh <- r1
wr(0,0) //skip reset
for(addr <- 0 until app.length)
wr(addr,app(addr)) //将.bin文件内容装载到内存的代码区或烧写代码到flash
boot() //上电启动
var k = 0
do {
tick()
k += 1
} while (peek(m.io.valid) == 0 && k < 10) //valid信号有效且k<10则始终非写、非boot状态
assert(k < 10,"Time Limit") //如果k>=10则抛出异常信息:Time Limit
expect(m.io.out,4) //期待out输出为4
}
class DownTickerSpec extends ChiselFlatSpec {
behavior of("Risc")
backends foreach {backend=>
it should s"run simple fsm implementation in $backend" in {
iotesters.Driver(()=>new Risc)(c=>new RiscTester(c)) should be(true)
}
}
}
|
|