平成26年9月28日
キャッシュ機能の設定確認
先日までの検証でキャッシュ機能の動作が確認できました。確認の意味で、個々の設定内容とその必要性について吟味してみます。
SYSTEMConfigPerformance()関数の処理内容を再度示します。
- PBCLKの設定はSYSCLKが80MHzを超える場合にはPBDIVを2に、それ以外は1に設定する。データシートからは見つけることが出来なかったのですが、周辺バスの駆動周波数は80MHzが上限のようです。
- RAMへのアクセスをデフォルトの1ウエイトから0ウエイトへ変更
- ROMへのアクセスを動作周波数に応じたウエイト数に設定
- キャッシュ機能への設定としては以下を行っています。
- CHECONレジスタのPREFENビットを3(キャッシュ可能領域とキャッシュ不可能領域の両方に対して予測プリフェッチを有効にする)に変更しています。
- CP0レジスタ内にあるキャッシュ有効ビットをセット
個々の必要性を考えると
- PBCLKの設定はキャッシュ機能には無関係なので不要
- RAMへのアクセスは動作周波数上限の80MHzまで0ウエイトで動作するので0ウエイトに設定する(初期値1ウエイトから変更)
- ROMへのアクセスは80MHzでは2ウエイト必要
- キャッシュ機能への設定としては
- CHECONレジスタのPREFENビットは命令のプリフェッチを設定しているので無効でも動作するが有効にした方がいい。
- CP0レジスタ内にあるキャッシュ有効ビットは必ずセットが必要。
となります。
ROM上での動作に対して最低限必要な処理としては、ROMアクセス時のウエイト数設定(デフォルトでは7)とキャッシュの有効ビットのセットの二つです。これで先日の動作確認で失敗した理由も判明しました。20MHzで動作可能な設定のまま周波数を80MHzに変更したため、ROMアクセス時のウエイト数設定が0ウエイトのままでした。2にしないから暴走する筈です。ああ、単純ミス...
これに従ってプログラムを修正します。処理中は割り込みを禁止する処理も追加してあります。
#include <xc.h>
#include "plib.h"
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_4, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL
int main(void)
{
unsigned int status = INTDisableInterrupts();
CHECONbits.PFMWS = 2; //ROMへのアクセスでは2ウエイト
//mBMXDisableDRMWaitState(); //RAMへのアクセスでは0ウエイト
//CHECONbits.PREFEN = 3; //プリフェッチ機能を有効化
CheKseg0CacheOn(); //キャッシュ機能有効
INTRestoreInterrupts(status);
//SYSTEMConfigPerformance(80000000); //この方が簡単だが
TRISD = 0;
LATD=0;
for(;;){
LATD=0xffff;
LATD=0;
}
return 0;
}
結果は期待通り80MHzで動作しています。