Custom MicroBlaze( 以後 CMB )モニタの機能と操作
FPGAのソフトCPUのモニタには、最低限の機能として以下のものを含んでいます。
  1. FPGAのUARTポートを介して、パソコンのターミナルソフト使って操作します。 ターミナルを使ってコマンドラインの入力
  2. ターミナルでの操作は、コマンドライン形式となります。1文字の命令、または文字列命令で行います。
  3. CMBの任意のメモリ番地を、ヘキサでターミナルに表示します。ダンプメモリ ダンプメモリ "d"
  4. CMBの任意のアドレスに対して、8、16、32ビット単位で読み書きできます。セットメモリ メモリの変更コマンド、"s"、"sw"、"sl"
  5. CMBの任意のアドレスから、任意のアドレスへ、メモリの内容をコピーします。ムーブ メモリのコピーコマンド、"m"、 "mw"、 "ml"
  6. CMBの任意の2個のメモリブロックの内容を比較して、違いを表示します。
    ベリファイメモリ 2領域のメモリ間の比較。"v"( バイト単位のみ )
  7. メモリに指定したバイト列があるか、検索します。メモリのデータ検索 "fx,y,n,p"
  8. CMBの任意のアドレスを先頭にして、パソコンから送られるSレコード形式のヘキサデータをロードします。
    ロード Sレコード形式のデータを受信し、メモリにロード "l","lxxx"
  9. CMBの任意のアドレスから実行します。ゴー 任意の番地から実行 "gxxxx"
以上の機能があれば、パソコンからヘキサデータをRAMにロードして、そこから実行することもできるので、簡単なデバッグができます。CMBにSRAMなどがあるとプログラムのテストができます。これだけの機能で8kBほどです。
さらに、割り込みでLED点滅をさせる操作 "ixxxx","i0"倍精度浮動小数点で、sin の値の計算を追加しています。

ターミナルを使ってコマンドラインの入力

電源ONで以下のようにターミナルに表示します。ここで、CMB-Bug>の右の" " はターミナルのカーソルです。
Custom MicroBlaze AVNET LX9 microboard 2013.x.xx-1
CMB-Bug>
ターミナルからコマンドを入力すると、CMBからエコーバックが表示されます。以下は、メモリの0〜0xFF番地をヘキサで表示するコマンドを入力した場合です。"d0,ff"
ダンプメモリ "d","dxxx,yyy"
Custom MicroBlaze AVNET LX9 microboard 2013.x.xx-1
CMB-Bug>d0,ff
ここで、Enterを入力すると、以下のように0〜0xFF番地のメモリ内容が表示されます。
CMB-Bug>d0,ff
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00000000 B000 0000 B808 0050 B000 0000 B808 0050 *.......P.......P*
00000010 B000 0000 B808 0174 0000 0000 0000 0000 *.......t........*
00000020 B000 0000 B808 0114 0000 0000 0000 0000 *................*
00000030 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00000040 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00000050 B000 0000 3020 7ED0 B000 0000 20C0 7A30 *....0 ~..... .z0*
00000060 B000 0000 20E0 7A70 0646 3800 BC72 0014 *.... .zp.F8..r..*
00000070 D806 0000 20C6 0004 0646 3800 BC92 FFF4 *.... ....F8.....*
00000080 B000 0000 20C0 7A70 B000 0000 20E0 7AE0 *.... .zp.... .z.*
00000090 0646 3800 BC72 0014 D806 0000 20C6 0004 *.F8..r...... ...*
000000A0 0646 3800 BC92 FFF4 20C0 0000 20E0 0000 *.F8..... ... ...*
000000B0 B000 0000 B9F4 6AB0 20A0 0000 2021 FFFC *......j. ... !..*
000000C0 D9E1 0000 9410 0002 B60F 0008 2021 0004 *............ !..*
000000D0 2021 FFFC D9E1 0000 9411 0002 B60F 0008 * !..............*
000000E0 2021 0004 206F 0000 B60F 0008 8000 0000 * !.. o..........*
000000F0 2061 0000 B60F 0008 8000 0000 9410 0100 * a..............*
CMB-Bug>

