五段式流水线CPU

流水线CPU

一、流水线CPU概述

1、流水线CPU的原理

流水线CPU是为提高吞吐量而创造的,五段式流水线CPU的吞吐量是单周期CPU的五倍,同一时间CPU上最多有五条指令在运行。如何达到同一CPU上五条指令呢?答案就在于把每条指令都拆分成五个阶段,按照CPU硬件执行流来拆成五段:IF(instruction fetch)、DEC(decode)、EXE(execute)、ME(memory)、WB(write back),CPU上五段部分分别执行一条指令的一个阶段。

因为CPU上五段分别进行不同指令的不同阶段,每段都需要自己当前执行指令的数据:IF段所用数据为指令地址,可有pc寄存器提供;DE、EXE、ME、WB段所用数据包含但不限于指令内容,一定需要对应流水线寄存器保存。

2、流水线CPU设计的难点

流水线CPU同时有多条指令运行,一个很重要的设计因素是解决冲突。冲突包含硬件冲突、控制冲突和数据冲突。

  • 硬件冲突

    硬件冲突是说同一时刻需要对同一互斥硬件(一次只允许一次读或写)进行访问,举例来说,D段需要从存储器中取出指令,M段需要对存储器写入数据,这两个操作同时进行就会带来冲突,在这里IM和DM是独立的两个存储器,因此不必考虑。

  • 控制冲突

    控制冲突是分支指令和跳转指令带来的冲突。分支指令的最终分支地址晚于下一周期到来,导致下一条指令的地址不能及时算出或者决定;跳转指令的跳转地址晚于下一周期到来,导致上述同样冲突。解决这样的冲突主要是通过假设不跳转或者延迟槽。假设不跳转是说先假设不跳转和分支,正常执行下一条指令,当计算出要跳转时清楚已执行的结果。延迟槽是说跳转指令后面加空指令nop,即等待跳转地址计算出来再决定是继续下一条指令还是跳转。

  • 数据冲突

    数据冲突是关于数据“新鲜性”的冲突。指令的执行离不开寄存器,有的指令会利用寄存器数据,有的指令会写回寄存器,有的指令两者皆有,当前序执行的指令的目的寄存器(将要写回的寄存器)和后序执行的指令的源寄存器(利用其数据的寄存器)相同时,就存在数据关联。当前序指令数据还未写入寄存器,后序指令就要用到该数据时,就会产生错误(冲突)。解决这种冲突需要暂停或者转发:当前序指令的“新”将要写回寄存器的数据(计算)赶不及后序指令使用其数据时就需要暂停后序指令,直到前序指令的“新”数据准备好;当前序指令的“新”数据能赶上后序指令的使用,当前序指令的“新”数据准备好后,转发给后序指令当前所处阶段的流水线寄存器,以达到更新数据的效果。

