Transcript
Page 1: PICO のパイプライン化

PICO のパイプライン化

慶應義塾大学 理工学部天野

Page 2: PICO のパイプライン化

PICO の構成(前期の図を若干変更)

ALUir

InstructionMemory

DataMemory

we_ddataout

dadr

idata

iadr

pc

MUX MUX

MU

X

MU

X

MUX

ddatain

dest

src

adrA

adrB

regbrega

Expander ‘2’

op

op2

opop2

110001

regc

regfile

com

aluoutoutc

aluainalubin

Page 3: PICO のパイプライン化

パイプライン処理の設計• 大きな処理を一定の同じ大きさの小さな段階

(ステージ)に分解• それぞれのステージにそれぞれの処理装置を設

ける• 順にデータを流してやり、自分の処理が終わっ

たらすぐ次のステージに渡す• 流れ作業と基本は同じ• ステージ数を S とすると、理想の場合は性能は

S 倍– ステージの処理量が均等でないと、最も重いものに

律速される– ステージ間の受け渡しで大概ロスがある

Page 4: PICO のパイプライン化

パイプライン処理組合せ回路

ステージ1

ステージ2

ステージ3

ステージ4

ステージ1

ステージ2

ステージ3

ステージ4

ステージ1

ステージ2

ステージ3

ステージ4

ステージ1

ステージ2

ステージ3

ステージ4

ステージ1

ステージ2

ステージ3

ステージ4

時間

Page 5: PICO のパイプライン化

流れ作業(パイプライン処理 )   vs  多人数による並列処理

• S 人居れば最大 S 倍、これは同じ• 流れ作業は、各人がそのステージの処理だけで

きれば良い ⇔並列処理は、すべての人が全作業をする能力がなければならない

• 流れ作業は、各人がそのステージの処理をするのに必要な工具(リソース)を持てば良い⇔並列処理は、すべての人がすべての工具、場所を持つ必要がある

• このため、日常的な作業効率向上、工場のオートメーションなどもまずは流れ作業を導入する

Page 6: PICO のパイプライン化

状態遷移→ステージ

IF RF EX WB

結果を書き込む命令

それ以外:分岐、 ST など

ir に命令をフェッチ

レジスタ読み出しPC←PC+2

演算実行飛び先セットメモリからの読み書き込み

結果の格納

パイプライン化されていない設計が良くできていれば、それぞれの状態は遅延時間がほぼ均等に分割されているはず。このため、状態をそのままパイプラインのステージに割り当ててしまうのが基本的な設計手法

Page 7: PICO のパイプライン化

PICO のパイプライン構造

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

Page 8: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

LDLI r1,#1

Page 9: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

LDLI r2,#2 LDLI r1,#1

Page 10: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

LDLI r3,#3 LDLI r2,#2 LDLI r1,#1

1

Page 11: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

ADD r1,#2 LDLI r2,#2 LDLI r1,#1

21

LDLI r3,#3

Page 12: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

ADD r2,r2 LDLI r3,#3 LDLI r2,#2

32

ADD r1,#2

Page 13: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

ADD r2,r2 LDLI r3,#3

33

ADD r1,#2

Page 14: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

ADD r2,r2

43

ADD r1,#2

Page 15: PICO のパイプライン化

InstructionMemory

DataMemory

AL

U

2

IF RF EX WB

IFPC

RFPC

IFIR RFIRwadr

rega

regb

regc

a

bc

Imm.

ADD r2,r2

4

Page 16: PICO のパイプライン化

今回の verilog 記述

ppico16_test.v テストベンチmemory.v メモリppico16.v CPU

if_stage.v 命令フェッチrf_stage.v レジスタフェッチex_stagef.v (ex_stage.v) 実行

パイプライン化はしてあるData Hazard, Control Hazard の除去はしてない→ これは来週

合成対象

Page 17: PICO のパイプライン化

if_stage.vmodule if_stage (   clk,   reset_,   idata,   pcset,   badr,   ifpc,   ifir);