コマンド入力は、BackSpace キーで、1文字戻ります。
CMB-Bug>d0,fff ここで BackSpace を押す
CMB-Bug>d0,ff

メモリの変更コマンド、"s"、"sw"、"sl"
任意のアドレスのメモリを、バイト s、ワード sw、ロングワード sl で、表示、変更します。アドレスは、コマンドに続けてアドレス値を追加します。
CMB-Bug>s7fc0 ここで Enter を押します。0x7FC0 番地からバイトで表示、変更
00007FC0=00  ここで、80 を入力
00007FC0=00 80 Enter を入力で 80 に変更され、次のアドレスに進みます。
00007FC1=00  新しいデータを順次入力して変更できます。
00007FC1=00  ここで、"r" キーを押すと、アドレスが1番地戻って変更後を表示します。
00007FC0=80  80 なら正しく変更されたことになります。80 以外ならメモリがどこか異状です
00007FC0=80  この状態で、"n" キーを押すと、このアドレスのメモリは変更せず以下のようになります。
00007FC1=00  次のアドレスの内容を表示します。"n" は、アドレスのみ進めます。"r" はアドレスのみ戻します。
	

sl コマンドの例です。
CMB-Bug>sl7fc0 ここで Enter を押します。0x7FC0 番地からロングワードで表示、変更
00007FC0=80000000  ここで、12345678 を入力
00007FC0=80000000 12345678 Enter を入力で 12345678 に変更され、次のアドレスに進みます。
00007FC4=00000000  新しいデータを順次入力して変更できます。
00007FC4=00000000  ここで、"r" キーを押すと、アドレスが4番地戻って変更後を表示します。
00007FC0=12345678  12345678 なら正しく変更されたことになります。12345678 以外ならメモリがどこか異状です
	

メモリのコピーコマンド、"m"、 "mw"、 "ml"
任意のアドレスから(ワードなどでは、そのサイズの境界を指定する必要があります)、任意のアドレスへ、任意個数コピーします。 操作の前に、各メモリは以下の通りだとします。
CMB-Bug>d7f80
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00007F80 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00007F90 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00007FA0 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00007FB0 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00007FC0 1234 5678 0000 0000 0000 0000 0000 0000 *.4Vx............*
00007FD0 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00007FE0 0000 0000 0000 0000 0000 0000 0000 0000 *................*
00007FF0 0000 0000 0000 0000 0000 0000 0000 0000 *................*
CMB-Bug>d7600
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00007600 2530 386C 583D 0000 2530 3258 2000 0000 *%08lX=..%02X ...*
00007610 2530 3258 0000 0000 2530 3458 0000 0000 *%02X....%04X....*
00007620 2530 386C 5820 0000 2530 3458 2000 0000 *%08lX ..%04X ...*
00007630 0D0A 4861 7264 7761 7265 2045 7863 6570 *..Hardware Excep*
00007640 7469 6F6E 2061 7420 5043 3D25 3038 6C58 *tion at PC=%08lX*
00007650 2041 4444 523D 2530 386C 580D 0A00 0000 * ADDR=%08lX.....*
00007660 0D0A 4375 7374 6F6D 204D 6963 726F 426C *..Custom MicroBl*
00007670 617A 6520 4156 4E45 5420 4C58 3920 6D69 *aze AVNET LX9 mi*
CMB-Bug>
このメモリダンプでは、1バイトが英数字コードなら文字をそのまま右の欄に表示します

ここで、m コマンドを実行します。コピー元は 0x7600、コピー先は 0x7F80 、個数は、0x80 です。
CMB-Bug>m7600,7F80,80 ここで Enter を押します。

