自己动手写CPU_5_5.1流水线数据相关问题

5.1 流水线数据相关问题

流水线中的相关性

流水线中经常有一些被称为“相关”的情况发生,使得指令序列中下一条指令无法按照设计的时钟周期执行,这些“相关”会降低流水线的性能。流水线中的相关性分为以下三种类型:

  1. 结构相关

    在指令执行过程中,由于硬件资源满足不了指令执行的要求,而产生硬件资源冲突。例如:在某个流水线执行中,CPU既要访问存储器,又要取出指令,这样就发生存储器访问冲突,产生结构相关。

  2. 数据相关

    在流水线执行的几条指令中,一条指令依赖于前面指令的执行结果。

  3. 控制相关

    流水线中的分支指令或者其他需要修改PC的指令造成的相关。

流水线的数据相关

流水线数据相关分为三种情况(假设指令i先执行,j后执行。i -> j):

  1. RAW(Read After Write)

    在指令i将数据写入寄存器后,指令j才能从这个寄存器中读取数据。如果指令j在指令i写入寄存器之前读取该寄存器将得到不正确的数据。

  2. WAR(Write After Read)

    在指令i从寄存器读取后,指令j才能写入这个寄存器。如果指令i在指令j写入寄存器之后读取该寄存器将得到不正确的数据。

  3. WAW(Write After Write)

    指令的写入顺序需要得到保证,否则会发生不同步。

数据相关实例

  相邻指令间的数据相关

  相邻两条指令间的指令存在数据相关

   相隔两条指令的数据相关

其中相隔2条指令的数据相关已经在regfile中解决,代码截取注解如下:

/**
        实现了端口1读操作
    **/
	always @ (*) begin
		if(rst == `RstEnable) begin									// 若rst使能,那么将会输出数据0。
			  rdata1 <= `ZeroWord;
	  end else if(raddr1 == `RegNumLog2'h0) begin					// 若raddr1引用$0 reg,那么直接输出0。
	  		rdata1 <= `ZeroWord;
	  end else if((raddr1 == waddr) && (we == `WriteEnable) 		// 若要读取的寄存器是要写入的数据的寄存器,那么直接复制,解决RAW问题
	  	            && (re1 == `ReadEnable)) begin
	  	  rdata1 <= wdata;
	  end else if(re1 == `ReadEnable) begin							// 读取使能且读取地址有效非特殊地址,复制相应数据。
	      rdata1 <= regs[raddr1];
	  end else begin
	      rdata1 <= `ZeroWord;										//无效情况,输出0
	  end
	end
	

对于相邻指令之间存在的数据相关、相隔1条指令的指令间存在数据相关这两种情况,有如下解决方法:

  1. 插入暂停周期:当检测到相关时,在流水线中插入一些暂停周期。

   2. 编译器调度:编译器检测到相关后,在不改变程序的语义下,调整部分指令的执行顺序。

  3. 数据前推:将计算结果从其产生处直接送到其他指令所需要处或所有需要的功能单元处,避免流水线暂停。

猜你喜欢

转载自www.cnblogs.com/ycc1997/p/12181082.html
今日推荐