【目次に戻る】

5. KUE-CHIP2の動作確認


KUE-CHIP2全体のSFL記述が完成したら,SECONDSを用いてその動作を確かめて みます.ここでは,KUE-CHIP2のプログラムを実際に動かしてみて,結果が正 しいかどうかを見て判断します.そのためには,KUE-CHIP2本体とメモリなど が搭載されたボードのようなものを用意する必要がありますので,まずはこれ をSFLのモジュールboardとして記述します. リスト5.1 に一例を示します.

kuechip2のサブモジュールタイプ宣言 [TOP]

モジュールboardでは,モジュールkuechip2をサブモジュールとして使用し ますので,ここでkuechip2のサブモジュールタイプ宣言を行う必要があります. モジュールkuechip2は,制御入力端子startを持ちますが,仮引数はありませ んので,仮引数の定義に関しては何も書きません.従って,外部端子の定義の みを書きます.

機能回路r512_8 [TOP]

次に,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番地を示します.

モジュールboardの定義部 [TOP]

以上で,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: }

1からNまでの和を計算するプログラム [TOP]

これで,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)となります.

[リスト 5.4] SECONDSの実行結果
[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に読み込むということもできます.

別のプログラムで動作確認 [TOP]

規定課題の資料 には,KUE-CHIP2のプログラムが2つ掲載されています.時間的に余裕のある方 は,これを用いた動作確認も行ってみてください.