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

Slides:



Advertisements
Similar presentations
C 言語講座 第 7 回 ポインター. メモリとアドレス(ポインターの前 に) コンピュータのメモリには 1 バイトずつ 0 番地、 1 番地、 2 番地・・・というように 住所が割り当てられている この住所をアドレスという。 メモリはデータをしまうもので それを引き出すためには メモリに番号(アドレス)を振っておけばよいな.
Advertisements

CPU設計と パイプライン.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
計算機工学特論A 10/17  テキスト内容 1.1~1.4.
VLSI設計論第4回 アキュムレータマシンと 仮遅延シミュレーション
5.3 各種カウンタ 平木.
CPU実験 第1回中間発表 4班 瀬沼、高橋、津田、富山、張本.
数値計算及び実習 第3回 プログラミングの基礎(1).
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
Verilog HDL 12月21日(月).
プログラミング基礎I(再) 山元進.
計算機構成 第7回 サブルーチンコールとスタック テキストp85-90
2006年度 計算機システム演習 第4回 2005年5月19日.
コンピュータ工学基礎 パイプラインハザード テキスト9章 115~124
条件式 (Conditional Expressions)
VLSI設計論第2回 組み合わせ回路の記述と 論理シミュレーション
4.2.2 4to1セレクタ.
計算機構成 第9回 POCOの性能評価と論理合成 テキスト7章
シグナル通信 普通の割込みとソフトウェア割込み ソフトウェア割込みとシグナル キーボードからのシグナル 例外 (exception)
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
2005年11月2日(木) 計算機工学論A 修士1年 No, 堀江準.
第7回 2006/6/12.
計算機工学特論A 第4回 論理合成 山越研究室 増山 知東 2007年11月7日 .
ハードウェア記述言語による 論理回路設計とFPGAへの実装 2
計算機構成 第1回 ガイダンス VerilogHDLのシミュレーション環境
第7回 条件による繰り返し.
・ディジタル回路とクロック ・プロセッサアーキテクチャ ・例外処理 ・パイプライン ・ハザード
図書館職員のための アプリケーション開発講習会
勉強会その3    2016/5/1 10 8分35秒 データの表現 演算.
最適化の方法 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第11章.
コンピュータ系実験Ⅲ 「ワンチップマイコンの応用」 第1週目 アセンブリ言語講座
R8C/Tiny I/Oポートの仕組み.
04: 式・条件分岐 (if) C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
第7回 条件による繰り返し.
第6回 6/4/2011 状態遷移回路とシングルサイクルCPU設計
計算機構成 第6回 分岐命令とプログラムの実行 テキスト第5章
第二部  回路記述編 第3章 文法概略と基本記述スタイル 3.1 文法を少々 3.1.1~3.1.3.
ディジタル回路の設計と CADによるシステム設計
計算機構成 第2回 ALUと組み合わせ回路の記述
計算機構成 第3回 データパス:計算をするところ テキスト14‐19、29‐35
計算機構成 第4回 アキュムレータマシン テキスト第3章
VLSI設計論第3回 順序回路の記述と論理合成
08. メモリ非曖昧化 五島 正裕.
計算機構成 第11回 マルチサイクルCPU 慶應大学 天野英晴.
計算機構成 第5回 RISCの命令セットアーキテクチャ テキスト第4章
情報工学科 3年生対象 専門科目 システムプログラミング 第4回 シェルスクリプト 情報工学科 篠埜 功.
制御文の役割と種類 IF文 論理式と関係演算子 GO TO文
コンピュータアーキテクチャ 第 10 回.
09. メモリ・ディスアンビギュエーション 五島 正裕.
坂井 修一 東京大学 大学院 情報理工学系研究科 電子情報学専攻 東京大学 工学部 電気工学科
Ibaraki Univ. Dept of Electrical & Electronic Eng.
基礎プログラミング演習 第6回.
計算機工学特論 スライド 電気電子工学専攻 修士1年 弓仲研究室 河西良介
コンピュータアーキテクチャ 第 10 回.
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
コンピュータアーキテクチャ 第 2 回.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
同期処理のモジュール化を 可能にする アスペクト指向言語
コンピュータアーキテクチャ 第 2 回.
ウェブデザイン演習 第6回.
計算機アーキテクチャ1 (計算機構成論(再)) 第二回 命令の種類と形式
第5回 プログラミングⅡ 第5回
計算機工学論A P46~P49 クロック、リセット、クロック・イネーブルのセット 状態の出力値の指定 ステート・トランジョンの指定
コンピュータ工学基礎 マルチサイクル化とパイプライン化 テキスト9章 115~124
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
プログラミング演習I 2003年6月11日(第9回) 木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
情報システム基盤学基礎1 コンピュータアーキテクチャ編
Presentation transcript:

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

今日の目標はPOCOのVerilog記述の理解 フルスクラッチシリーズは後に機会を設けるので今日やらなくて良い

POCOの全体構成 Y S ext ext11 A B + + ext ext0 PC … … 命令メモリ データメモリ ‘0’ 00 01 2:0 00 Y THB 01 S 00 01 10 pcsel ext ext11 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 aadr 10:8 badr PC cadr 1 ‘7’ rf_c rwe rf_csel casel 00 01 10 7:5 idatain ddatain iaddr … … ddataout daddr 命令メモリ データメモリ we

もう決まっちゃってる所 Y S ext ext11 A B + + ext ext0 PC assign we = st_op; … … ‘0’ 2:0 00 Y THB 01 S 00 01 10 pcsel ext ext11 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 assign {opcode,rd,rs,func} = idatain; assign imm=idatain[7:0]; aadr 10:8 badr 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

データパスの記述 Y S ext ext11 A B + + ext ext0 assign com = (addi_op|laddiu_op) ? `ALU_ADD: (ldi_op|ldiu_op)?`ALU_LD: func[2:0]; ‘0’ 2:0 00 Y THB 01 S 00 01 10 pcsel ext ext11 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 aadr 10:8 badr 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

pc周辺 Y S ext ext11 A B + + ext ext0 PC … … 命令メモリ データメモリ ‘0’ 00 01 10 2:0 00 Y THB 01 S 00 01 10 pcsel ext ext11 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 aadr 10:8 badr PC cadr 1 ‘7’ rf_c rwe rf_csel casel 00 01 10 7:5 idatain ddatain iaddr … … ddataout daddr 命令メモリ データメモリ we

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

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

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

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)); マルチプレクサの記述が 完全に図とマッチしている

pc周辺も分離して書くことは可能だが見やすいとはいえない 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周辺も分離して書くことは可能だが見やすいとはいえない

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

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

pocof.vを参照 内部変数をregで定義 デフォルトの値を最初に書いてしまう その後は後に書いたものが前のを打ち消す 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) … 内部変数をregで定義 デフォルトの値を最初に書いてしまう その後は後に書いたものが前のを打ち消す

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

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

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

ディスプレースメント付きレジスタ 間接指定 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の今までのタイプと異なる

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