这个CPU的设计是教科书式的4级流水线结构。IF-ID-EX-MEM/WB 因此较为简单,效率也还可以。但是由于RISC-V IMC指令集是16-32位变长指令集。IF阶段需要正确地区分两种指令。不像OpenMIPS一样一个劲儿pc+=4就可以了。
另外求精~这个帖子会慢慢连载,不过学业较重,可能更新不及时。这个帖子适合看过自己动手写CPU——OpenMIPS的人。
由此,我们开始说IF阶段的设计。
先上仿真波形图:
先上传RISC-V的指令集描述资料~
首先,RISC-V指令的最后两位表示指令类型。为11是非压缩指令,11则是压缩指令。这样对指令的区分要比连续变长的CISC处理器简单很多。也不会有ARM的Thumb-ARM切换带来的开销。
同步RAM的数据落后于地址一个周期,自然而然我们需要有一个超前1word(4)的pc指针。将它称为pc_4。
同样,由于新版RISC-V规范规定32位指令不必须对齐到32位,因此,很有可能出现一条指令被截为两半的情况,一半存于上次取来的指令的高16位,一半存在新取来的指令中的低16位。因此我们还需要一个32位寄存器来缓冲上一次取来的指令,将它称为last_instr。
在32位指令对齐的情况下,pc直接对应于内存输出的数据。因此,判断是否是压缩指令,只需要判断内存输出最后两位即可。
如果在纯16位指令的情况下,pc也将直接对应于内存输出数据分别的低16位和高16位的最后两位。在判断到取到了16位指令后,将pc的自增速度从4调为2即可。
如果在32位指令和16位指令混合的情况下,我们需要引入一个等待逻辑,由于指令一半存于上次取来的数据的高16位,一半存在新取来的数据中的低16位。于是不能让原先取得的数据由于时钟的作用被新取来的数据覆盖掉。
于是,等待逻辑的执行条件是原先的pc自增量为2,并且当前的指令于32位对齐的情况。
故有代码:
|