注意:以下是笔者设计流水线的流程(吃百家饭得来

二、流水线CPU的功能设计

1、支持指令

str ld cal_r cal_i lui b_type j jr jal jalr shamt mod
sw lw addu ori   beq         sll mult
sb lb add xori   bne         sra multu
sh lh subu andi   blez         srl div
  lbu sub addiu   bgtz           divu
  lhu sllv addi   bltz            
    srav sltiu   bgez            
    srlv slti                
    and                  
    or                  
    xor                  
    nor                  
    slt                  
    sltu                  

2、流水线寄存器

流水线寄存器记录上一阶段的数据并保持,供所在阶段使用,因此每阶段寄存器所需数据如下:

D E M W
IR IR IR IR
      RD
    AO AO
  RD1    
  EXTD EXTD EXTD
  RD2 RD2  
PC4      
PC8 PC8 PC8 PC8
PC PC PC PC
    TNEW_E TNEW_M
    HI HI
    LO LO

3、所需硬件

先不考虑所有冲突而只考虑执行指令,和单周期CPU的功能硬件设计一样,列出所需硬件,不一样的是指令分五段执行,硬件也可分阶段列出。

本表不包含多选器,多选器在整合数据通路时给出。

下面列出的硬件中有三个值得说明:

  • BEEXT和RDEXT

    支持指令中有sh,sb,lh,lhu,lb,lbu这些对半字、字节操作的指令,但是存储器是按照字读或者写的,因此对于存储指令需要BEEXT给出字节选择信号,对于加载指令需要RDEXT处理读出的字。

    BEEXT接受的输入为AO_M1_0和三个布尔信号(分别代表指令是否为sw,sh,sb)。AO_M1_0意义是ALU输出在M段结果的低两位,也就是写入地址对4取模的结果(一个字4字节)。BEEXT产生的输出是四位信号,分别表示将要存储的数据的四个字节是否存储。

    RDEXT接受的输入为AO_W1_0、RD_W和五个布尔信号(分别表示指令是否是lw,lh,lhu,lb,lbu)。AO_W1_0是ALU输出在W段结果的低两位,也就是读出地址对4取模的结果。RD_W是DM中读出的字。按照五条指令的要求分别对RD_W处理,最后根据五个布尔信号选择一个输出。

  • MDU

    乘除运算单元和hi,lo寄存器所在。whi和wlo是hi,lo寄存器的写入信号。start是乘除运算的启动信号,busy是乘除运算进行中的信号。这里乘法模拟用5个时钟周期完成(start后的第一个上升沿开始,busy高亮五个周期),除法模拟用10个时钟周期完成。

阶段 module input output 功能描述
IF PC D Q  
  ADD4 PC PC4  
  ADD8 PC PC8  
  IM IA IR  
         
DE RF A1 RD1 从寄存器堆读出寄存器数据
    A2 RD2  
  EXT I16 EXTD 选择输出SIMM,LIMM,UIMM
    EXTOP    
  CMP0 FRSD LESS 输出和0比较的结果,独热输出
      GREAT  
      LE_EQ  
      GR_EQ  
  CMP D1 RES 输出比较结果
    D2    
  NPC PC4 NEXTPC 选择输出BPC,JPC
    I26    
    NPCOP    
         
EX MDU NUM1 BUSY 乘除模块,WHI,WLO为写使能,WDHI,WDLO为写入数据
    NUM2 HI  
    MDUOP LO  
    START    
    WHI    
    WLO    
  ALU A AO 执行不同操作
    B    
    SHAMT    
    ALUOP    
         
ME BEEXT AO_M1_0 BE 得到字节写入使能信号,为1的那一位代表对应dm中的字相应部分写入字节
    SW_M    
    SH_M    
    SB_M    
  DM DA[11:2] RD 支持写入字节、半字、字和读出字
    WD    
    WM    
    BE[3:0]    
         
WB RDEXT RD_W RDEXTD 将dm中取出的字按照指令做相应处理得到将写入rf的字
    AO_W1_0    
    LW_W    
    LHU_W    
    LH_W    
    LBU_W    
    LB_W    
  RF A3    
    WD3    
    WR    

4、数据通路

将流水线寄存器和功能硬件针对每一条指令连接起来。

模块 INPUT NOP LD STR CAL_R CAL_I SHAMT LUI J JR JAL JALR B_TYPE MDU
PC D                          
ADD4 PC Q Q Q Q Q Q Q Q   Q   Q Q
ADD8 PC                   Q Q    
IM IA Q Q Q Q Q Q Q Q Q Q Q Q Q
                             
PC D PC4 PC4 PC4 PC4 PC4 PC4 PC4         PC4 PC4
REG_D IR_D IR IR IR IR IR IR IR IR IR IR IR IR IR
  PC4_D               PC4   PC4   PC4  
  PC8_D                   PC8 PC8    
RF A1   IR_D[RS] IR_D[RS] IR_D[RS] IR_D[RS]       IR_D[RS]   IR_D[RS] IR_D[RS] IR_D[RS]
  A2       IR_D[RT]   IR_D[RT]           IR_D[RT] IR_D[RT]
EXT I16   IR_D[I16] IR_D[I16]   IR_D[I16]   IR_D[I16]            
CMP D1                       RD1  
  D2                       RD2  
CMP0 FRSD                       FRSD  
NPC PC4               PC4_D   PC4_D   PC4_D  
  I26               IR_D[I26]   IR_D[I26]   IR_D[I16]  
                             
PC D               NEXTPC RD1 NEXTPC RD1 NEXTPC/PC4  
REG_E IR_E IR_D IR_D IR_D IR_D IR_D IR_D IR_D IR_D IR_D IR_D IR_D IR_D IR_D
  RS_E   RD1 RD1 RD1 RD1               RD1
  EXT_E   EXTD EXTD   EXTD   EXTD            
  RT_E     RD2 RD2   RD2             RD2
  PC8_E                   PC8_D PC8_D    
MDU NUM1                         RS_E
  NUM2                         RT_E
ALU A   RS_E RS_E RS_E RS_E                
  B   EXT_E EXT_E RT_E EXT_E RT_E              
  SHAMT           IR_E[SH]              
                             
REG_M IR_M IR_E IR_E IR_E IR_E IR_E IR_E IR_E IR_E IR_E IR_E IR_E IR_E IR_E
  AO_M   AO AO AO AO AO              
  RT_M     RT_E                    
  PC8_M                   PC8_E PC8_E    
  EXT_M             EXT_E            
  HI_M                          
  LO_M                          
BEEXT AO_M1_0     AO_M[1:0]                    
DM DA   AO_M AO_M                    
  WD     RT_M                    
  BE     BE                    
                             
REG_W IR_W IR_M IR_M IR_M IR_M IR_M IR_M IR_M IR_M IR_M IR_M IR_M IR_M IR_M
  RD_W   RD                      
  AO_W   AO_M   AO_M AO_M AO_M              
  PC8_W                   PC8_M PC8_M    
  EXT_W             EXT_M            
  HI_W                          
  LO_W                          
RDEXT RD_W   RD_W                      
  AO_W1_0   AO_W[1:0]                      
RF A3   IR_W[RT]   IR_W[RD] IR_W[RT] IR_M[RD] IR_W[RT]     $31 IR_W[RD]    
  WD3   RDEXTD   AO_W AO_W AO_W EXT_W     PC8_W PC8_W    

5、整合数据通路

将上面的数据通路整合起来,得到硬件间的连接情况。当某一硬件的某一端口前输入来源不唯一时,需添加多选器来选择一个作为输入。

外模块 内模块 输入               复用器 选择信号
IFU PC Q PC4 NEXTPC RD1         MFPC PCSEL
  ADD4 PC Q                
  ADD8 PC Q                
  IM IA Q                
                       
    nowstate                  
REG_D   IR_D IR                
    PC4_D PC4                
    PC8_D PC8                
                       
RFU RF A1 IR_D[RS]                
    A2 IR_D[RT]                
    A3 IR_W[RT] IR_W[RD] 31         MFA3 A3SEL
    WD3 RDEXTD AO_W EXT_W PC8_W HI_W LO_W   MFWD3 WD3SEL
                       
IDU EXT I16 IR_D[I16]                
  CMP0 FRSD RD1                
  CMP D1 RD1                
    D2 RD2                
  NPC PC4 PC4_D                
    I26 IR_D[I26]                
                       
REG_E   IR_E IR_D                
    RS_E RD1                
    EXT_E EXTD                
    RT_E RD2                
    PC8_E PC8_D                
                       
EXU MDU NUM1 RS_E                
    NUM2 RT_E RS_E           MFNUM2 NUM2SEL
  ALU A RS_E                
    B EXT_E RT_E           MFB BSEL
    SHAMT IR_E[SH]                
                       
REG_M   IR_M IR_E                
    AO_M AO                
    RT_M RT_E                
    PC8_M PC8_E                
    EXT_M EXT_E                
    HI_M HI                
    LO_M LO                
                       
MEU BEEXT AO_M1_0 AO_M[1:0]                
  DM DA AO_M                
    WD RT_M                
    BE BE                
                       
REG_W   IR_W IR_M                
    RD_W RD                
    AO_W AO_M                
    PC8_W PC8_M                
    EXT_W EXT_M                
    HI_W HI_M                
    LO_W LO_M                
                       
RFU RDEXT RD_W RD_W                
    AO_W1_0 AO_W[1:0]                

6、控制信号

列出所有指令的控制信号表。

TYPE 指令 INPUT     OUTPUT                            
    OP FUNCT RT PCSEL EXTOP NPCOP ALUCTRL ALUOP BSEL START MDUOP WHI WLO NUM2SEL WM A3SEL WD3SEL WR
LD LW 100011 X X 0 0 X 0 0(+) 0 0 X 0 0 X 0(不写) 0 0 1
  LHU 100101 X X 0 0 X 0 0(+) 0 0 X 0 0 X 0 0 0 1
  LH 100001 X X 0 0 X 0 0(+) 0 0 X 0 0 X 0 0 0 1
  LBU 100100 X X 0 0 X 0 0(+) 0 0 X 0 0 X 0 0 0 1
  LB 100000 X X 0 0 X 0 0(+) 0 0 X 0 0 X 0 0 0 1
STR SW 101011 X X 0 0 X 0 0(+) 0 0 X 0 0 X 1 X X 0
  SH 101001 X X 0 0 X 0 0(+) 0 0 X 0 0 X 1 X X 0
  SB 101000 X X 0 0 X 0 0(+) 0 0 X 0 0 X 1 X X 0
CAL_R ADD 000000 100000 X 0 X X 15 0 1 0 X 0 0 X 0 1 1 1
  ADDU 000000 100001 X 0 X X 15 0 1 0 X 0 0 X 0 1 1 1
  SUB 000000 100010 X 0 X X 15 1 1 0 X 0 0 X 0 1 1 1
  SUBU 000000 100011 X 0 X X 15 1 1 0 X 0 0 X 0 1 1 1
  SLLV 000000 000100 X 0 X X 15 4 1 0 X 0 0 X 0 1 1 1
  SRAV 000000 000111 X 0 X X 15 5 1 0 X 0 0 X 0 1 1 1
  SRLV 000000 000110 X 0 X X 15 6 1 0 X 0 0 X 0 1 1 1
  AND 000000 100100 X 0 X X 15 10 1 0 X 0 0 X 0 1 1 1
  OR 000000 100101 X 0 X X 15 2 1 0 X 0 0 X 0 1 1 1
  XOR 000000 100110 X 0 X X 15 11 1 0 X 0 0 X 0 1 1 1
  NOR 000000 100111 X 0 X X 15 12 1 0 X 0 0 X 0 1 1 1
  SLT 000000 101010 X 0 X X 15 3 1 0 X 0 0 X 0 1 1 1
  SLTU 000000 101011 X 0 X X 15 13 1 0 X 0 0 X 0 1 1 1
SHAMT SLL 000000 000000 X 0 X X 15 7 1 0 X 0 0 X 0 1 1 1
  SRL 000000 000010 X 0 X X 15 9 1 0 X 0 0 X 0 1 1 1
  SRA 000000 000011 X 0 X X 15 8 1 0 X 0 0 X 0 1 1 1
CAL_I ORI 001101 X X 0 2 X 2 2 0 0 X 0 0 X 0 0 1 1
  XORI 001110 X X 0 2 X 11 11 0 0 X 0 0 X 0 0 1 1
  ANDI 001100 X X 0 2 X 10 10 0 0 X 0 0 X 0 0 1 1
  SLTIU 001011 X X 0 0 X 13 13 0 0 X 0 0 X 0 0 1 1
  SLTI 001010 X X 0 0 X 3 3 0 0 X 0 0 X 0 0 1 1
  ADDI 001000 X X 0 0 X 0 0 0 0 X 0 0 X 0 0 1 1
  ADDIU 001001 X X 0 0 X 0 0 0 0 X 0 0 X 0 0 1 1
LUI   001111 X X 0 1 X X X X 0 X 0 0 X 0 0 2 1
B_TYPE BEQ 000100 X X RES X 0 X X X 0 X 0 0 X 0 X X 0
  BNE 000101 X X ~RES X 0 X X X 0 X 0 0 X 0 X X 0
  BLEZ 000110 X X ~GREAT X 0 X X X 0 X 0 0 X 0 X X 0
  BGTZ 000111 X X GREAT X 0 X X X 0 X 0 0 X 0 X X 0
  BLTZ 000001 X 00000 LESS X 0 X X X 0 X 0 0 X 0 X X 0
  BGEZ 000001 X 00001 ~LESS X 0 X X X 0 X 0 0 X 0 X X 0
J   000010 X X 1 X 1 X X X 0 X 0 0 X 0 X X 0
JR   000000 001000 X 2 X X X X X 0 X 0 0 X 0 X X 0
JAL   000011 X X 1 X 1 X X X 0 X 0 0 X 0 2 3 1
JALR   000000 001001 X 2 X X X X X 0 X 0 0 X 0 1 3 1
NOP   000000 000000 X 0 X X X X X 0 X 0 0 X 0 X X 0
MOD MULT 000000 011000 X 0 X X X X X 1 0 0 0 0 0 X X 0
  MULTU 000000 011001 X 0 X X X X X 1 1 0 0 0 0 X X 0
  DIV 000000 011010 X 0 X X X X X 1 2 0 0 0 0 X X 0
  DIVU 000000 011011 X 0 X X X X X 1 3 0 0 0 0 X X 0
MFR MFHI 000000 010000 X 0 X X X X X 0 X 0 0 X 0 1 4 1
  MFLO 000000 010010 X 0 X X X X X 0 X 0 0 X 0 1 5 1
MTO MTHI 000000 010001 X 0 X X X X X 0 X 1 0 X 0 X X 0
  MTLO 000000 010011 X 0 X X X X X 0 X 0 1 1 0 X X 0

三、流水线CPU的冲突解决

0、特别说明

我们现在要考虑流水线CPU的冲突问题,前面说过的三类冲突问题:硬件冲突在这里没有,因为IM和DM的独立;控制冲突通过延迟槽解决,因此硬件上也不需要多余设计(如果用假设不跳转的思路,需要增加流水线寄存器的同步清零信号,以清除错误执行指令的结果,且添加同步清零的控制逻辑);数据冲突是我们着重要考虑的问题,关键在于什么时候暂停,什么时候转发,并且逻辑不能太复杂,经过大佬方法点拨和个人揣摩,我采取如下方法。

1、AT法

AT法是大佬的叫法,按我下面的表格,更适合叫做是SDT法,即源头、目的时间法。

对任意一条标准指令(只涉及通用寄存器的指令),有源头寄存器和目的寄存器:当一条通用指令i需要寄存器s1、寄存器s2的数据时,s1和s2就是i的源头寄存器(不需要用到数据时,s1和s2为0);当一条通用指令i需要写入寄存器des时,des就是i的目的寄存器(不需要写寄存器时,des为0)。

对于源寄存器s有时间tuseD(/E/M),意思是在从D(/E/M)段开始,过几个时钟周期需要使用s里的数据。对于目的寄存器des有数据tnewD(/E/M),意思是从D(/E/M)段开始,过几个时钟周期des的数据被更新。

  • 什么时候要暂停

    暂停的时刻放在D段,每条指令i在D段时,要和它前面的指令j对照判断,看是否需要暂停:当i的源寄存器和j的目的寄存器相同时(设为寄存器k),i和j存在数据关联,这时如果i的tuse大于j的tnew,代表k中数据还没被j准备好(甚至不能转发过来),这时需要暂停D段指令i,否则i会使用k中旧数据里错误运行。

    暂停需要做的工作很简单,将pc和D段流水线寄存器禁止使能,即一直维持当前数据直到D段指令和前序指令没有数据关联或者tuse不大于tnew。

  • 何时转发?转发去哪?转发什么?

    当前序指令的tnew为0时代表新数据已经准备好,需要立刻转发到前面以备可能的数据冲突。

    这里是转发到前面阶段(比如D段)的最开始,紧接着对应阶段的寄存器数据源头(比如RD1、RD2、RS_E、RT_E),和原本流水线寄存器的输出一起被选择(比如多选器MFRSD、MFRTD),当数据关联时就选择转发的数据(比如FRSD、FRTD),否则选择原来数据(比如RD1、RD2)。

    转发的是前序指令已经准备好的数据,在每一阶段可以根据指令类别写出待转发数据,得到真值表。

    特别的对于W段指令到D段指令的转发,由于W段写入和D段读出都是对于寄存器堆,我们采用内部转发:通过寄存器堆的结构使得,在同一个时钟上升沿,若有数据写入寄存器r,也有从寄存器r读出数据的请求,将将写入数据直接读出。这样一来,W段到D段的数据不再需要外部转发。

对于非通用指令,比如mult、div、mfhi、mflo、mthi、mtlo,通过下表分析可知:它们内部不存在数据冲突,因为写回hi/lo和计算出结果在同一周期内完成;它们和通用指令之间的数据冲突处理方式和前面一样。

        S1_D/E/M TUSE1_ S1D MUX   S2_D/E/M TUSE2_ S2D MUX   DES_ TNEW_ DESD_
D   STR   IR_D[RS] 1 RD1 MFRSD   IR_D[RT] 2 RD2 MFRTD   X X X
    LD   IR_D[RS] 1 RD1 MFRSD   $0 X       X X X
    CAL_R   IR_D[RS] 1 RD1 MFRSD   IR_D[RT] 1 RD2 MFRTD   X X X
    SHAMT   $0 X       IR_D[RT] 1 RD2 MFRTD   X X X
    CAL_I   IR_D[RS] 1 RD1 MFRSD   $0 X       X X X
    LUI   $0 X       $0 X       X X X
    B_TYPE   IR_D[RS] 0 RD1 MFRSD   IR_D[RT] 0 RD2 MFRTD   X X X
    J   $0 X       $0 X       X X X
    JR   IR_D[RS] 0 RD1 MFRSD   $0 X       X X X
    JAL   $0 X       $0 X       X X X
    JALR   IR_D[RS] 0 RD1 MFRSD   $0 X       X X X
    MOD   IR_D[RS] 1 RD1 MFRSD   IR_D[RT] 1 RD2 MFRTD        
    MFHI   HI/$0 3       $0 X            
    MFLO   LO/$0 3       $0 X            
    MTHI   IR_D[RS] 1 RD1 MFRSD   $0 X            
    MTLO   IR_D[RS] 1 RD1 MFRSD   $0 X            
                                 
E   STR   IR_E[RS] 0 RS_E MFRSE   IR_E[RT] 1 RT_E MFRTE   $0 X X
    LD   IR_E[RS] 0 RS_E MFRSE   $0 X       IR_E[RT] 2 X
    CAL_R   IR_E[RS] 0 RS_E MFRSE   IR_E[RT] 0 RT_E MFRTE   IR_E[RD] 1 X
    SHAMT   $0 X       IR_E[RT] 0 RT_E MFRTE   IR_E[RD] 1 X
    CAL_I   IR_E[RS] 0 RS_E MFRSE   $0 X       IR_E[RT] 1 X
    LUI   $0 X       $0 X       IR_E[RT] 0 EXT_E
    B_TYPE   $0 X       $0 X       $0 X X
    J   $0 X       $0 X       $0 X X
    JR   $0 X       $0 X       $0 X X
    JAL   $0 X       $0 X       $31 0 PC8_E
    JALR   $0 X       $0 X       IR_E[RD] 0 PC8_E
    MOD   IR_E[RS] 0 RS_E MFRSE   IR_E[RT] 0 RT_E MFRTE   HI,LO/$0 5,10/X X
    MFHI   HI/$0 2 HI/X     $0 X       IR_E[RD] 1 X
    MFLO   LO/$0 2 LO/X     $0 X       IR_E[RD] 1 X
    MTHI   IR_E[RS] 0 RS_E MFRSE   $0 X       HI/$0 0 X
    MTLO   IR_E[RS] 0 RS_E MFRSE   $0 X       LO/$0 0 X
                                 
M   STR   $0 X       IR_M[RT] 0 RT_M MFRTM   $0 X X
    LD   $0 X       $0 X       IR_M[RT] 1 X
    CAL_R   $0 X       $0 X       IR_M[RD] 0 AO_M
    SHAMT   $0 X       $0 X       IR_M[RD] 0 AO_M
    CAL_I   $0 X       $0 X       IR_M[RT] 0 AO_M
    LUI   $0 X       $0 X       IR_M[RT] 0 EXT_M
    B_TYPE   $0 X       $0 X       $0 X X
    J   $0 X       $0 X       $0 X X
    JR   $0 X       $0 X       $0 X X
    JAL   $0 X       $0 X       $31 0 PC8_M
    JALR   $0 X       $0 X       IR_M[RD] 0 PC8_M
    MOD   $0 X       $0 X       $0 X X
    MFHI   HI/$0 1 HI_M/X     $0 X       IR_M[RD] 0 HI_M
    MFLO   LO/$0 1 LO_M/X     $0 X       IR_M[RD] 0 LO_M
    MTHI   $0 X       $0 X       $0 X X
    MTLO   $0 X       $0 X       $0 X X
                                 
W   STR   X X       X X       $0 X X

2、补充所需硬件

经过AT法的分析,每一阶段寄存器数据的源头不再唯一,还包含从后面阶段(前序指令)转发过来的“最新”数据,需要添加相应多选器,这些多选器mux在上表中已然列出。

阶段 module input output 功能描述
IF MFPC PCSEL D 选择下一个pc值
    PC4    
    NEXTPC    
    RD1/FRSD    
  PC D Q  
  ADD4 PC PC4  
  ADD8 PC PC8  
  IM IA IR  
         
DE RF A1 RD1 从寄存器堆读出寄存器数据
    A2 RD2  
  MFRSD FRSDSEL FRSD 选择转发到D级rs寄存器的值
    RD1    
    ETOD   E段转发到D段的数据,下同
    MTOD    
  MFRTD FRTDSEL FRTD 选择转发到D级rt寄存器的值
    RD2    
    ETOD    
    MTOD    
  EXT I16 EXTD 选择输出SIMM,LIMM,UIMM
    EXTOP    
  CMP0 FRSD LESS 输出和0比较的结果,独热输出
      GREAT  
      LE_EQ  
      GR_EQ  
  CMP D1 RES 输出比较结果
    D2    
  NPC PC4 NEXTPC 选择输出BPC,JPC
    I26    
    NPCOP    
         
EX MFRSE FRSESEL FRSE 选择转发到E级rs寄存器的值
    RS_E    
    MTOE    
    WTOE    
  MFRTE FRTESEL FRTE 选择转发到E级rt寄存器的值
    RT_E    
    MTOE    
    WTOE    
  MFNUM2 FRTE NUM2 选择输入num2
    FRSE    
  MDU NUM1 BUSY 乘除模块,WHI,WLO为写使能,WDHI,WDLO为写入数据
    NUM2 HI  
    MDUOP LO  
    START    
    WHI    
    WLO    
  MFB BSEL B 选择alu的b输入
    EXT_E    
    FRTE    
  ALU A AO 执行不同操作
    B    
    SHAMT    
    ALUOP    
         
ME MFRTM FRTMSEL FRTM 选择转发到M级rt寄存器的值
    RT_M    
    WTOM    
  BEEXT AO_M1_0 BE 得到字节写入使能信号,为1的那一位代表对应dm中的字相应部分写入字节
    SW_M    
    SH_M    
    SB_M    
  DM DA[11:2] RD 支持写入字节、半字、字和读出字
    WD    
    WM    
    BE[3:0]    
         
WB RDEXT RD_W RDEXTD 将dm中取出的字按照指令做相应处理得到将写入rf的字
    AO_W1_0    
    LW_W    
    LHU_W    
    LH_W    
    LBU_W    
    LB_W    
  MFA3 A3SEL A3 选择a3
    IR_W[RT]    
    IR_W[RD]    
    31    
  MFWD3 WD3SEL WD3 选择wd3
    RDEXTD    
    AO_W    
    EXT_W    
    PC8_W    
  RF A3    
    WD3    
    WR    

3、修改数据通路

经过转发数据mux选择后的数据作为新的所在阶段寄存器数据的源头。

外模块 内模块 端口               复用器 选择信号
IFU PC Q PC4 NEXTPC RD1/FRSD         MFPC PCSEL
  ADD4 PC Q                
  ADD8 PC Q                
  IM IA Q                
                       
    nowstate                  
REG_D   IR_D IR                
    PC4_D PC4                
    PC8_D PC8                
                       
RFU RF A1 IR_D[RS]                
    A2 IR_D[RT]                
    A3 IR_W[RT] IR_W[RD] $31         MFA3 A3SEL
    WD3 RDEXTD AO_W EXT_W PC8_W HI_W LO_W   MFWD3 WD3SEL
  MFRSD FRSDSEL                  
    RD1                  
    ETOD                  
    MTOD                  
  MFRTD FRTDSEL                  
    RD2                  
    ETOD                  
    MTOD                  
                       
IDU EXT I16 IR_D[I16]                
  CMP0 FRSD RD1/FRSD                
  CMP D1 RD1/FRSD                
    D2 RD2/FRTD                
  NPC PC4 PC4_D                
    I26 IR_D[I26]                
                       
REG_E   IR_E IR_D                
    RS_E RD1/FRSD                
    EXT_E EXTD                
    RT_E RD2/FRTD                
    PC8_E PC8_D                
                       
EXU MFRSE FRSESEL                  
    RS_E                  
    MTOE                  
    WTOE                  
  MFRTE FRTESEL                  
    RT_E                  
    MTOE                  
    WTOE                  
  MDU NUM1 RS_E/FRSE                
    NUM2 RT_E/FRTE RS_E/FRSE           MFNUM2 NUM2SEL
  ALU A RS_E/FRSE                
    B EXT_E RT_E/FRTE           MFB BSEL
    SHAMT IR_E[SH]                
                       
REG_M   IR_M IR_E                
    AO_M AO                
    RT_M RT_E/FRTE                
    PC8_M PC8_E                
    EXT_M EXT_E                
    HI_M HI                
    LO_M LO                
                       
MEU MFRTM FRTMSEL                  
    RT_M                  
    WTOM                  
  BEEXT AO_M1_0 AO_M[1:0]                
  DM DA AO_M                
    WD RT_M/FRTM                
    BE BE                
                       
REG_W   IR_W IR_M                
    RD_W RD                
    AO_W AO_M                
    PC8_W PC8_M                
    EXT_W EXT_M                
    HI_W HI_M                
    LO_W LO_M                
                       
RFU RDEXT RD_W RD_W                
    AO_W1_0 AO_W[1:0]                

四、结束

到此,简化五段式流水线CPU就已经设计完毕,Verilog代码就不放出来了,代码量庞大

说明一下,文中写的通用指令和非通用指令是自创的,没有严格定义,只是区分一下。

本文是对笔者学习思考CPU的一点总结,供复习所用,若能帮到读者就最好不过了。

感谢阅读,若有错误,请评论给出,万分感谢。

 

五段式流水线CPU

上一篇:Linux安装RocketMQ(需要jdk环境)


下一篇:jar在linux下永久运行