一、基于RV32I ISA理解CPU结构

写在前面

  本文参考书目:《计算机组成,软硬件接口,Risc-V版》
  CPU结构和指令集是分不开的,因此,我们在使用HDL语言实现CPU之前,首先了解其指令集。

1、从一个简单数据通路开始

  简单数据通路,即RV32I的一个子集,实现RV32I指令集中的部分简单指令。(主要是R型,B型,lw和sw指令),下面先介绍这些指令。
一、基于RV32I ISA理解CPU结构_第1张图片

RV32I 的指令类型概览

  从图上可以得出,我们根据指令不同的格式将其分成了6种类型。

1.1 R型指令

  R型指令可以罗列为下图
一、基于RV32I ISA理解CPU结构_第2张图片
  或者是下图的样子
一、基于RV32I ISA理解CPU结构_第3张图片
  主要实现的功能是实现逻辑运算。R-type指令的opcode都是0110011,如前所示,R型指令的特殊之处在于其使用了rs1,rs2和rd,运算完毕rs1和rs2之后,把rs1,rs2运算完毕的结果写回(Write Back)RF中的rd. 值得一提的是,Risc-V有32个通用寄存器x0-x31,不妨将他们叫做寄存器堆(RF,Register File)。寄存器堆的首个寄存器,即x0是始终为0的,无法通过写入改变其值

1.2 lw指令

  lw指令是I型指令中的一种,lw指令详细描述如下
一、基于RV32I ISA理解CPU结构_第4张图片
  我们可以学会使用这种公式来表示指令的功能
x [ r d ] = M [ x [ r s 1 ] + s e x t ( o f f s e t ) ] x[rd] = M[x[rs1]+sext(offset)] x[rd]=M[x[rs1]+sext(offset)]
  lw指令用到了rs1,rd和offset三类数据,需要读Data Memory并写回(Write Back)给RF。其中和R型指令的共同点是都用了rs和rd。
  值得一提的是,同样属于I型指令的addi这些,就不需要访存MEM这一步,而是直接将结果写回。而且这两类I型指令的opcode也不同,足见其特殊之处。因此I-Type指令可以细分为访存类立即数运算类

1.3 sw指令

  sw指令的详细叙述如下
一、基于RV32I ISA理解CPU结构_第5张图片
  sw使用了rs1,rs2和offset三类数据,需要将rs2的数据写入到Data Memory.

1.4 B型指令

  B型指令是 branch,分支跳转指令的简称,其格式如下
一、基于RV32I ISA理解CPU结构_第6张图片
  或者如下

在这里插入图片描述
  B型指令的opcode是1100011,其用到了rs1,rs2和offset,这一点和sw一样。只不过B指令做的不是计算rs1和offset的结果作为访存地址,而是将rs1,rs2作为ALU输入。而offset是和pc进行运算的(如果条件转移满足的话),可以参考beq指令。
一、基于RV32I ISA理解CPU结构_第7张图片

1.5 简单数据通路

  通过下图我们可以看到该结构是如何将上述四种指令结合起来
一、基于RV32I ISA理解CPU结构_第8张图片
  我们以R型指令为例(结合上图)。
  PC是时序电路,假设当下PC输入时pc+4,pc输出是pc,那当下一个posedge到来时,PC输出变成pc+4,完成了一次输入到输出的刷新。pc变成pc+4后,输入到Instruction Memory的read address就发生了变化。Instruction Memory是组合逻辑,当Read Address变化后,其输出的Instruction也发生变化。
  输出的Instruction经过简单的译码之后,给出register1和register2的地址。给到RF,RF的读取也是组合逻辑,因此随之Read data1和Read data2也会立即变化.
  rs1,rs2送到ALU中,计算完毕的结果在写回处,即RF的write data处等待下次时钟周期的到来.
  下一个posedge到来后写回的数据就会被写入RF。

  以上描述了指令运行的五个阶段,IF,ID,EX,MEM和WB,在R型指令中没有MEM阶段,EX的结果直接WB到RF。

  我们再看lw指令。
  lw指令选择计算rs1和offset,计算的结果作为Data Memory的读地址,Mem的读取也是组合逻辑,读取的结果WB到RF。因此该指令是完全包含五个阶段的。

  我们再看sw指令。
  同样计算rs1和offset的结果作为Data Memory的写地址,rs2作为Write data,由于写是时序,因此在下一个posedge到来时将值写入到Data memory中。这个指令是没有WB阶段的,因为是store word,把数据写入到Data Memory就标志着结束。

  最后我们再来看B指令。
  B型指令例如beq,将rs1和rs2进行对比,如果输出结果Zero指示为0的话,就将PC的输入值改为pc+offset(左移1位,按照16位对指令空间进行地址跳转),否则仍然是pc+4.

2、加入控制模块的数据通路

  控制模块将ALU的控制单独分离出来一个模块。这样做的好处是多级控制,简化逻辑。如下图所示。
  *需要注意的是我们写的是RV32I,所以图上的64位有关的叙述我们需要进行调整。
一、基于RV32I ISA理解CPU结构_第9张图片
  我们可以观察到,除了ALU控制之外,Control的控制是基于7位的opcode的,这一定程度上也能解释I型指令中,为何访存指令立即数算数指令,它们的结构一样(因此都是I型指令),却要用不同的opcode.见下图
一、基于RV32I ISA理解CPU结构_第10张图片
  因为立即数运算和访存的执行很像,都是rs1和offset相加,只不过立即数运算是直接将相加结果写回到RF,而访存指令是将结果作为访存的地址,得到的输出再写回RF,因此多了一步MEM。因此这些需要通过控制模块来实现,所以采用不同的opcode来保证不同的控制输出(例如多选器选择写回RF的数据源)

你可能感兴趣的:(RISC-V,CPU实战专题,开发语言,计算机组成,risc-v)