这次要来实作指令decoder,负责pipeline中的decode stage。计组教科书上常见的pipeline架构依序为:fetch、decode、execute、memory、write back,当然在一个instruction-accurate(IA)的模拟器中,没有必要去切得这麽细,目前只要大致分成fetch、decode以及execute三个步骤就好,memory与write back就合并在execute stage。这三个步骤做的处理罗列如下:
暂时先以常数取代,等memory model实作完成後再来时做此stage。
稍微研究了现有的模拟器是如何实作decoder,发现主要有两种方法:
fn decode(inst_bytes) -> InstID {
for entry in instruction_table_buffer {
if (inst_bytes & entry.mask) == entry.opcode
return entry.inst_id
for entry in instruction_table {
if (inst_bytes & entry.mask) == entry.opcode {
instruction_table_buffer.add(entry)
return entry.inst_id
}
}
}
fn decode(inst_bytes) -> InstID {
switch (inst_bytes & mask_a) {
case 0: {
switch (inst_bytes & mask_b) {
case 0:
return InstID::SUB
...
}
}
case 1:
return InstID::ADD
...
}
}
这边采用第二种方案,并且保留弹性,之後也可以实作第一种方案,并且比较两种的效能。
很简单,直接呼叫对应的指令function就好。
将以上的三个stage结合起来就可以完整的执行一条指令:
impl RVCore {
fn step(&mut self, inst_bytes: u32) {
// Decode
let inst = self.id_instance.decode(inst_bytes);
// Execute
(inst.operate)(self, &inst);
self.pc += inst.len;
}
}
let mut core = RVCore{};
// Fetch, 假设fetch的结果为0x00002197(AUIPC)
core.step(0x00002197);
完整的程序码可以参考此连结
<<: 使用证书对代码进行签章,以防止其被篡改并向用户验证您的身份-使用您的私钥对代码进行散列并加密结果
这个实用网路行销工具系列文,将会整理我平常研究的各项网路行销工具,帮助工程师如果有现成的服务可以快速...
Implement audio wave generator using the Mbed API ...
虽然在 WordPress 中扩充功能有很多方式,例如在布景主题上使用子布景主题 (child th...
前言 前两天分享了远距工作的好处与挑战,今天针对应用面来谈谈 Scrum 活动如何在远距工作的情况下...
前篇回顾 sed - 简介 读取编辑文字档的好工具 sed - 2 Pattern sed - 3 ...