結果を表示すると、以下のようになります。
CMB-Bug>d7600
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00007600 2530 386C 583D 0000 2530 3258 2000 0000 *%08lX=..%02X ...*
00007610 2530 3258 0000 0000 2530 3458 0000 0000 *%02X....%04X....*
00007620 2530 386C 5820 0000 2530 3458 2000 0000 *%08lX ..%04X ...*
00007630 0D0A 4861 7264 7761 7265 2045 7863 6570 *..Hardware Excep*
00007640 7469 6F6E 2061 7420 5043 3D25 3038 6C58 *tion at PC=%08lX*
00007650 2041 4444 523D 2530 386C 580D 0A00 0000 * ADDR=%08lX.....*
00007660 0D0A 4375 7374 6F6D 204D 6963 726F 426C *..Custom MicroBl*
00007670 617A 6520 4156 4E45 5420 4C58 3920 6D69 *aze AVNET LX9 mi*
CMB-Bug>d7f80
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00007F80 2530 386C 583D 0000 2530 3258 2000 0000 *%08lX=..%02X ...*
00007F90 2530 3258 0000 0000 2530 3458 0000 0000 *%02X....%04X....*
00007FA0 2530 386C 5820 0000 2530 3458 2000 0000 *%08lX ..%04X ...*
00007FB0 0D0A 4861 7264 7761 7265 2045 7863 6570 *..Hardware Excep*
00007FC0 7469 6F6E 2061 7420 5043 3D25 3038 6C58 *tion at PC=%08lX*
00007FD0 2041 4444 523D 2530 386C 580D 0A00 0000 * ADDR=%08lX.....*
00007FE0 0D0A 4375 7374 6F6D 204D 6963 726F 426C *..Custom MicroBl*
00007FF0 617A 6520 4156 4E45 5420 4C58 3920 6D69 *aze AVNET LX9 mi*
CMB-Bug>

2領域のメモリ間の比較、( バイト単位のみ )"vxxx,yyy,zzz"
ここで、2個のメモリブロック、先頭アドレスが、0x7600 と、0x7F80 で始まる0x80バイトの内容が同じかチェックします。v コマンド
CMB-Bug>v7600,7f80,80 ここで Enter を押します。
CMB-Bug> とのみ表示されます。

ここで、s7f90 Enter で、0x7F90 番地を、0xFF に変更します。
CMB-Bug>s7f90
00007F90=25 ff
00007F91=30 
CMB-Bug>
ここで、2個のメモリブロックで、内容が同じかチェックします。v コマンド
CMB-Bug>v7600,7f80,80 ここで Enter を押します。
	
00007610=25 00007F90=FF
CMB-Bug> と表示され、0x7610 番地と、0x7F90 番地の内容が異なってることを示します

メモリを検索して、指定したバイト列があるか探す "fx,y,n,p"

指定したメモリの範囲内から、1〜4バイトの長さの指定した値のデータ列を探し、あればその先頭アドレスを表示します。コマンドは、"fx,y,n,p" で、"x "は検索開始アドレス、"y" は、終了アドレス+1、"n" はバイト列の長さで、1〜4、"p" は、データ列の並びで、1〜8個のヘキサで指定します。
例として、指定範囲0x0〜0x7800に、"sin" という文字列を探します。文字列の場合でも、ヘキサでしか指定できません。
CMB-Bug>f0,7800,3,73696e ( enter ) 73696e は、"sin" の文字コード
000076A6 000076C2 000076E2 
CMB-Bug>
ここで、メモリをダンプすると、"sin" が3箇所あり、アドレスが一致しているのが判ります。
CMB-Bug>d7680
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00007680 6372 6F62 6F61 7264 2032 3031 332E 322E *croboard 2013.2.*
00007690 3130 2D31 0D0A 0000 434D 422D 4275 673E *10-1....CMB-Bug>*
000076A0 0000 0000 0D0A 7369 6E28 2535 6C64 2F31 *......sin(%5ld/1*
000076B0 3030 2920 3D20 302E 2530 396C 6400 0000 *00) = 0.%09ld...*
000076C0 0D0A 7369 6E28 2535 6C64 2F31 3030 2920 *..sin(%5ld/100) *
000076D0 3D20 312E 3030 3030 3030 3030 3000 0000 *= 1.000000000...*
000076E0 0D0A 7369 6E28 2535 6C64 2F31 3030 2920 *..sin(%5ld/100) *
000076F0 3D20 2530 386C 5820 0000 0000 0D0A 7063 *= %08lX ......pc*
CMB-Bug>


パソコンのターミナルソフトからSレコード形式のデータを送信し、メモリにロード "l","lxxx"