`include "pico.h"

input clk, reset_;

input [DataBus-1:0] idata; // Data from I-Cache

input pcset; // Branch Taken Signal

input [AddrBus-1:0] badr; // Branch Addr

output [AddrBus-1:0] ifpc; // PC ( IFstage output )

output [DataBus-1:0] ifir; // IR ( IFstage output )

reg [AddrBus-1:0] pc;

reg [DataBus-1:0] ir;

assign ifpc = pc;

assign ifir = ir;

always @( posedge clk ) begin

if ( reset_ == Enable_ ) begin

pc <= NULL;   ir <= NULL;

end else begin

ir <= idata;

if( pcset == Enable ) begin

pc <= badr; end

else begin

pc <= ifpc + 2; end

end

end

endmodule

pcset が1ならば分岐先アドレスのセット

そうでなければ+2(バイトアドレスなの

で)

Page 18: PICO のパイプライン化

pico.h コードの定義parameter Enable = 1'b1;parameter Disable = 1'b0;parameter Enable_ = 1'b0;parameter Disable_ = 1'b1;parameter AddrBus = 16;parameter DataBus = 16;parameter ComNum = 3;parameter RegNum = 3;parameter StateNum = 4;parameter MemSize = 32768;parameter Opcode = 5;parameter NULL = 16'h0000;

parameter ROP = 5'b00000;parameter LDLI = 5'b11100;parameter LDHI = 5'b11101;parameter BNEZ = 5'b01001;parameter BEQZ = 5'b01010;parameter JMP = 5'b01111;

parameter LD = 5'b01000;parameter ST = 5'b01001;parameter NOP = 5'b00000;

parameter THA = 3'b000;parameter THB = 3'b001;parameter ANDOP = 3'b010;parameter OROP = 3'b011;parameter SLOP = 3'b100;parameter SROP = 3'b101;parameter ADDOP = 3'b110;parameter SUBOP = 3'b111;

Page 19: PICO のパイプライン化

rf_stage.v  1 入出力と定義module rf_stage ( clk, reset_, ifir, ifpc, rwe, c, rwadr, rfpc, rfir, a, b, imm );`include "pico.h"input clk;input reset_;input [DataBus-1:0] ifir; // IR ( IF stage output )input [AddrBus-1:0] ifpc; // PC ( IF state output )input rwe; // Register Write Enable (c)input [DataBus-1:0] c; // Destination Datainput [RegNum-1:0] rwadr; // Destination Register Nooutput [DataBus-1:0] rfpc; // PC ( RFstage output )output [DataBus-1:0] rfir; // IR ( RFstage output )output [DataBus-1:0] a; // Source Data Aoutput [DataBus-1:0] b; // Source Data Boutput [DataBus-1:0] imm; // Immediate Data// Pipeline Registers

reg [DataBus-1:0] reg_a;reg [DataBus-1:0] reg_b;reg [DataBus-1:0] reg_im;reg [DataBus-1:0] reg_ir;reg [AddrBus-1:0] reg_pc;

// Outputs assign rfir = reg_ir;assign rfpc = reg_pc;assign a = reg_a;assign b = reg_b;assign imm = reg_im;

Page 20: PICO のパイプライン化

rf_stage.v  2 レジスタファイルとレジスタセット// Register File

wire [DataBus-1:0] dout1; // Register File Output for Source A (Rd)

wire [DataBus-1:0] dout2; // Register File Output for Source B (Rs)

regfile regfile ( // See regfile.v

.clk( clk ),

.adrA( ifir[10:8] ), // Read Address for Source A

.adrB( ifir[7:5] ), // Read Address for Source B

.adrC( rwadr ), // Write Address

.inc( c ), // Write Data

.outa( dout1 ),

.outb( dout2 ),

.rwe( rwe ) // Write Enable

);

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 <= dout1;   reg_b <= dout2;

reg_im <= {{8{ifir[7]}},ifir[7:0]}; end

end

endmodule

Page 21: PICO のパイプライン化

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 = rfile[adrA];

assign outb = rfile[adrB];

always @(posedge clk)

if (rwe) rfile[adrC] <= inc;

endmodule

 レジスタファイル本体

データ入力用 C ポートを独立

Page 22: PICO のパイプライン化

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] rfir; // IR ( RF stage output )input [DataBus-1:0] rfim; // Immediate Datainput [DataBus-1:0] a; // Source Data Ainput [DataBus-1:0] b; // Source Data Binput [DataBus-1:0] ddatain; // Read Data from D-Memoryinput [DataBus-1:0] rfpc; // PC (RF stage output )

output [DataBus-1:0] c; // Operation Resultoutput [DataBus-1:0] ddataout; // Write Data to D-Memoryoutput [AddrBus-1:0] address; // Address for D-Memory accessoutput [RegNum-1:0] rwadr; // Destination Register Nooutput dmwe; // D-Memory Write Enableoutput rwe; // Register Write Enableoutput pcset; // PC branch address set

Page 23: PICO のパイプライン化

ex_stage.v レジスタと簡単な論理部の接続// Pipeline Registers

reg [DataBus-1:0] reg_c;reg [RegNum-1:0] reg_rwadr;reg reg_rwe;reg pcsetr;

// Temporary Wirewire [DataBus-1:0] aluout; // ALU Outputwire [ComNum-1:0] aluope; // ALU Operationwire [DataBus-1:0] alu_ina, alu_inb;// Temporary Wire for ALU Source Bwire [DataBus-1:0] result; // Temporary Wire for resultswire rwen;wire pcsett;wire [Opcode-1:0] op, op2;wire [RegNum-1:0] dest;

// Output

assign rwadr = reg_rwadr;assign rwe = reg_rwe;assign c = reg_c;assign pcset = pcsetr;assign address = (op ==ROP) & (op2 == ST)? a : b;assign ddataout = b;assign op = rfir[15:11];assign dest = rfir[10:8];assign op2 = rfir[4:0];assign dmwe = ( op == ROP )& (op2 == ST) ? Enable : Disable;

