Upload
irving
View
57
Download
3
Embed Size (px)
DESCRIPTION
PICO のパイプライン化. 慶應義塾大学 理工学部 天野. MUX. MUX. MUX. MUX. MUX. PICO の構成(前期の図を若干変更). regc. aluout. outc. op. pc. ir. com. op2. ALU. op. 110 001. alubin. aluain. Expander. ‘2’. regb. op2. rega. dest. adrA. src. adrB. idata. regfile. ddatain. ddataout. we_. Instruction - PowerPoint PPT Presentation
Citation preview
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
パイプライン処理の設計• 大きな処理を一定の同じ大きさの小さな段階
(ステージ)に分解• それぞれのステージにそれぞれの処理装置を設
ける• 順にデータを流してやり、自分の処理が終わっ
たらすぐ次のステージに渡す• 流れ作業と基本は同じ• ステージ数を S とすると、理想の場合は性能は
S 倍– ステージの処理量が均等でないと、最も重いものに
律速される– ステージ間の受け渡しで大概ロスがある
パイプライン処理組合せ回路
ステージ1
ステージ2
ステージ3
ステージ4
ステージ1
ステージ2
ステージ3
ステージ4
ステージ1
ステージ2
ステージ3
ステージ4
ステージ1
ステージ2
ステージ3
ステージ4
ステージ1
ステージ2
ステージ3
ステージ4
時間
流れ作業(パイプライン処理 ) vs 多人数による並列処理
• S 人居れば最大 S 倍、これは同じ• 流れ作業は、各人がそのステージの処理だけで
きれば良い ⇔並列処理は、すべての人が全作業をする能力がなければならない
• 流れ作業は、各人がそのステージの処理をするのに必要な工具(リソース)を持てば良い⇔並列処理は、すべての人がすべての工具、場所を持つ必要がある
• このため、日常的な作業効率向上、工場のオートメーションなどもまずは流れ作業を導入する
状態遷移→ステージ
IF RF EX WB
結果を書き込む命令
それ以外:分岐、 ST など
ir に命令をフェッチ
レジスタ読み出しPC←PC+2
演算実行飛び先セットメモリからの読み書き込み
結果の格納
パイプライン化されていない設計が良くできていれば、それぞれの状態は遅延時間がほぼ均等に分割されているはず。このため、状態をそのままパイプラインのステージに割り当ててしまうのが基本的な設計手法
PICO のパイプライン構造
InstructionMemory
+
DataMemory
AL
U
2
IF RF EX WB
IFPC
RFPC
IFIR RFIRwadr
rega
regb
regc
a
bc
Imm.
InstructionMemory
+
DataMemory
AL
U
2
IF RF EX WB
IFPC
RFPC
IFIR RFIRwadr
rega
regb
regc
a
bc
Imm.
LDLI r1,#1
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
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
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
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
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
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
InstructionMemory
+
DataMemory
AL
U
2
IF RF EX WB
IFPC
RFPC
IFIR RFIRwadr
rega
regb
regc
a
bc
Imm.
ADD r2,r2
4
今回の 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 の除去はしてない→ これは来週
合成対象
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(バイトアドレスなの
で)
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;
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;
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
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 ポートを独立
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
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;
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
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) ;
やや見にくい
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文で置き換える
簡単なものは今まで通り
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
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 )
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)
);
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 で波形を見てみよう
演習
• LDHI2 rd,#Xrd の上位 8 ビットに X をセットし、下位
8ビットは rd のままにする命令を付け加えてみよ。