KUE-CHIP2全体のSFL記述が完成したら,SECONDSを用いてその動作を確かめて みます.ここでは,KUE-CHIP2のプログラムを実際に動かしてみて,結果が正 しいかどうかを見て判断します.そのためには,KUE-CHIP2本体とメモリなど が搭載されたボードのようなものを用意する必要がありますので,まずはこれ をSFLのモジュールboardとして記述します. リスト5.1 に一例を示します.
モジュールboardでは,モジュールkuechip2をサブモジュールとして使用し ますので,ここでkuechip2のサブモジュールタイプ宣言を行う必要があります. モジュールkuechip2は,制御入力端子startを持ちますが,仮引数はありませ んので,仮引数の定義に関しては何も書きません.従って,外部端子の定義の みを書きます.
次に,KUE-CHIP2が使用する512バイトのメモリを,機能回路r512_8として 設計します.メモリは,機能回路においてのみ構成要素として記述できるから です.
制御入力端子としては,読み出し,書き込みを行うためのread, writeを用 意します.データ入力端子としては,アドレスを示すadrs,書き込みデータを 入力するdinを用意します.データ出力端子としては,読み出しデータを出力 するdoutを用意します.
SFLではmemというキーワードでメモリを表します.ここでは,cellという 名前の512バイト(8ビットを1バイトとする)のメモリを宣言しています.
次に,制御入力端子の仮引数の定義を行います.制御入力端子の仮引数の 定義は,モジュールの場合,サブモジュールタイプの宣言部で行いましたが, 機能回路の場合は,内容の定義とインタフェースの宣言を同時に記述するので, ここで行います.readの仮引数はadrs,writeの仮引数はadrsとdinとします.
あとは,制御入力端子readとwriteの動作を記述します.cell[adrs]で, cellというメモリのadrs番地を示します.
以上で,kuechip2とメモリr512_8のSFL記述ができましたので,IBUF, IBUF_FLAG, OBUF, OBUF_FLAGと共に,これらに関係を持たせましょう.モジュー ルboardがその役目を果たします.
モジュールboardには外部端子を用意しません.SECONDSでは,メモリに直 接値を書き込んだり,kuechip2の端子に値を設定できるからです.
従って,構成要素の定義から始めます.モジュールboardは,モジュール kuechip2, 機能回路r512_8を,サブモジュール名cpu, memとして利用します. また,ibuf, ibuf_flag, obuf, obuf_flagは,reg_wrで実現することにします.
あとは,動作の記述です.初めのpar{ }で囲まれた部分には,常に行われ る動作が記述されています.つまり,ibuf_flag, obuf_flagの値は,常にcpu のibuf_flg_in, obuf_flg_inに供給されるということです.42行目から49行目 には,cpuの制御出力端子の動作の定義が行われています.以前にも申しまし たが,あるモジュールの制御出力端子の動作の定義は,このように,そのモジュー ルの外側で行われます.
以上で,リスト5.1の説明は終わりです.リスト5.1のSFL記述はboard.sfl というファイルに格納することにします.
[リスト 5.1] 動作確認のためのSFL記述(board.sfl) [TOP]1: /** board : KUE-CHIP2 Educational Board **/ 2: /** This description is just for simulation using SECONDS **/ 3: 4: submod_type kuechip2 { 5: /** external pins **/ 6: instrin start; 7: input dbi<8>; 8: input ibuf_flg_in, obuf_flg_in; 9: instrout mem_we, mem_re; 10: instrout ibuf_re, ibuf_flg_clr, obuf_we; 11: output dbo<8>, ab<9>; 12: } 13: 14: circuit_type r512_8 { 15: /** external pins **/ 16: instrin read, write; 17: input adrs<9>, din<8>; 18: output dout<8>; 19: /** elements **/ 20: mem cell[512]<8>; 21: /** arguments of instrin **/ 22: instr_arg read(adrs); 23: instr_arg write(adrs, din); 24: /** operations of instrin **/ 25: instruct read dout = cell[adrs]; 26: instruct write cell[adrs] := din; 27: } 28: 29: module board { 30: /** elements **/ 31: reg_wr ibuf<8>, ibuf_flg, obuf<8>, obuf_flg; 32: kuechip2 cpu; 33: r512_8 mem; 34: 35: /** operations in common **/ 36: par { 37: cpu.ibuf_flg_in = ibuf_flg; 38: cpu.obuf_flg_in = obuf_flg; 39: } 40: 41: /** operations of instrout **/ 42: instruct cpu.mem_we mem.write(cpu.ab, cpu.dbo); 43: instruct cpu.mem_re cpu.dbi = mem.read(cpu.ab).dout; 44: instruct cpu.ibuf_re cpu.dbi = ibuf; 45: instruct cpu.ibuf_flg_clr ibuf_flg := 0b0; 46: instruct cpu.obuf_we par { 47: obuf := cpu.dbo; 48: obuf_flg := 0b1; 49: } 50: }
これで,KUE-CHIP2のプログラムをSECONDSを用いて実行してみるためのSFL 記述が整いました.
まず最初は,1からNまでの和を計算するKUE-CHIP2のプログラムで動作を確 認してみます.リスト5.2にアセンブルリストを示します.このプログラムは, X080番地の値をNとして,1からNまでの和を計算して,結果をX081番地に格納 するというものです.
[リスト 5.2] 1からNまでの和を計算するKUE-CHIP2のプログラム*** KUE-CHIP2 Assembler ver.1.0 by H.Ochi *** * Sum from 1 to N * Programmed by Akira Uejima, May. 5, 1992 * e-mail: uejima@mics.cs.ritsumei.ac.jp * N 80 : N: EQU 80H * Sum(result) 81 : SUM: EQU 81H 00 : 6C 80 LD IX, [N] 02 : 62 00 LD ACC, 0 04 : B1 LOOP: ADD ACC, IX 05 : AA 01 SUB IX, 1 07 : 33 04 BP LOOP 09 : 74 81 ST ACC, [SUM] 0B : 0F HLT END
リスト5.3は,このプログラムをSECONDSで実行するためのコマンド列です. SECONDSにはmemsetというメモリに値を書き込む便利なコマンドがあります.1 つめのmemsetでは,1からNまでの和を計算するKUE-CHIP2のプログラムを, X000番地を始点としてメモリに書き込んでいます.2つめのmemsetでは,X080 番地にNの値を書き込んでいます.最後の行では,1からNまでの和が格納され ているX081番地の内容を表示しています.
[リスト 5.3] SECONDSへのコマンド列# sum of 1, 2, ..., n sflread kuechip2.sfl sflread board.sfl autoinstall board # program memset mem/cell X000 \ X6c X80 X62 X00 Xb1 Xaa X01 X33 X04 X74 \ X81 X0f # n memset mem/cell X080 \ X0a # report rpt_add mem \ "[%3T] (%B)%S re=%B we=%B ab=%X dbi=%X dbo=%X " \ cpu/all.t cpu/all cpu.mem_re cpu.mem_we cpu.ab cpu.dbi cpu.dbo rpt_add reg \ "pc=%X ir=%X acc=%X ix=%X flag=%B%B%B%B %B\n" \ cpu/pc cpu/ir cpu/acc cpu/ix cpu/cf cpu/vf cpu/nf cpu/zf # execution set cpu/start 1; forward +75; # show result print "%X\n" mem/cell@X081
リスト 5.3の内容を,sum_1n.secというファイルに保存して,コマンドプ
ロンプトで,
% seconds < sum_1n.sec
としてみてください.実行結果は,リスト5.4のようになるはずです.この場
合,NがX0a(10)なので,X81番地の内容はX37(55)となります.
[1 ] (1)p1 re=1 we=0 ab=000 dbi=6c dbo=zz pc=00 ir=00 acc=00 ix=00 flag=0000 [2 ] (1)p2 re=1 we=0 ab=001 dbi=80 dbo=zz pc=01 ir=6c acc=00 ix=00 flag=0000 [3 ] (1)p3 re=1 we=0 ab=080 dbi=0a dbo=zz pc=02 ir=6c acc=00 ix=00 flag=0000 [4 ] (1)p1 re=1 we=0 ab=002 dbi=62 dbo=zz pc=02 ir=6c acc=00 ix=0a flag=0000 [5 ] (1)p2 re=1 we=0 ab=003 dbi=00 dbo=zz pc=03 ir=62 acc=00 ix=0a flag=0000 [6 ] (1)p1 re=1 we=0 ab=004 dbi=b1 dbo=zz pc=04 ir=62 acc=00 ix=0a flag=0000 [7 ] (1)p2 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=05 ir=b1 acc=00 ix=0a flag=0000 [8 ] (1)p1 re=1 we=0 ab=005 dbi=aa dbo=zz pc=05 ir=b1 acc=0a ix=0a flag=0000 [9 ] (1)p2 re=1 we=0 ab=006 dbi=01 dbo=zz pc=06 ir=aa acc=0a ix=0a flag=0000 [10 ] (1)p1 re=1 we=0 ab=007 dbi=33 dbo=zz pc=07 ir=aa acc=0a ix=09 flag=0000 : : : [60 ] (1)p1 re=1 we=0 ab=004 dbi=b1 dbo=zz pc=04 ir=33 acc=36 ix=01 flag=0000 [61 ] (1)p2 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=05 ir=b1 acc=36 ix=01 flag=0000 [62 ] (1)p1 re=1 we=0 ab=005 dbi=aa dbo=zz pc=05 ir=b1 acc=37 ix=01 flag=0000 [63 ] (1)p2 re=1 we=0 ab=006 dbi=01 dbo=zz pc=06 ir=aa acc=37 ix=01 flag=0000 [64 ] (1)p1 re=1 we=0 ab=007 dbi=33 dbo=zz pc=07 ir=aa acc=37 ix=00 flag=0001 [65 ] (1)p2 re=1 we=0 ab=008 dbi=04 dbo=zz pc=08 ir=33 acc=37 ix=00 flag=0001 [66 ] (1)p1 re=1 we=0 ab=009 dbi=74 dbo=zz pc=09 ir=33 acc=37 ix=00 flag=0001 [67 ] (1)p2 re=1 we=0 ab=00a dbi=81 dbo=zz pc=0a ir=74 acc=37 ix=00 flag=0001 [68 ] (1)p3 re=0 we=1 ab=081 dbi=zz dbo=37 pc=0b ir=74 acc=37 ix=00 flag=0001 [69 ] (1)p1 re=1 we=0 ab=00b dbi=0f dbo=zz pc=0b ir=74 acc=37 ix=00 flag=0001 [70 ] (1)p2 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=0c ir=0f acc=37 ix=00 flag=0001 [71 ] (0)p1 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=0c ir=0f acc=37 ix=00 flag=0001 [72 ] (0)p1 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=0c ir=0f acc=37 ix=00 flag=0001 [73 ] (0)p1 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=0c ir=0f acc=37 ix=00 flag=0001 [74 ] (0)p1 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=0c ir=0f acc=37 ix=00 flag=0001 [75 ] (0)p1 re=0 we=0 ab=zzz dbi=zz dbo=zz pc=0c ir=0f acc=37 ix=00 flag=0001 37
この結果を見ると,1から10までの和を求めるのに,70クロック要していま す.今回設計したKUE-CHIP2では,各命令を実行するのに2あるいは3クロック を要し,命令実行のオーバラップは行っていません.各命令に必要なクロック 数を減らしたり,各命令の実行をオーバラップさせることで,kuechip2を高速 化していく余地はまだまだあります.例えば,時間61では,mem_re, mem_weと もに起動されておらず,アドレスバスabが使用されていません.このとき,ir の値はb1なので,ADD ACC, IXという命令が実行されています.レジスタ間の 加算なので,メモリにはアクセスしていないというわけです.設計次第では, この隙に,次の命令をメモリからirに読み込むということもできます.
規定課題の資料 には,KUE-CHIP2のプログラムが2つ掲載されています.時間的に余裕のある方 は,これを用いた動作確認も行ってみてください.