Page 24: PICO のパイプライン化

ex_stage.v ALU

// ALU operationassign aluout = alu ( alu_ina, alu_inb, aluope );

// ALU ( ThrohghA, ThrohghB, And, Or, ShiftLeft, ShiftRight, Add, Sub )

function [DataBus-1:0] alu ;input [DataBus-1:0] a, b;input [ComNum-1:0] com;

case(com)THA: alu = a ;THB: alu = b ;ANDOP: alu = a & b;OROP: alu = a | b;SLOP: alu = a << b[3:0];SROP: alu = a >> b[3:0];ADDOP: alu = a + b;SUBOP: alu = a - b;endcase

endfunction

Page 25: PICO のパイプライン化

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) ;

やや見にくい

Page 26: PICO のパイプライン化

ex_stage f .v   function の利用// Intermediate wires

assign alu_ina = (op == BNEZ) | (op == BEQZ) ? rfpc: a;

function [DataBus-1:0] aluinb;

input [Opcode-1:0] ope;

input [7:0] imm;

input [DataBus-1:0] rfim, b;

if(ope[4:2]==3'b001) aluinb = rfim;

else

case(ope)

BEQZ, BNEZ, LDLI : aluinb = rfim;

ROP: aluinb = b;

LDHI: aluinb = {imm,8'b0};

default: aluinb = {8'b0,imm};

endcase

endfunction

assign alu_inb = aluinb(op,rfir[7:0],rfim,b);

function [ComNum-1:0] aluope;

input [Opcode-1:0] ope;

input [ComNum-1:0] func;

case (ope)

BEQZ, BNEZ : aluope = ADDOP;

LDLI, LDHI : aluope = THB;

ROP: aluope = func;

default: aluope = ope[ComNum-1:0];

endcase

endfunction

assign alu_ope = aluope(op,op2[ComNum-1:0]);

複雑な記述を function文で置き換える

簡単なものは今まで通り

Page 27: PICO のパイプライン化

ex_stage.v レジスタのセット

always @ ( posedge clk or negedge reset_ ) beginif ( reset_ == Enable_ ) begin

reg_c <= NULL;reg_rwadr <= NULL;reg_rwe <= Disable;pcsetr <= Disable;

end else begin// See Figure

reg_c <= result;reg_rwadr <= dest;reg_rwe <= rwen;pcsetr <= pcsett;

endend

Page 28: PICO のパイプライン化

ppico.v 入出力と接続信号線module ppico16 (   clk,   reset_,   idata,   ddatain,   iaddr,   daddr,   ddataout,   dmwe   );

`include "pico.h"

input clk, reset_;

input [DataBus-1:0] idata; // Instruction Data from I-Memory

input [DataBus-1:0] ddatain; // Read Data from D-Memory

output [AddrBus-1:0] iaddr; // Instruction Addr to I-Memory

output [AddrBus-1:0] daddr; // Data Addr to D-Memory

output [DataBus-1:0] ddataout; // Write Data to D-Memory

output dmwe; // D-Memory Write Enable

// IF & RF stage

wire pcset; // Branch Taken Signal

wire [AddrBus-1:0] ifpc; // PC ( IFstage output )

wire [DataBus-1:0] ifir; // IR ( IFstage output )

// RF stage

wire rwe; // Register Write Enable

wire rwen; // RWE for Next Clock Cycle

// RF & EX stage

wire [DataBus-1:0] a; // Source Data A

wire [DataBus-1:0] b; // Source Data B

wire [DataBus-1:0] c; // Destination Data

wire [DataBus-1:0] imm; // Immediate Data

wire [ComNum-1:0] rwadr; // Destination Register No

wire [DataBus-1:0] rfir; // IR ( RFstage output )

wire [AddrBus-1:0] rfpc; // PC ( RFstage output )

Page 29: PICO のパイプライン化

ppico.v ステージ間接続

assign iaddr = ifpc; // Fetch Addr to Instruction Memory

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 ), .c( c ), .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 ), .ddataout( ddataout ), .address( daddr ),.rwadr( rwadr ), .dmwe( dmwe ), .rwe( rwe ), .pcset(pcset)

);

Page 30: PICO のパイプライン化

test.prg11100_001_00000001 // LDLI r1,#111100_010_00000010 // LDLI r2,#211100_011_00000011 // LDLI r3,#300110_001_00000010 // ADDI r1#200000_010_010_00110 // ADD r2,r200000_000_00000000 // NOP00000_000_00000000 // NOP00000_000_00000000 // NOP00000_000_00000000 // NOP00000_000_00000000 // NOP

ikarus verilog で実行して gtkwave で波形を見てみよう

Page 31: PICO のパイプライン化

演習

• LDHI2 rd,#Xrd の上位 8 ビットに X をセットし、下位

8ビットは rd のままにする命令を付け加えてみよ。


Recommended