1 / 19

計算機構成 第 8 回 POCO の構造と Verilog 記述 テキスト第 5 章 - 第 6 章

計算機構成 第 8 回 POCO の構造と Verilog 記述 テキスト第 5 章 - 第 6 章. 情報工学科 天野英晴. 今日の目標は POCO の Verilog 記述の理解. 論理合成と性能評価に入る前に、 POCO のプログラム、 Verilog 記述について確認しておく 今までの POCO 関係の演習で出してないのがあれば、今日中にやっておこう フルスクラッチシリーズは後に機会を設けるので今日やらなくて良い. POCO の全体構成. ‘0’. 2:0. 00. Y. THB. S. 01. 1 0. pcsel. ext. ext11.

varen
Download Presentation

計算機構成 第 8 回 POCO の構造と Verilog 記述 テキスト第 5 章 - 第 6 章

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 計算機構成 第8回POCOの構造とVerilog記述テキスト第5章-第6章計算機構成 第8回POCOの構造とVerilog記述テキスト第5章-第6章 情報工学科 天野英晴

  2. 今日の目標はPOCOのVerilog記述の理解 • 論理合成と性能評価に入る前に、POCOのプログラム、Verilog記述について確認しておく • 今までのPOCO関係の演習で出してないのがあれば、今日中にやっておこう • フルスクラッチシリーズは後に機会を設けるので今日やらなくて良い

  3. POCOの全体構成 ‘0’ 2:0 00 Y THB S 01 10 pcsel ext ext11 00 01 ADD 10 A B alu_bsel + comsel zero 7:0 10:0 00 01 10 ‘1’ zero + ext ext0 7:0 rf_a rf_b 1 pcjr 0 aadr 10:8 badr 0 PC cadr 1 ‘7’ rf_c rwe rf_csel casel 00 01 10 7:5 idatain ddatain iaddr … … ddataout daddr 命令メモリ データメモリ we

  4. もう決まっちゃってる所 ‘0’ 2:0 00 Y THB S 01 10 pcsel ext ext11 00 01 ADD 10 rfile rfile_1(.clk(clk), .a(rf_a), .aadr(rd), .b(rf_b), .badr(rs), .c(rf_c), .cadr(cadr), .we(rwe)); A B alu_bsel + comsel zero 7:0 10:0 00 01 10 ‘1’ zero + ext ext0 7:0 rf_a rf_b 1 pcjr 0 assign {opcode,rd,rs,func} = idatain; assign imm=idatain[7:0]; aadr 10:8 badr 0 PC cadr 1 ‘7’ rf_c rwe rf_csel casel 00 01 10 assign ddataout = rf_a; assign daddr = rf_b; 7:5 idatain ddatain assign we = st_op; iaddr … … assign iaddr = pc; ddataout daddr 命令メモリ データメモリ we

  5. データパスの記述 assign com = (addi_op|laddiu_op) ? `ALU_ADD: (ldi_op|ldiu_op)?`ALU_LD: func[2:0]; ‘0’ 2:0 00 Y THB S 01 10 pcsel ext ext11 00 01 ADD 10 A B alu_bsel + comsel zero 7:0 10:0 00 01 10 ‘1’ zero + ext ext0 assign alu_b = (addi_op|addiu_op)? { {8{imm[7]}},imm} : (addiu_opldiu_op)? {8’b0,imm}: rf_b; 7:0 rf_a rf_b 1 pcjr 0 aadr 10:8 badr 0 PC cadr 1 ‘7’ rf_c rwe rf_csel casel 00 01 10 7:5 assign cadr = jal_op? 3’b111 : rd; idatain ddatain assign rwe = ld_op | alu_op | ldi_op | ldiu_op | addi_op | addiu_op..|jal_op; assign rf_c = ld_op ? ddatin: jal_op ? pc+1: alu_y; iaddr … … ddataout daddr 命令メモリ データメモリ we

  6. pc周辺 ‘0’ 2:0 00 Y THB S 01 10 pcsel ext ext11 00 01 ADD 10 always @(posedge clk or negedge rst_n) begin if(!rst_n) pc <= 0; else if ((bez_op & rf_a == 16’b0) | (bnz_op & rf_a != 16’b0) | (bpl_op & ~rf_a[15]) | (bmi_op & rf_a[15])) pc<=pc+{{8imm[7]}},imm}+1; else if (jmp_op| jal_op) pc <= pc +{{5{idatain[10]}},idatain[10:0]}}+1; else if(jr_op) pc <= rf_a; else pc<=pc+1; end A B alu_bsel + comsel zero 7:0 10:0 00 01 10 ‘1’ zero + ext ext0 7:0 rf_a rf_b 1 pcjr 0 aadr 10:8 badr 0 PC cadr 1 ‘7’ rf_c rwe rf_csel casel 00 01 10 7:5 idatain ddatain iaddr … … ddataout daddr 命令メモリ データメモリ we

  7. なぜPC周辺のみ図とマッチしないか? • always文の中はif文やcase文が使えて便利なのでなるべく中で判断までやってしまう • 他の部分でも、マルチプレクサの制御信号などは明示的に書いていない →今回の書き方は、テキストの図に忠実に、しかし以下を例外とした マルチプレクサの制御信号は明示的に書かない → 書いても面倒なだけなので、、 レジスタに対する書き込み制御は always文内に書く → 無理に外に出すより読みやすいので、、

  8. pocoz.v:図に完全に忠実に書いた記述(decode.vの後半)pocoz.v:図に完全に忠実に書いた記述(decode.vの後半) assign we = st_op; assign rwe = ld_op | alu_op | ldi_op | ldiu_op | addi_op | addiu_op | ldhi_op | jal_op ; assign rf_csel = ld_op ? 2'b01 : jal_op ? 2'b10: 2'b00 ; assign alu_bsel = (addi_op | ldi_op) ? 2'b01 : (addiu_op | ldiu_op) ? 2'b10 : ldhi_op? 2'b11 : 2'b00; assign comsel = (addi_op | addiu_op) ? 2'b01 : (ldi_op | ldiu_op | ldhi_op) ? 2'b10 : 2'b00; assign casel = jal_op; assign pcjr = jr_op; assign pcsel = (bez_op & zero | bnz_op & ~zero | bpl_op & ~mi | bmi_op & mi) ? 2'b01 : jmp_op | jal_op ? 2'b10 : 2'b00; endmodule

  9. pocoz.v:図に完全に忠実に書いた記述 モジュール decode.v include "def.h" module decode( input [`OPCODE_W-1:0] opcode, input [`OPCODE_W-1:0] func, input zero, mi, output [1:0] alu_bsel, comsel, rf_csel, pcsel, output we, rwe, casel, pcjr); wire st_op, bez_op, bnz_op, bmi_op, bpl_op, addi_op, ld_op, alu_op; wire ldi_op, ldiu_op, ldhi_op, addiu_op, jmp_op, jal_op, jr_op, jalr_op; assign st_op = (opcode == `OP_REG) & (func == `F_ST); assign ld_op = (opcode == `OP_REG) & (func == `F_LD); assign jr_op = (opcode == `OP_REG) & (func == `F_JR); assign jalr_op = (opcode == `OP_REG) & (func == `F_JALR); assign alu_op = (opcode == `OP_REG) & (func[4:3] == 2'b00); assign ldi_op = (opcode == `OP_LDI); assign ldiu_op = (opcode == `OP_LDIU); assign addi_op = (opcode == `OP_ADDI); assign addiu_op = (opcode == `OP_ADDIU); assign ldhi_op = (opcode == `OP_LDHI); assign bez_op = (opcode == `OP_BEZ); assign bnz_op = (opcode == `OP_BNZ); assign bpl_op = (opcode == `OP_BPL); assign bmi_op = (opcode == `OP_BMI); assign jmp_op = (opcode == `OP_JMP); assign jal_op = (opcode == `OP_JAL);

  10. pocoz.vの本体 assign {opcode, rd, rs, func} = idatain; assign imm = idatain[`IMM_W-1:0]; decode decode_1 (.opcode(opcode), .func(func), .zero(zero), .mi(mi), .alu_bsel(alu_bsel), .comsel(comsel), .rf_csel(rf_csel), .pcsel(pcsel), .we(we), .rwe(rwe), .casel(casel), .pcjr(pcjr)); assign alu_b = alu_bsel==2'b01 ? {{8{imm[7]}},imm} : alu_bsel == 2'b10 ? {8'b0,imm} : alu_bsel == 2'b11 ? {imm, 8'b0} : rf_b; assign com = comsel==2'b01 ? `ALU_ADD: comsel==2'b10 ? `ALU_THB: func[`SEL_W-1:0]; assign rf_c = rf_csel==2'b01 ? ddatain : rf_csel==2'b10 ? pc+1 : alu_y; assign cadr = casel ? 3'b111 : rd; alu alu_1(.a(rf_a), .b(alu_b), .s(com), .y(alu_y)); rfile rfile_1(.clk(clk), .a(rf_a), .aadr(rd), .b(rf_b), .badr(rs), .c(rf_c), .cadr(cadr), .we(rwe)); マルチプレクサの記述が 完全に図とマッチしている

  11. pocoz.vの本体 assign zero = rf_a == 16'b0; assign mi = rf_a[15]; assign pcadd = pcsel == 2'b01 ? {{8{imm[7]}},imm} : pcsel == 2'b10 ? {{5{idatain[10]}},idatain[10:0]}: 0; assign pcnext = pcjr ? rf_a: pc+pcadd+1; always @(posedge clk or negedge rst_n) begin if(!rst_n) pc <= 0; else pc <= pcnext; end pc周辺も分離して書くことは可能だが見やすいとはいえない

  12. 今回の記述の特徴 • 出力信号依存の書き方 • 全ての出力を分離して記述している モジュールA モジュールA・B モジュールB まとめて書ければ可読性が向上する (かもしれない) AとBに共通性があっても 分離して書かなければならない

  13. function文 • うまく使うと非常に分かりやすく書ける • しかし、落とし穴がある • 変数スコープが曖昧 • 代入文は前後関係が生じる • 出力をまとめる必要がある • この授業では使わないが興味があればどうぞ

  14. pocof.vを参照 function [7:0] decode( input [`OPCODE_W-1:0] op, input [`OPCODE_W-1:0] fu); reg [1:0] alu_bsel, comsel, rf_csel; reg rwe, casel; begin alu_bsel = 2'b00; comsel = 2'b00; rf_csel = 2'b00; rwe = 1'b0; casel = 1'b0; case (op) `OP_REG: if(fu==`F_LD) begin rwe = 1'b1; rf_csel = 2'b01; end else if(fu[4:3] == 2'b00) rwe = 1'b1; … 内部変数をregで定義 デフォルトの値を最初に書いてしまう その後は後に書いたものが前のを打ち消す

  15. pocof.vを参照 `OP_LDI: begin rwe = 1'b1; comsel = 2'b10; alu_bsel = 2'b01; end `OP_LDIU: begin rwe = 1'b1; comsel = 2'b10; alu_bsel = 2'b10; end `OP_ADDI: begin rwe = 1'b1; comsel = 2'b01; alu_bsel = 2'b01; end `OP_ADDIU: begin rwe = 1'b1; comsel = 2'b01; alu_bsel = 2'b10; end `OP_LDHI: begin rwe = 1'b1; comsel = 2'b10; alu_bsel = 2'b11; end `OP_JAL: begin rwe = 1'b1; casel = 1'b1; rf_csel = 2'b10; end endcase decode = {alu_bsel, comsel, rf_csel, rwe, casel}; end endfunction 命令毎に特徴的な出力の動きをまとめて書ける 最後に全体の信号をくっつけて出力

  16. pocof.vを参照 `OP_LDI: begin rwe = 1'b1; comsel = 2'b10; alu_bsel = 2'b01; end `OP_LDIU: begin rwe = 1'b1; comsel = 2'b10; alu_bsel = 2'b10; end `OP_ADDI: begin rwe = 1'b1; comsel = 2'b01; alu_bsel = 2'b01; end `OP_ADDIU: begin rwe = 1'b1; comsel = 2'b01; alu_bsel = 2'b10; end `OP_LDHI: begin rwe = 1'b1; comsel = 2'b10; alu_bsel = 2'b11; end `OP_JAL: begin rwe = 1'b1; casel = 1'b1; rf_csel = 2'b10; end endcase decode = {alu_bsel, comsel, rf_csel, rwe, casel}; end endfunction 命令毎に特徴的な出力の動きをまとめて書ける 最後に全体の信号をくっつけて出力

  17. pocof.vの本体 assign {alu_bsel, comsel, rf_csel, rwe, casel} = decode(opcode,func); • always文をレジスタ以外にも使う書き方でも 同様の多入力、多出力的な書き方が可能 • 一時、論理合成の効率が良かったためFPGAベンダーが推奨したため、広がった • しかし入門者は使わないほうが良い 外部の信号線に 関係付けを行う

  18. ディスプレースメント付きレジスタ間接指定 LDD rd,n(ra): rd ←(n+ra) 01110 ddd aaa nnnnn STD rd,n(ra): (n+ra) ← rd 01111 ddd aaa nnnnn • レジスタ間接指定の一種 • レジスタとn(ディスプレースメント)を加えた値が実効アドレスになる • ループアンローリングができるので、RISCではこの方式が一般的 • POCOの今までのタイプと異なる

  19. 演習 LDDとSTDを実装せよ。 • eximem.datにテストプログラムがあるのでこれをimem.datにコピーして用いよ • shapaは対応していないので注意! • def.hには加えてある • 変更箇所が多く構造とVerilog記述の関係を良く理解しないとできない • gtkwaveを使って論理的にバグを追い詰めること

More Related