計算機構成: トップダウンの解説

データハザードとその解決法
慶應義塾大学 理工学部
天野
PICOのパイプライン構造
IF
RF
RFPC
WB
EX
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
パイプラインハザード
• パイプライン動作を阻害するもの
• 構造(Structural) ハザード
– 各ステージで共有資源がある場合に生じる
– 資源を複製すれば解決可能→コストと性能のトレードオフの問題
• データハザード
– パイプライン中で並列に実行される複数の命令間のデータの依存性
に起因するハザード
– 先行命令の結果が書き込まれる前に後続命令がデータを読んでしま
う
• 制御(Control)ハザード
– 分岐命令に起因するハザード
– 次に実行する命令がわからなくなる
メモリを共有する場合の構造ハザード
IF
RF
RFPC
WB
EX
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Imm.
RFIR
統合
Memory
wadr
構造ハザードによるパイプライン
ストール
LD/ST命令 ステージステージステージステージ
2
3
4
1
ステージステージステージステージ
2
3
4
1
ステージステージステージステージ
2
3
4
1
ステージステージステージステージ
命令
2
3
4
1
フェッチ
ステージステージステージステージ
ができ
2
3
4
1
ない
ストールするパイプラインのCPI = 理想CPI + ダメージの確率×ダメージサイクル
データハザード
• 先行命令が書き込む前に後続命令がレジス
タファイルからデータを読み込んでしまう。
• RAW(Read After Write)ハザード
– WAR(Write After Read)ハザード
– WAW(Write After Write)ハザードもあるが今回
は関係ない
• ストールすると性能低下が大きい
• 解決するにはフォワーディングを用いる
ADDI r3,#2
LD r3,(r1)
IF
RF
LDLI r1,#0
RFPC
EX
WB
a
2
ALU
+
rega
IFPC
0
regc
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
ST (r1),r3
ADDI r3,#2
IF
RF
LD r3,(r1)
RFPC
EX
LDLI r1,#0
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
0
ST (r1),r3
IF
RF
ADDI r3,#2
RFPC
EX
LD r3,(r1)
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
U
パイプラインストール
LD r3,(r1)
NOP
IF
RF
LDLI r1,#0
NOP
RFPC
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
0
NOP
LD r3,(r1)
IF
RF
NOP
RFPC
NOP
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
レジスタファイルのフォワーディング
IF
RF
RFPC
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
ストールサイクルの減少
NOP
LD r3,(r1)
IF
RF
LDLI r1,#0
NOP
RFPC
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
0
ALUからのフォワーディング
IF
RF
RFPC
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
ADDI r3,#2
LD r3,(r1)
IF
RF
LDLI r1,#0
RFPC
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
ST (r1),r3
ADDI r3,#2
IF
RF
RFPC
LD r3,(r1)
LDLI r1,#0
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
ST (r1),r3
IF
RF
ADDI r3,#2
RFPC
EX
WB
a
2
regc
ALU
+
rega
IFPC
regb
c
b
IFIR
Instruction
Memory
Imm.
wadr
RFIR
Data
Memory
LD r3,(r1)
今回のverilog記述
ppico16_test.v テストベンチ
memory.v メモリ
ppico16.v CPU
変更
変更
if_stage.v 命令フェッチ
変更
rf_stage.v レジスタフェッチ
ex_stagef.v (ex_stage.v) 実行
変更はrf_stage, ex_stageのみ
rf_stage.v 1 レジスタファイル周辺
wire [DataBus-1:0]
dout1;
// Register File Output for Source A (Rd)
wire [DataBus-1:0]
fout1;
// Forwarding Source A
wire [DataBus-1:0]
dout2;
// Register File Output for Source B (Rs)
wire [DataBus-1:0]
fout2;
// Forwarding Source B
wire [RegNum-1:0]
proc_dest, foll_dest; // Destination registers
wire [RegNum-1:0]
proc_src, foll_src;
// Source registers
assignfoll_dest = ifir[10:8];
assignproc_dest = reg_ir[10:8];
assignfoll_src = ifir[7:5];
assignproc_src = reg_ir[7:5];
regfile regfile ( .clk( clk ), .adrA( foll_dest ),
.adrB( foll_src),
.adrC( rwadr ), .inc( c ), .outa( dout1 ),
.outb( dout2 ), .rwe( rwe )
);
// Outputs
assignrfir = reg_ir;
assignrfpc = reg_pc;
assigna = reg_a;
assignb = reg_b;
assignimm = reg_im;
assignfout1 = rwen & (proc_dest == foll_dest) ? result : dout1;
assignfout2 = rwen & (proc_dest == foll_src) ? result : dout2;
rf_stage.v 2 レジスタセット
always @( posedge clk ) begin
if ( reset_ == Enable_ ) begin
reg_ir <= NULL;
reg_pc <= NULL;
reg_a <= NULL;
reg_b <= NULL; end
else begin
reg_ir
<= ifir;
reg_pc
<= ifpc;
reg_a <= fout1;
reg_b <= fout2;
reg_im
<= {{8{ifir[7]}},ifir[7:0]}; end
end
レジスタファイル本体
module regfile (clk, adrA, adrB, adrC, inc, outa, outb, rwe);
`include "pico.h"
input clk;
input [RegNum-1:0] adrA, adrB, adrC;
input [DataBus-1:0] inc;
output [DataBus-1:0] outa, outb;
input rwe;
reg [DataBus-1:0] rfile [0:7];
assign outa = (adrA==adrC) & rwe ? inc : rfile[adrA];
assign outb = (adrB==adrC) & rwe ? inc : rfile[adrB];
always @(posedge clk)
if (rwe) rfile[adrC] <= inc;
endmodule
ex_stage.v 入出力
module ex_stage (clk, reset_, rfir, rfim, a, b, ddatain, rfpc, c, ddataout,
address, rwadr, dmwe, rwe, pcset );
`include "pico.h"
input
clk;
input
reset_;
input
[DataBus-1:0]
input
[DataBus-1:0]
input
[DataBus-1:0]
input
[DataBus-1:0]
input
[DataBus-1:0]
input
[DataBus-1:0]
rfir;
rfim;
a;
b;
ddatain;
rfpc;
output
output
c;
result;
[DataBus-1:0]
[DataBus-1:0]
output
[DataBus-1:0]
output
[AddrBus-1:0]
output
[RegNum-1:0]
output
dmwe;
output
rwe;
output
rwen;
output pcset;
// IR ( RF stage output )
// Immediate Data
// Source Data A
// Source Data B
// Read Data from D-Memory
// PC (RF stage output )
// Operation Result
// Operation Result
ddataout; // Write Data to D-Memory
address; // Address for D-Memory access
rwadr;
// Destination Register No
// D-Memory Write Enable
// Register Write Enable
// PC branch address set
ex_stage.v ALU周辺中間信号線
// Intermediate wires
assign alu_ina = (op == BNEZ) | (op == BEQZ) ? rfpc: a;
assign alu_inb = // Sign extended immediate
( rfir[15:13] == 3‘b001 ) | (op == BEQZ) | (op == BNEZ) | (op == LDLI) ? rfim:
(op == ROP) ? b:
(op == LDHI) ? {rfir[7:0],8'b0}: // LDHI
{8'b0,rfir[7:0]}; // Sign unextended immediate
assign aluope = // Braches
(op == BEQZ) | (op == BNEZ) ? ADDOP:
(op == LDLI) | (op == LDHI) ? THB: // LDLI, LDHI
(op == ROP) ? rfir[2:0]: rfir[13:11];
信号を外に出すだけ
assign rwen = // Disable when Braches or ST
(op == BEQZ) | (op == BNEZ) |
((op == ROP) & (op2 == ST)) |
((op == ROP) & (op2 == NOP)) ? Disable : Enable;
assign result = // when LD datain
((op == ROP) & (op2 == LD)) ? ddatain : aluout;
assign pcsett = ( op == BEQZ )& (a==16'h0000) |
( op == BNEZ )& (a!=16'h0000) ;
ppico.v ステージ間接続
assign iaddr = ifpc;
Memory
// Fetch Addr to Instruction
if_stage if_stage ( .clk( clk ), .reset_( reset_ ), .idata( idata ), .pcset( pcset ),
.badr( c ), .ifpc( ifpc ), .ifir( ifir )
);
rf_stage rf_stage ( .clk( clk ), .reset_( reset_ ), .ifir( ifir ), .ifpc( ifpc ),
.rwe( rwe ), .rwen(rwen), .c( c ), .result(result),
.rwadr( rwadr ), .rfpc( rfpc ), .rfir( rfir ),
.a( a ), .b( b ), .imm( imm )
);
ex_stage ex_stage ( .clk( clk ) .reset_( reset_ ),.rfir( rfir ), .a( a ), .b( b ),
.rfim( imm ), .ddatain( ddatain ), .rfpc(rfpc),
.c( c ), .result(result), .ddataout( ddataout ), .address( daddr ),
.rwadr( rwadr ), .dmwe( dmwe ), .rwe( rwe ), .rwen(rwen), .pcset(pcset)
);
演習
• fowardingをやらない場合、以下の仮定
でCPIがどうなるか計算せよ
– 理想のCPIは1
– 先行命令の結果を次の命令が利用する可
能性が70%
– 分岐命令の影響については無視