流水线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的一点总结,供复习所用,若能帮到读者就最好不过了。

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