コマンドは、小文字のL "l"、"l7f00"、など。"l7f00" は、Sレコードのアドレス情報に、0x7F00 を加算したアドレスになります。"l" のみ場合は、アドレスの加算が0になります。Sレコードのファイルの最後には、"S7" か "S8" か "S9" で始まる終了を示す行がないと、パソコンからの送信が終わっても、CMB は受信を待ち続けます。もし、終了の行が無いファイルの場合は、コントロールCで強制終了できます。
パソコンから送信するSレコードファイルを、srecordtest.txt は以下の内容とします。このヘキサデータは、0x80番地から0x80バイトのサイズがあります。
S1130080B000000020C07A70B000000020E07AE0E8
S113009006463800BC720014D806000020C60004CE
S11300A006463800BC92FFF420C0000020E00000A7
S11300B0B0000000B9F46AB020A000002021FFFCC9
S11300C0D9E1000094100002B60F000820210004BA
S11300D02021FFFCD9E1000094110002B60F0008B2
S11300E020210004206F0000B60F000880000000EB
S11300F020610000B60F0008800000009410010089
S9030000FC
CMB-Bug>l7f00 ここで Enter を押し、
 
この状態にしてから、ターミナルソフトで、Sレコードファイルを送信します。全部送信すると以下のように表示します。
start loading address = 00007F80 ---> 最初に受信したSレコードデータをどこに書いたかを示します。
END.     bytes loaded = 00000080 ---> 受信してメモリに書いた総バイト数を表示します。
CMB-Bug> 

これで、0x80バイトのデータが、0x80+0x7F00 番地以降にロードされたはずなので、表示してみます。
CMB-Bug>d7f80
ADDR      0 1  2 3  4 5  6 7  8 9  A B  C D  E F  ascii
00007F80 B000 0000 20C0 7A70 B000 0000 20E0 7AE0 *.... .zp.... .z.*
00007F90 0646 3800 BC72 0014 D806 0000 20C6 0004 *.F8..r...... ...*
00007FA0 0646 3800 BC92 FFF4 20C0 0000 20E0 0000 *.F8..... ... ...*
00007FB0 B000 0000 B9F4 6AB0 20A0 0000 2021 FFFC *......j. ... !..*
00007FC0 D9E1 0000 9410 0002 B60F 0008 2021 0004 *............ !..*
00007FD0 2021 FFFC D9E1 0000 9411 0002 B60F 0008 * !..............*
00007FE0 2021 0004 206F 0000 B60F 0008 8000 0000 * !.. o..........*
00007FF0 2061 0000 B60F 0008 8000 0000 9410 0100 * a..............*
CMB-Bug>


任意の番地から実行 "gxxxx"

コマンドは、"g7f80" と、"g" に続いて実行したいアドレスを指示します。内部の処理としては、0x7F80 番地をサブルーチンとして呼び出してしています。命令は、brlid r15,0x7f80 などとなり、実行するプログラムがサブルーチン形式なら、return することも可能です。
CMB-Bug>g7f80 ここで Enter を押すと、0x7f80 番地からサブルーチンとして実行しまが、その前にプログラムを書きます。

実行したプログラムが return で戻れるように、以下のように、"sl7f80" コマンドで、マシン語で次のようにメモリに書いて、実行してみます。
CMB-Bug>sl7f80
00007F80=B0000000 20610000    addi	r3, r1, 0    の命令、レジスタ r3 に r1( stack pointer ) をロードします
00007F84=20C07A70 b60f0008    rtsd	r15, 8          return 命令。r15 には呼び出した命令のアドレスがコピーされています。
00007F88=B0000000 80000000    or	r0, r0, r0      NOP 命令、これは、CMBの遅延スロットで、実行されます。
00410006=20E07AE0 ここで、コントロールCを押して、メモリの変更を中止します。
CMB-Bug>g7f80       0x7F80 番地を実行します。
ret= 00007E98       r3 を表示します。 r3 には、スタックポインタ、r1 がコピーされているので、現在のスタックポインタになります。
CMB-Bug>


割り込みで、LEDの点滅 "ixxxx","i0"

