先の例では、アセンブラによるプログラムを実行して実行結果の波形を表示し ました。しかし、この場合でも、どこに誤りがあるのかを見つけるのは至難の 技です。そこで、今度はシミュレータが出力した結果とシミュレーション結果 の期待値とを比較する方法について紹介します。
"testadd.asm" のアセンブル後の実行イメージである "testadd.hex" を KITE シミュレータ("~ai2/bin/kite2sim")にかけると以下のような情報を得ること ができます。 現在 "~ai2/bin/kite2sim" は、jackal, cms21, cms02 でしか動作しません。rlogin してお使い下さい。
Start address = 000 ---- acc=0000 ixr=000 ssp=000 out=0000 pc=000 c108 ld #0x08 ---- acc=0008 ixr=000 ssp=000 out=0000 pc=001 bc00 swp ---- acc=0800 ixr=000 ssp=000 out=0000 pc=002 9100 or #0x00 ---- acc=0800 ixr=000 ssp=000 out=0000 pc=003 f004 mv sp, acc ---- acc=0800 ixr=000 ssp=800 out=0000 pc=004 c800 in 0x00 中略 ---- acc=0037 ixr=7fd ssp=800 out=0000 pc=008 cc00 out 0x00 ---- acc=0037 ixr=7fd ssp=800 out=0037 pc=009 f800 halt ---- acc=0037 ixr=7fd ssp=800 out=0037 pc=00a f009 mv ixr, sp
では、論理シミュレータは、この期待値と同じ書式で実行結果を出力できるの でしょうか? 実は、できます。シミュレーションを行う際の "testfixture.new"ファイルとして、以下の内容を使用します。
// // CLOCK : 1MHz infinite loop // initial begin CLOCK = 1'b1; while(1) CLOCK = #5000 ~CLOCK; end // // I_A : 2MHz infinite loop // integer i1; initial begin I_A = 1'b1; while(1) I_A = #2500 ~I_A; end // // Condition for Termination : IR = HALT and HALT = TRUE // always @( ACC_IR or HALT ) if( ACC_IR == 16'hF800 && HALT == 1'b0 ) #10000 $finish; // // RESET, EXEC, CLKM, INSTM // initial begin RESET = # 0 1; // 0ns RESET = # 15000 0; // 1500 RESET = # 10000 1; // 2500 end initial begin EXEC = # 0 1; // 0ns end initial begin CLKM = # 0 1; // 0ns end initial begin INSTM = # 0 1; // 0ns end // // Load instructions on Memory // reg [15:0] MEM[0:4095]; // Memory Image initial begin $readmemh("/user/staff/kuga/work/cadence/4bit/testadd.ram", MEM); end // // Memory and I/O Transactions // initial begin ACK = # 0 1; // 0ns end reg [15:0] OUTR; // OUT port initial begin OUTR = # 0 16'h0000; // 0ns end always @( MREQ ) begin if ( MREQ == 1'b0 && RW == 1'b1 ) begin io_DATA = MEM[ADDR]; ACK = 1'b0; // $display("MEM Transaction READ : ADDR=%x DATA=%x", ADDR, MEM[ADDR]); end else if ( MREQ == 1'b1 && RW == 1'b1 ) begin io_DATA = 16'hZZZZ; ACK = 1'b1; end else if ( MREQ == 1'b0 && RW == 1'b0 ) begin MEM[ADDR] = DATA[15:0]; ACK = 1'b0; // $display("MEM Transaction WRITE : ADDR=%x DATA=%x", ADDR, DATA); end else if ( MREQ == 1'b1 && RW == 1'b0 ) begin ACK = 1'b1; end end always @( IORQ ) begin if ( IORQ == 1'b0 && RW == 1'b1 ) begin io_DATA = 16'h000a; // Input Value ACK = 1'b0; // $display("I/O Transaction INPUT : ADDR=%x DATA=%x", ADDR, io_DATA); end else if ( IORQ == 1'b1 && RW == 1'b1 ) begin io_DATA = 16'hZZZZ; ACK = 1'b1; end else if ( IORQ == 1'b0 && RW == 1'b0 ) begin ACK = 1'b0; OUTR = DATA; // $display("I/O Transaction OUT : ADDR=%x DATA=%x", ADDR, DATA); end else if ( IORQ == 1'b1 && RW == 1'b0 ) begin ACK = 1'b1; end end // // Execution Trace // always @( test.top.I70.ICS or I_A or CLOCK) begin if ( test.top.I70.ICS == 1'b1 && I_A == 1'b0 && CLOCK == 1'b0 ) #675 $display(" %s%s%s%s acc=%x ixr=%x ssp=%x out=%x pc=%x %x", ( S == 1'b0 ) ? "M" : "-", ( V == 1'b0 ) ? "V" : "-", ( Z == 1'b0 ) ? "Z" : "-", ( C == 1'b0 ) ? "C" : "-", ACC_IR, IXR, SP, OUTR, PC, MEM[PC]); end
上記の "testfixture.new" を用いてシミュレーションを行うと、シミュレー ション時のログである "simout.tmp" の中に以下のようなログが出力されます。
中略 ---- acc=0008 ixr=000 ssp=000 out=0000 pc=001 bc00 ---- acc=0800 ixr=000 ssp=000 out=0000 pc=002 9100 ---- acc=0800 ixr=000 ssp=000 out=0000 pc=003 f004 中略 ---- acc=0037 ixr=7fd ssp=800 out=0037 pc=009 f800 ---- acc=0037 ixr=7fd ssp=800 out=0037 pc=00a f009 中略
したがって、KITE シミュレータの出力からアセンブリ記述を省いた部分のファ イルを期待値ファイルとして用意し、また、"simout.tmp" ファイルから期待 値に対応する部分だけをコピーして一つのファイルにしておきます。あとは、 この二つのファイルを比較するだけです。
期待値のファイル名を "testadd.sim"、論理シミュレータのファイル名を "simout.tmp" としたとき、"diff" コマンドの出力は以下のようになります。
[panther]~/work/cadence/4bit[1413]% diff testadd.sim simout.tmp 1d0 < ---- acc=0000 ixr=000 ssp=000 out=0000 pc=000 c108
My mail address is
kuga@cms.kyutech.ac.jp .
Last modified on