KUE-CHIP2全体のSFL記述が完成したら,SECONDSを用いてその動作を確か めてみます.ここでは,KUE-CHIP2の命令セットからなるプログラムを実際に 動かしてみて,結果が正しいかどうかを見て判断します.そのためには, KUE-CHIP2本体とメモリなどが搭載されたボードのようなものを用意する必要 がありますので,これをSFLのモジュールboardとして記述します.リスト5.1に一例を示します.
まず,KUE-CHIP2が使用する512バイトのメモリを,機能回路 r512_8として設計します.メモリは,機能回路においてのみ構成要 素として記述できるからです.
制御入力端子としては,読み出し,書き込みを行うためのread, writeを用意します.データ入力端子としては,アドレスを示す adrs<9>,書き込みデータを入力するdin<8>を用意します. データ出力端子としては,読み出しデータを出力するdout<8>を用意 します.
SFLではmemというキーワードでメモリを表します.ここでは, cellという名前の512バイト(8ビットを1バイトとする)のメモリを宣 言しています.あとは,制御入力端子readとwriteの動作 を記述します.cell[adrs]で,cellというメモリの adrs番地を示します.
モジュールboardでは,モジュールkuechip2と機能回路 r512_8をサブモジュールとして使用しますので,ここでこれらのイ ンタフェースの宣言を行う必要があります.モジュールkuechip2は, 制御入力端子startを持ちますが,仮引数はありませんので,仮引数 の定義に関しては何も書きません.従って,外部端子の定義のみを書きます. 機能回路r512_8については,readの仮引数を adrs,writeの仮引数をadrsとdinとし ます.
以上で,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に供給されるということです.49行目から58行目には, cpuの制御出力端子の動作の定義が行われています.このように,あ るモジュールの制御出力端子の動作の定義は,そのモジュールをサブモジュー ルとして用いる外側のモジュールで行われます.
以上で,リスト5.1の説明は終わりです.リスト5.1のSFL記述はboard.sfl というファイルに格納することにします.
リスト5.1: 動作確認のためのSFL記述(board.sfl) [TOP]1 /** board : KUE-CHIP2 Educational Board **/ 2 /** This description is only for simulation using SECONDS **/ 3 4 circuit r512_8 { 5 /** external pins **/ 6 instrin read, write; 7 input adrs<9>, din<8>; 8 output dout<8>; 9 /** elements **/ 10 mem cell[512]<8>; 11 /** operations of instrin **/ 12 instruct read dout = cell[adrs]; 13 instruct write cell[adrs] := din; 14 } 15 16 declare kuechip2 { 17 /** external pins **/ 18 instrin start; 19 input dbi<8>; 20 input ibuf_flg_in, obuf_flg_in; 21 instrout mem_we, mem_re; 22 instrout ibuf_re, obuf_we; 23 output dbo<8>, ab<9>; 24 } 25 26 declare r512_8 { 27 /** external pins **/ 28 instrin read, write; 29 input adrs<9>, din<8>; 30 output dout<8>; 31 /** arguments of instrin **/ 32 instr_arg read(adrs); 33 instr_arg write(adrs, din); 34 } 35 36 module board { 37 /** elements **/ 38 reg_wr ibuf<8>, ibuf_flg, obuf<8>, obuf_flg; 39 kuechip2 cpu; 40 r512_8 mem; 41 42 /** operations in common **/ 43 par { 44 cpu.ibuf_flg_in = ibuf_flg; 45 cpu.obuf_flg_in = obuf_flg; 46 } 47 48 /** operations of instrout **/ 49 instruct cpu.mem_we mem.write(cpu.ab, cpu.dbo); 50 instruct cpu.mem_re cpu.dbi = mem.read(cpu.ab).dout; 51 instruct cpu.ibuf_re par { 52 cpu.dbi = ibuf; 53 ibuf_flg := 0b0; 54 } 55 instruct cpu.obuf_we par { 56 obuf := cpu.dbo; 57 obuf_flg := 0b1; 58 } 59 }
これで,KUE-CHIP2のプログラムをSECONDSを用いて実行してみるためのSFL 記述が整いました.
まず最初は,1からNまでの和を計算するKUE-CHIP2のプログラムで動作を確 認してみます.リスト5.2にアセンブルリストを示します.このプログラムは, X080番地の値をNとして,1からNまでの和を計算して,結果をX081番地に格納 するというものです.
リスト5.2: 1からNまでの和を計算するKUE-CHIP2のプログラム1 *** KUE-CHIP2 Assembler ver.1.0 by H.Ochi *** 2 3 * Sum from 1 to N 4 * Programmed by Akira Uejima, May. 5, 1992 5 * e-mail: uejima@mics.cs.ritsumei.ac.jp 6 7 * N 8 80 : N: EQU 80H 9 * Sum(result) 10 81 : SUM: EQU 81H 11 12 00 : 6C 80 LD IX, [N] 13 02 : 62 00 LD ACC, 0 14 04 : B1 LOOP: ADD ACC, IX 15 05 : AA 01 SUB IX, 1 16 07 : 33 04 BP LOOP 17 09 : 74 81 ST ACC, [SUM] 18 0B : 0F HLT 19 20 END
リスト5.3は,このプログラムをSECONDSで実行するためのコマンド列です. SECONDSにはmemsetというメモリに値を書き込む便利なコマンドがあ ります.1つめのmemsetでは,1からNまでの和を計算するKUE-CHIP2 のプログラムを,X000番地を始点としてメモリに書き込んでいます. 2つめのmemsetでは,X080番地にNの値を書き込んでいます. 最後の行では,1からNまでの和が格納されているX081番地の内容を 表示しています.
リスト5.3: SECONDSへのコマンド列1 # sum of 1, 2, ..., n 2 3 sflread kuechip2.sfl 4 sflread board.sfl 5 autoinstall board 6 7 # program 8 memset mem/cell X000 \ 9 X6c X80 X62 X00 Xb1 Xaa X01 X33 X04 X74 \ 10 X81 X0f 11 12 # n 13 memset mem/cell X080 \ 14 X0a 15 16 # report 17 rpt_add mem \ 18 "[%3T] (%B)%S re=%B we=%B ab=%X dbi=%X dbo=%X " \ 19 cpu/all.t cpu/all cpu.mem_re cpu.mem_we cpu.ab cpu.dbi cpu.dbo 20 21 rpt_add reg \ 22 "pc=%X ir=%X acc=%X ix=%X flag=%B%B%B%B %B\n" \ 23 cpu/pc cpu/ir cpu/acc cpu/ix cpu/cf cpu/vf cpu/nf cpu/zf 24 25 # execution 26 set cpu/start 1; forward +75; 27 28 # show result 29 print "%X\n" mem/cell@X081
リスト 5.3の内容を,sum1n.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つ掲載されています.時間的に余裕のある方は,こ れを用いた動作確認も行ってみてください.