割り込みを発生させるインターバルタイマを設定して、有効にし、MSRレジスタの”IE”フラグを1にして、CMBを割り込み可能状態にします。モニタのソース、cmbiofint.c には、以下のような割り込みインタバルタイマの設定と、MSRレジスタの操作をする部分があります。例としてプリセットを、0x2FAE( 12207−1 )とすると、100MHzでカウントするので、約121μ秒に1回割り込みを発生させることができます。
//	プリセットタイマーカウントの値を、1Mとして、この値になると、カウントを0とし、割り込みを発生する。
	case	'i':	// interrupt
		comp++;
		param[0].l32 = 0x100000;
		if((i=argck(&comp,param,1))== -1)
		{
			paramer();
			break;
		}
		if(param[0].l32 > 0x100)// タイマー割り込み許可
		{
			*((volatile long *)(INTCOUNT + 0)) = 0x00000;// タイマーカウントクリア
			*((volatile long *)(INTCOUNT + 4)) = param[0].l32;// プリセットタイマーカウント
			*((volatile long *)(INTCOUNT + 8)) = 0x00000;// 割り込みは、0−−>1の変化で有効
			ENINTFLAG = 1;
			_inten();// msrset r0,2 を実行するアセンブラプログラムをCALL startup.s
		}
		else// タイマー割り込み禁止
		{
			*((volatile long *)(INTCOUNT + 0)) = 0x00000;// タイマーカウントクリア
			*((volatile long *)(INTCOUNT + 8)) = 0x00000;
			ENINTFLAG = 0;
			_intds();// msrclr r0,2 を実行するアセンブラプログラムをCALL startup.s
		}
		break;
割り込みを受け付けると、モニタのソースで、inttest を実行させ、割り込みでカウンタ( leddata )を+1して、leddata と、0x1000をアンドして0以外ならLEDを点灯、0なら消灯します。モニタのソース、cmbiofint.c には、以下のような割り込み処理関数を記述しています。inttest をCALLする部分は、アセンブラのソース、startup.s にあります。
int	leddata;
// 割り込み処理
#define LEDPORT *((volatile char *)0xF000000F)
void inttest (void ) __attribute__ ((interrupt_handler));
void inttest()
{
	*((volatile long *)(INTCOUNT + 8)) = 0x00000;
	leddata++;
	if(leddata & 0x1000)
		LEDPORT = 1;
	else
		LEDPORT = 0;
}

実際に割り込みインターバルカウンタにプリセット値0x2FAEを設定し、割り込みを発生させ、LEDを点滅させ、ledtata の値の変化を見ると、以下のようになります。
CMB-Bug>i2fae ( enter ) でLEDが点滅開始します。
CMB-Bug>sl7a30( enter )  で、leddata の内容を表示します。leddata のアドレスは、cmbiofint.map 参照
00007A30=000088AA nのみキー入力。enter を押すと ledtata の内容が0になります
00007A34=00000000 rのみキー入力。以下、"n","r" を入力する間隔は約1秒
00007A30=0000C83F nのみキー入力
00007A34=00000000 rのみキー入力
00007A30=0000EB12 nのみキー入力
00007A34=00000000 rのみキー入力
00007A30=00010D5B nのみキー入力
00007A34=00000000 rのみキー入力
00007A30=00012F3F CTRL−Cのみキー入力
CMB-Bug>
LEDは、約0.5秒点灯、0.5秒消灯を繰り返しますが、プリセット値0x2FAEで、約122μ秒に1回の割り込みなので、leddata の値と、0x1000をアンドすると、4096カウントで0か否かになって、122x4096で、0.5秒でLEDの状態が変化します。

倍精度浮動小数点で、sin の値の計算 "F1,0,xx,yy","F0,0,xx,yy"

三角関数の sin 演算精度を、次のようにして、倍精度浮動小数点64ビット表現をそのままヘキサで表示させます。
CMB-Bug>F1,0,65,64 ( enter ) 角度0度から、1度単位に、100度までIEEE754表示
ここで、F1 は、IEEE754 の指定、0,65,64 は、0度から、101度手前まで、0.01度単位*100の意味。
結果。IEEE 754 形式の、符号部 1 + 指数部 11 + 仮数部 53( 52+1 )

CMB-Bug>F0,0,65,64 ( enter ) 角度0度から、1度単位に、100度まで表示。小数点以下は9桁まで。








戻る


inserted by FC2 system