プロペラの深層に迫る文書
原題:Early Propeller Chip Documentation rev.1
状態:この文書は現在翻訳中です
原文:http://forums.parallax.com/showthread.php?83682-Propeller-Guts-Download
翻訳者: @ksksue,@yishii
対象読者:プロペラのブートシーケンス、アセンブラ仕様などの詳細を知りたい人
ハードウェアについて †
リセット詳細 †
リセットが起こると、すべてのCOGはシャットダウンし、すべてのピンは強制的に浮いた状態になります。そのあと、ひとつのCOGがメインメモリのROMからスタートアッププログラムをロードしブートします。このプログラムはP31(RX)のシリアルホスト接続をチェックします。もしホストが存在する場合、P30(TX)を通じて通信を確立します。そしてホストは高レベルコードをメインメモリRAMへロードします。そしてホストは、そのコードが実行される前にまず直接EEPROMへ書き込みます。もしホストが存在しない場合、スタートアッププログラムは24LC256 EEPROMからP28(SCL)とP29(SDA)を経由して高レベルコードをリードし、実行しようと試みます。もし、シリアルホストもEEPROMも存在しない場合、プログラムはそのチップをシャットダウンモードに移行させます。次のリセットが起こるまで、電力は最小になり、すべてのピンは浮いた状態となります。
高レベルコードとはプログラマの視点で言う初期化プログラムに当たるものです。それは他のcogを高レベルタスクやアセンブリ言語プログラムでブートすることができます。高レベルコードの実行について言えば、ある一つのCOGがメインメモリROMからインタプリタプログラムをロードし、そのインタプリタプログラムがメインメモリRAMに含まれる高レベルコードを実行します。
COG詳細 †
各Cogは512 x 32-bit レジスタ領域を持っています。最後の特殊レジスタ16個を除いて、この512個のレジスタはすべてRAMです。
RAM領域は実行コード、データ、変数のために使われます。最後の16個のレジスタはHUB、IOピン、ローカルCOGペリフェラルのインタフェースとして使われます。
一つのCOGがブートされたとき、そのCONGのRAM記憶領域はメインメモリからシーケンシャルにロードされます。そしてその特殊レジスタはゼロにクリアされます。
ロードされた後、そのCOGで$000から命令の実行がスタートします。リセットが起こるか、自身もしくは他のCOGによってストップかリブートがかかるまで、コードが実行され続けます。
I/Oピンや消費電力といったすべての影響をキャンセルするため、
ひとつのCOGがストップされたときもしくはリセットが起こった時、すべてのCOGのI/Oレジスタは即座に0クリアされます。
下の表はCOG内の特殊レジスタの概要です。
Address | Name | Access | Description |
$000-$1EF | - | リード/ライト | 汎用RAM |
$1F0 | PAR | リードオンリー* | ロングアドレスパラメータ |
$1F1 | CNT | リードオンリー* | システムカウンタ |
$1F2 | INA | リードオンリー* | P31〜P0の入力値 |
$1F3 | INB | リードオンリー* | P63〜P32の入力値** |
$1F4 | OUTA | リード/ライト | P31〜P0の出力値 |
$1F5 | OUTB | リード/ライト | P63〜P32の出力値** |
$1F6 | DIRA | リード/ライト | P31〜P0の方向制御 |
$1F7 | DIRB | リード/ライト | P63〜P32の方向制御** |
$1F8 | CTRA | リード/ライト | カウンタA制御 |
$1F9 | CTRB | リード/ライト | カウンタB制御 |
$1FA | FRQA | リード/ライト | カウンタA周波数 |
$1FB | FRQB | リード/ライト | カウンタB周波数 |
$1FC | PHSA | リード/ライト | カウンタAフェーズ |
$1FD | PHSB | リード/ライト | カウンタBフェーズ |
$1FE | VCFG | リード/ライト | ビデオコンフィグレーション |
$1FF | CSCL | リード/ライト | ビデオスケール |
*ソースレジスタとしてのみアクセス可能(例 MOV DEST, SOURCE)
** 現状未実装。予約領域。
COGは512個のレジスタ領域にある32bit命令を実行します。命令はいくつかのビットフィールドに分けられています。
一般的なアセンブリ命令のフォーマットは以下のようになっています。
{アドレスラベル}{実行コンディション}命令 ディスティネーション, {#}ソース, {実行エフェクト(コンマ区切り)}
例:
entry rdlong temp,PAR wz 'wait for command (non-0)
if_z jmp #entry
32bit命令の詳細
オペコード | Zフラグ | Cフラグ | 結果更新 | ソース即値 | 実行コンディション | ディスティネーションレジスタ | ソースレジスタor即値 |
31..26 | 25 | 24 | 23 | 22 | 21..18 | 17..9 | 8..0 |
iiiiii | z | c | r | i | cccc | ddddddddd | sssssssss |
フィールド | 範囲 | 説明 |
オペコード | 31..26 | ADD, SUB, AND, OR, JMP など |
実行エフェクト | 25..23 | 1の場合それぞれCフラグ、Zフラグそしてディスティネーションレジスタを有効にする。 ビット25が1の場合、Zフラグ有効。 ビット24が1の場合、Cフラグ有効。 ビット23が1の場合はディスティネーションレジスタ有効。 |
ソース即値 | 22 | 1の場合bit8..0が32ビットの即値として扱われる。このときの32ビット即値は下位9bit以外は0で埋められる。 |
実行コンディション | 21..18 | CとZフラグの状態によって命令を実行。詳細は「実行コンディション」の項目を参照 |
ディスティネーションレジスタ | 17..9 | 1番目のレジスタ。 |
ソースレジスタor即値 | 8..0 | 2番目のレジスタもしくは即値 |
ソースレジスタ or 即値 †
@yishii翻訳中
この9ビットのフィールドは、インストラクションのソースとして、レジスタ(512の内のどれか)の選択、もしくは0拡張された即値指定として使用する。
ビット22に対して0をセットすることでレジスタ選択、または1を指定することで即値となる。
アセンブリコードにおいては、 #シンボルは即値モードをセットする。
ディスティネーションレジスタ †
@yishii翻訳中
この9ビットのフィールドは、インストラクションのディスティネーションとして512の内のどのレジスタを使用するかを選択する為に使用する。
実行コンディション †
実行エフェクト †
HUB命令 †
メインメモリアクセス †
CLKレジスタ書き込み †
COG制御 †
@ksksue翻訳中
COGのスタートとストップを管理する3つのHUB命令があります。
COGID D `このCOG番号をDへ保存
COGINT D `Dに従ってCOGを初期化
COGSTOP D `COG番号Dをストップ
COGID命令でDへCOG番号を保存します。この命令は、そのCOGをストップまたはリスタートさせるために、COGのID(全8個)を知るときに使用します。
COGINIT命令はCOGをスタートもしくはリスタートさせます。レジスタ D は
- どのCOGがスタートするか
- メインメモリのどこからプログラムが始まるか、
- PARレジスタに何が含まれているか
この3つのフィールドを決定する情報を含んでいます。
スタートするCOGのPARレジスタのビット[15..2]をD[31..18]へ書き込みます。
LOCK使用方法 †
分岐命令 †
加算、減算、比較命令 †
乗算、除算、平方根命令 †
ウェイト命令 †
メインメモリ †
@yishii翻訳中
アドレス範囲 | メモリータイプ | 内容 |
$0000-$7FFF | RAM | ユーザーメモリ – 8,192 longs / 16,384 words / 32,768 bytes |
$8000-$BFFF | ROM | キャラクター定義 – 4,096 longs 256種 16 x 32 ピクセルキャラクタ定義 |
$C000-$CFFF | ROM | 対数テーブル – 2,048 words of fractional exponents |
$D000-$DFFF | ROM | 逆対数テーブル – 2,048 words of top-bit-set 17-bit mantissas |
$E000-$F001 | ROM | 正弦テーブル – 2,049 unsigned words。カバー範囲:0° 〜 90° |
$F002-$FFFF | ROM | ブートと割り込みプログラム |
ROM内テーブルは、アセンブリ言語で容易に高速なリアルタイム信号処理を行う為に用意されている。
High-level programs may not find much direct use for this data, though they may leverage objects which take advantage of it.
ユーザメモリ($0000-$7FFF) †
@yishii翻訳中
メインメモリーの前半は全てRAMである。この領域は、ユーザープログラム、変数、スタックの格納に使用する。
本領域へは、シリアルインターフェースまたは外部EEPROMから、プログラムがチップにロードされた時に書き込まれる。
ユーザープログラムは $0010 から開始する。この領域以降、 $7FFFまでがスタックとして使用される。また、$0000 から $000F までのデータは、主に初期時の割り込みポインタとして使用される。
この領域に格納されている、long長のマスタークロック周波数(単位:[Hz])及びbyte長のグローバルクロックレジスタ値はユーザープログラムにとって重要であろう。
もし、ユーザープログラムがグローバルクロックレジスタを変更した場合、オブジェクトが現在の状態を参照する為にこれら2つの値を更新する。
上位プログラムからは、マスタークロック周波数は、 'FREQ' で読み出し可能である。また、 'LONG[0]'によっても読み出し並びに書き込み可能である。
グローバルクロックレジスタ値のコピーへの読み書きアクセスは 'BYTE[15]' で可能である。
キャラクタ定義($8000-$BFFF) †
対数、逆対数テーブル($C000-$DFFF) †
対数テーブル($C000-$CFFF) †
逆対数テーブル($D000-$DFFF) †
サインテーブル($E000-$F001) †
ブートプログラムとインタプリタ($F002-$FFFF) †
ROMの最後のパートにはブートプログラムとインタプリタが置かれています。これはアセンブラプログラムで、チップの重要な処理を実行します。
ブートプログラムはリセットされたら自動的に実行され、チップをブートさせる処理を担っています。ブートプログラムはまずホストとシリアル通信するためしばらくP31とP30を監視します。もしホストが存在した場合、高レベルプログラムをRAMへ転送します。そのプログラムを実行するため外部EEPROMへ書き込みインタプリタを立ち上げます。もしシリアル通信のホストが存在しない場合、ブートプログラムはP29とP28へアクセスし、外部EEPOMからRAMへ高レベルプログラムをロードを試みます。成功したら、インタプリタが立ち上がりそのプログラムを実行します。もしEEPROMがない場合もしくは高レベルプログラムにデータの破損があった場合、ブートプログラムは電力消費を抑えるためチップをシャットダウンします。
インタプリタは高レベルプログラムを実行します。そして、インタプリタは最初は同一COG内で実行されているブートプログラムによって呼び出されます。その高レベルプログラムを実行しているインタプリタによって、ほかのCOGのインタプリタが呼び出されます。そのようにして、他の高レベルプログラムを並列に実行させることができます。
グローバルクロックレジスタ †
@yishii 翻訳中
グローバルクロックレジスタは、チップのマスタークロック源を制御する。ここには上位言語からは 'CLKSET(value)'命令 、アセンブリ言語からは 'CLKSET D'命令で書き込み可能である。
このクロックレジスタに書き込みが発生した時には、クロックの乗り換えの為に100[us]以下のグローバルディレイが発生する。
このレジスタが変更された際には、レジスタ値のコピーを BYTE[4] に、更新されたマスタークロック周波数をLONG[0] に書き込むこと。
これでオブジェクトは現在の情報を参照し、それぞれのタイミング計算に使用することになる。
このクロックレジスタは以下で構成されている。
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Name | RESET | PLLENA | OSCENA | OSCM1 | OSCM0 | CLKSEL2 | CLKSEL1 | CLKSEL0 |
RESET | 動作内容 |
0 | チップをリセットしない場合は '0' を書く |
1 | ハードウェアリセット。チップはリブートする |
PLLENA | 動作内容 |
0 | 全PLL回路を無効にする |
1 | PLL回路を有効にする。PLLは内部でXINからの入力周波数を16逓倍する。XINに入力した信号をPLLに伝達させる為に、OSCENA には '1' をセットする。PLL内部周波数は 64[MHz] から 128[MHz] の範囲にすること(XIN入力周波数としては 4.00[MHz] から 8.00[MHz])。CLKSEL ビットによる切り替え前に、PLL安定待ち 100[us] が必要である。OSC及びPLLが安定すれば、ユーザープログラムは、CLKSELにより自由に全てのクロックソースを切り替えることが可能である。 |
OSCENA | 動作内容 |
0 | OSC回路を無効にする |
1 | OSC回路を有効にし、XINからのクロック入力、もしくはXINとXOUTによるフィードバックオシレータ動作を可能とする。OSCMビットでOSC回路の動作モードを選択する。なお、発振回路の為に外部に抵抗やコンデンサは不要である。CLKSELビットによりOSCまたはPLL出力に切り替える前に、10[ms]の発振器安定待ちが必要である。OSC回路を有効にしたときには、同時にPLLも有効になるので、その安定待ち期間はそれぞれで共有することになる。 |
OSCM1 | OSCM0 | XOUT抵抗値 | XIN/XOUT容量 | 周波数範囲 |
0 | 0 | 無限大 | 6pF (パッドのみ) | DC to 80MHz Input |
0 | 1 | 2000 Ω | 36pF | 4MHz 〜 16MHz 水晶/セラミック発振子 |
1 | 0 | 1000 Ω | 26pF | 8MHz 〜 32MHz 水晶/セラミック発振子 |
1 | 1 | 500 Ω | 16pF | 20MHz 〜 60MHz 水晶/セラミック発振子 |
CLKSEL2 | CLKSEL1 | CLKSEL0 | マスタークロック | クロック源 | 備考 |
0 | 0 | 0 | 〜12MHz | 内部 | 外付け部品不要。8MHz〜20MHz |
0 | 0 | 1 | 〜20KHz | 内部 | 超低電力。13kHz〜33kHz |
0 | 1 | 0 | XIN | OSC | OSCENAは'1'をセットすること |
0 | 1 | 1 | XIN × 1 | OSC+PLL | OSCENAとPLLENAは'1'をセットすること |
1 | 0 | 0 | XIN × 2 | OSC+PLL | OSCENAとPLLENAは'1'をセットすること |
1 | 0 | 1 | XIN × 4 | OSC+PLL | OSCENAとPLLENAは'1'をセットすること |
1 | 1 | 0 | XIN × 8 | OSC+PLL | OSCENAとPLLENAは'1'をセットすること |
1 | 1 | 1 | XIN × 16 | OSC+PLL | OSCENAとPLLENAは'1'をセットすること |
更新履歴 †
2011/12/19:「ソースレジスタ or 即値」「ディスティネーションレジスタ」「メインメモリ」「ユーザーメモリ」追記(@yishii)
2011/12/18:「リセット詳細」追記(@ksksue), 「ブートプログラムとインタプリタ($F002-$FFFF) 」追記(@ksksue)
2011/12/17:ページ作成。「COG詳細」「COG制御」追記(@ksksue)