データハザードとその解決法 慶應義塾大学 理工学部 天野 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% – 分岐命令の影響については無視
© Copyright 2025 ExpyDoc