この記事では、MIPS32リリース2割り込みの構成と使用のいくつかの例を提供します。これには、これで設定される構成の詳細な説明や、外部割り込みコントローラーの操作方法が記載されています。
説明されているすべてのコードは、mipsfpga-plus [ L3 ]プロジェクトの一部としてgithubで公開されています。
はじめに
読者は:
- ハリスとハリスの教科書の巻の主題領域に精通している[ L1 ];
- タイマーや割り込みの使用など、(あらゆるアーキテクチャの)マイクロコントローラのプログラミングの経験があります。
- ソースコードMIPSfpga [ L2 ]およびmipsfpga-plus [ L3 ]にアクセスできます。
この記事を書くことにより、MIPS microAptivコアの割り込みを処理するすべての機能を包括的に述べるつもりはありません。 これには、ドキュメントの大規模な翻訳と、ほぼ同じ量のコメントが必要です。 目標は、下位互換性、ベクトル、外部コントローラーの使用の3つの可能なモードで割り込みを構成および使用する実例を示すことです。 したがって、読者がより快適に感じるために、ドキュメントの次のセクションをすぐに理解することをお勧めします。
- MIPS32 microAptiv UPプロセッサーコアファミリーインテグレーターズガイド[ D1 ]
(セクション4「割り込みインターフェイス」); - MIPS32 microAptiv UPプロセッサコアファミリソフトウェアユーザーマニュアル[ D2 ]
(セクション:5.1-5.6 "microAptiv UPコアの例外と割り込み"、6.2.13 "カウントレジスタ"、6.2.15 "比較レジスタ"、6.2.16 "ステータスレジスタ"、6.2.17 "IntCtlレジスタ"、6.2 .22 "原因レジスタ"、6.2.28 "EBaseレジスタ"、6.2.33 "Config3レジスタ"); - Codescape GNU Tools for MIPSプログラマーズガイド[ D3 ]
(セクション:15.5。「例外」、15.6。「割り込み」)。
すべての例で、わかりやすくするために、シミュレーターで実行されるシステムmipsfpga-plusでの起動について説明しています。 同様に成功した場合、これはハードウェアでも実行できます。コード全体の機能は、Terasic DE10-Lite [ L4 ]ボードでテストされました。
受け入れられた指定
信号の名前はイタリック体( SI_Int [7:0] )で示されていますが、特に指定がない限り、すべての信号はMIPSfpgaシステムの上位モジュール(m14k_top)のインターフェースです。 レジスタの場合、飽和フォント( Count )が使用され、個々のビット(フィールド)の名前は、関連するレジスタを示すドット( Cause.DC )で示されます。ドキュメントの個別のコピーでは、レジスタフィールドは下付き文字( Cause IV )で示されます。 すべてのレジスタについて、これが別に指定されていない場合、幅x32が想定されます。 ドキュメントのコピーで定数を指定する場合、記号「ポンド」の前に番号システムの指示があります(16#180、2#00001)。
なぜなら 残念ながら、オプション「GPR Shadow Registers」(Shadow Register Set、SRS)はMIPSfpgaでは利用できないため、この記事では汎用シャドウレジスタに関する詳細を省略しています。 この機能がダイアグラム上にある場合-灰色(色あせた)色で反映されます。
例外処理
例外は、プロセッサがカーネルモードに切り替わるすべてのイベントとして理解されます:外部デバイスからの割り込み要求を含む、メモリアクセスエラー、ゼロ除算など。 考えられるすべての例外の処理は広範なトピックであり、オペレーティングシステム(OS)のカーネルから切り離して正しく考慮することはできません。これは明らかにこの記事の範囲外です。 ただし、OSの使用が意図されていない場合でも(ベアメタルコード)、開発者はメモリ内に最小限のハンドラーセットを提供して、例外の発生について学習し、「任意の水泳」でのプログラムの実行を防止する必要があります。
if Status.EXL = 1 then vectorOffset ← 16#180 else if ExceptionType = TLBRefill then vectorOffset ← 16#000 elseif (ExceptionType = Interrupt) then // if (Cause.IV = 0) then vectorOffset ← 16#180 else if (Status.BEV = 1) or (IntCtl.VS = 0) then vectorOffset ← 16#200 else if Config3.VEIC = 1 then VecNum ← Cause.RIPL else VecNum ← VIntPriorityEncoder() endif vectorOffset ← 16#200 + (VecNum × (IntCtl.VS || 2#00000)) endif endif endif endif Cause.ExcCode ← ExceptionType // , Status.EXL ← 1 // , " " if Status.BEV = 1 then vectorBase ← 16#BFC00200 else // EBase[31:30] = 2'b10 // kseg0 kseg1 vectorBase ← EBase[31:12] || 16#000 endif // // vectorBase vectorOffset // 29 30 PC ← {vectorBase[31:30], (vectorBase[29:0] + vectorOffset[29:0])}
上記のアルゴリズムでは、次の点は考慮されません。
- プロセッサのリセットにつながる例外(Reset、SoftReset、NMI-16#BFC00000への移行を引き起こす);
- EJTAG例外;
- キャッシュ/ SPRAMパリティエラー。キャッシュされたセグメントkseg0の代わりにStatus.BEV = 0の場合、キャッシュされていないセグメントkseg1( vectorBase [29] = 1'b1)とEBase [29:12] = 0にマップされます。 、および16#A0000000。 私たちの場合、これは重要ではありません。 MIPSfpgaプロジェクトでは、メモリセグメントが交差し(mfp_ahb_lite_decoderモジュールのRTLコードを参照)、メモリにアクセスするときにアドレスの上位3ビットが無視されます。
- オフセット0x80のXTLB Refil例外。[ D2 ]では説明されていませんが、[ D3 ]および提供されているすべてのコード例で説明されています。 読者の一人がこの点を明確にできれば、その情報に感謝します。
例外の詳細は[ D2 ]にあります。
したがって、割り込みを使用しなくても、開発者は次のオフセットに例外ハンドラがあることを確認する必要があります。
- 16#000-TLB補充ハンドラー。
- 16#080-XTLB Refil;
- 16#100-キャッシュ/ SPRAMパリティエラー。
- 16#180-一般的な例外ハンドラ。
割り込み処理モード
それらの3つだけがあります。
- 割り込み互換モード-互換モード。
- ベクトル割り込み(VI)モード-ベクトルモード。
- 外部割り込みコントローラー(EIC)モード-外部割り込みコントローラーのモード。
デフォルトでは、プロセッサは互換モードで起動します。 将来的には、ビット(フィールド)の対応する値を設定することで変更できます。
- Status.BEV-割り込みハンドラーのベクトルの変位が計算されるベースアドレスを定義し、プログラムで設定されます。リセット後の値は1です。
- Cause.IV-割り込みハンドラーのベクトルの変位を決定し、プログラムで設定されます。リセット後の値は定義されていません。
- IntCtl.VS-ベクトル間の間隔は、ベクトル間のオフセットを決定し、プログラムで設定されます。リセット後の値は0です。
- Config3.VINT-すべてのmicroAptivコアで1に等しい、ベクトル化された割り込み、読み取り専用。 およびMIPSfpgaの場合。
- Config3.VEIC-外部割り込みコントローラーの存在を判別します。読み取り専用で、値はSI_EICPresent信号によって設定されます。
リストされたビット(フィールド)とそれらが関連するレジスタの詳細な説明はドキュメントに記載されています。これらの値の合計が割り込み処理モードに与える影響に注意してください。
システムタイマー
割り込みの処理の説明に進む前に、最も頻繁に発生するソースの1つであるシステムタイマーについて考えてみましょう。 その機能は非常にシンプルですが、プロセッサコアの一部であり、省エネモードで動作することもできるため、どの環境でも使用できます。
これを使用するには、2つのレジスタが使用されます。
- カウント -カウンターの登録。 Cause.DC == 0(カウントレジスタを無効にする、デフォルト= 0)の場合、各プロセッサクロックサイクルで1ずつ増加します。 カウンターをリセットする唯一の方法は、新しい値(たとえば、ゼロ)を書き込むことです。タイマー割り込み信号(等式Count == Compareによって引き起こされる)は、カウンターを自動的にリセットしません。
- 比較 -比較レジスタ。 Count == CompareおよびCompare != 0の場合、割り込みのソースとして機能するSI_TimerInt信号が1に設定され、 Cause.TIビット(タイマー割り込み)が同時に設定されます。 この信号をリセットするには、 Compareに書き込みます。
これらのレジスタを使用するには、mips / cpu.hで宣言されているmips32_setcompareおよびmips32_setcountマクロを使用してタイマーを初期化およびリセットすると便利です。実際には、同じコード[ S0 ]が使用されます。
mips32_setcompare(MIPS_TIMER_PERIOD); //set compare (TOP) value to turn on /reset timer mips32_setcount(0); //reset counter
下のスクリーンショットは、割り込み処理中のタイマーの初期化とリセットの瞬間を示しています。
SI_TimerInt信号の存在は、割り込みを引き起こすには不十分です。 処理するためには、RTLレベルで正しくルーティングする必要があります。RTLレベルは、以下で説明する現在の割り込みモードに依存します。
割り込み互換モード
MIPS32リリース1との下位互換性モード。主な機能:
- 8つの外部割り込みが使用可能です。入力SI_Int [7:0]は、フラグCause.IP9 - IP2に対応しています。
- 2つのソフトウェア割り込みが使用可能です: Cause.IP1 - IP0 ;
- 割り込みが発生した入力に関係なく、制御は1つのハンドラーに転送されます。このハンドラーは、とりわけ、例外の処理を担当します。
- ハードウェア割り込みの優先順位付けはありません。
- 最も優先度の高い割り込みの定義は開発者に残り、 Cause.IP9〜IP0 、 Cause.TIを分析することによりハンドラー内で実行されます。
- タイマー割り込み出力( SI_TimerInt )は、 SI_Int [7:0]入力のいずれかに関連付ける必要があります。 このため、信号を明示的に相互に接続する必要はありません。入力SI_IPTI [2:0]を使用できます。値0x2はSI_TimerIntが SI_Int [0]にそれぞれ接続されることを意味し、0x7はSI_Int [5]への接続を意味します。 SI_Int [5]への接続は従来型と見なされます。
- MIPS32リリース1プロセッサについて話すと、6個の外部割り込みのみが使用可能です( Cause.IP9 - IP8は存在しません)[ D4 ]、ここから、 SI_IPTI [2:0]を使用してタイマー割り込みを他のポートに切り替えることができないことを継承しましたSI_Int [5]より 。 したがって、下位互換性モードは、MIPS32リリース1で最初に利用できた機能よりも多くの機能を提供します。
比較的最近のマイクロコントローラーでの組み込みシステムの開発で初めての経験をした人は、例外の大部分を含む、すべての「わずか」6個の外部割り込みと1つの共通プロセッサーに戸惑うかもしれません。 ここでは、MIPSアーキテクチャのいくつかの歴史を考慮する必要があります。割り込みソースは階層的に接続されると想定され、割り込みへの(からの)入力コードはすべてのハンドラーに共通であると見なされました。 外部デバイスは本質的に低速であるため(イベントはほとんど発生しません)、ソースと優先度の「手動」チェックによる特別なパフォーマンスの損失はなく、可能な最適化の余地さえあります。 [ L5 ]からのそのような接続の例を以下に示します。
これらの機能が「欠点」と見なされた場合でも、MIPSfpgaプロセッサコアの対応するインターフェイスを介して接続された外部割り込みコントローラーを使用する可能性により、対応するセクションで簡単に補償されます。
例
起動順序
- 次の設定がmfp_ahb_lite_matrix_config.vhファイルに設定されていることを確認します(外部割り込みコントローラーを使用するための設定はコメント化する必要があります)[ S1 ]:
`define MFP_USE_WORD_MEMORY //`define MFP_USE_IRQ_EIC
- ディレクトリmipsfpga-plus / Programs / 06_timer_irq /;に移動します。
- main.cファイルで、[ S2 ]を設定します。
#define RUNTYPE COMPATIBILITY
- プログラムをビルドし、シミュレーターで実行します。
02_compile_and_link.bat 05_generate_verilog_readmemh_file.bat 06_simulate_with_modelsim.bat
- シミュレーションスクリプトの完了後、シミュレータが閉じないようにするには「いいえ」をクリックします。
プログラムとシステム構成の説明
RTLヘッダーファイルで設定された設定は、プロセッサコア割り込みインターフェイス[ S3 ]の以下の構成につながります。
assign SI_Offset = 17'b0; //not used assign SI_EISS = 4'b0; //not used assign SI_Int[7:4] = 4'b0; assign SI_Int[3] = uart_interrupt; assign SI_Int[2:0] = 3'b0; assign SI_EICVector = 6'b0; //not used assign SI_EICPresent = 1'b0; //no external interrupt controller assign SI_IPTI = 3'h7; //enable MIPS timer interrupt on HW5
ファイルexceptions.Sには、操作に必要な割り込みベクトルが含まれています。それらはすべてほぼ同じタイプです[ S4 ]:
.org 0x200 # set symbol offset from section beginning .weak __mips_isr_sw0 # if the symbol does not already exist, it will be created __isr_vec_sw0: la $k1, __mips_isr_sw0 # load interrupt handler (__mips_isr_sw0) addr beqz $k1, __general_exception # if it is not present then go to generic nop jr $k1 # jump to irq_sw0 nop
例外ベクターは、対応するハンドラーがプログラムで定義されていない場合、コードループ[ S5 ]が実行されるという点で、割り込みベクターとは異なります。
.org 0x0 # set symbol offset from section beginning .weak _mips_tlb_refill # if the symbol does not already exist, it will be created __tlb_refill: la $k1, _mips_tlb_refill # load exception handler (_mips_tlb_refill) addr beqz $k1, __tlb_refill # if _mips_tlb_refill doen not exist then just loop here nop jr $k1 # jump to _mips_tlb_refill. # we can use 'j _mips_tlb_refill' nop # but it works only with 1st 28 bits of addr
mian.cファイルは、タイマー[ S0 ]を順番に初期化します。
mips32_setcompare(MIPS_TIMER_PERIOD); //set compare (TOP) value to turn timer on mips32_setcount(0); //reset counter
割り込みの初期化[ S6 ]:
//compatibility mode, one common handler // Status.BEV 0 - place handlers in kseg0 (0x80000000) mips32_bicsr (SR_BEV); // Cause.IV, 0 - general exception handler (offset 0x180) mips32_biccr (CR_IV); // interrupt enable, HW5, SR_SINT1 - unmasked mips32_bissr (SR_IE | SR_HINT5 | SR_SINT1);
そして、順次ハンドラーを想定した1つのハンドラーでの処理:この例外が割り込みかどうかを確認し、どの割り込みを処理する必要があるかを判断し、処理自体を実行します[ S7 ]
void __attribute__ ((interrupt, keep_interrupts_masked)) _mips_general_exception () { MFP_RED_LEDS = MFP_RED_LEDS | 0x1; uint32_t cause = mips32_getcr(); //check that this is interrupt exception if((cause & CR_XMASK) == 0) { //check for timer interrupt if(cause & CR_HINT5) { MFP_RED_LEDS = MFP_RED_LEDS | 0x10; n++; mipsTimerReset(); mips32_biscr(CR_SINT1); //request for software interrupt 1 MFP_RED_LEDS = MFP_RED_LEDS & ~0x10; } //check for software interrupt 1 else if (cause & CR_SINT1) { MFP_RED_LEDS = MFP_RED_LEDS | 0x8; mips32_biccr(CR_SINT1); //clear software interrupt 1 flag MFP_RED_LEDS = MFP_RED_LEDS & ~0x8; } } MFP_RED_LEDS = MFP_RED_LEDS & ~0x1; }
- この例では、関連する割り込みフラグ(HW5)を使用してシステムタイマーの割り込みを確認します。このために、 Cause.TI (マクロCR_TI)を使用できます。
- プログラムの各段階は、対応する状態MFP_RED_LEDSに反映されます。
タイマー割り込み(HW5)では、カウンターがインクリメントされ、タイマーがリセットされ、プログラム割り込み要求フラグSW1 [ S8 ]が設定されます。
n++; mipsTimerReset(); mips32_biscr(CR_SINT1);
割り込みSW1では、割り込みフラグのみがリセットされます[ S9 ]:
mips32_biccr(CR_SINT1);
- フラグの操作に使用されるすべてのマクロは、mips / cpu.hで宣言されています。
メイン機能コードでは、カウンターは7セグメントインジケーターに周期的に出力されます[ S10 ]:
for (;;) MFP_7_SEGMENT_HEX = n;
- プログラムの結果は、次のような信号図です。 レジスタの値、特にCauseおよびStatus 、 PC 、 Countおよびompareをリアルタイムで観察できるため、デバッグが大幅に簡素化されることに注意してください。
ベクタ割り込みモード
ベクトル割り込み処理モード。
主な機能:
- 処理された割り込みの数と構成(8つの外部ソフトウェアと2つのソフトウェア)、およびSI_TimerIntを操作する手順は、割り込み互換モードと完全に類似しています。
- 各割り込みを処理するには、独自のハンドラー(ベクター)が使用されます。
- 割り込みには、プロセッサコアによって処理される順序を決定する優先順位があります。 優先度の昇順:SW0、SW1(ソフトウェア割り込み)、HW0-HW7(ハードウェア割り込み、SI_Int信号[7:0]に対応)
- 最初のベクトル割り込みハンドラーはオフセット0x200に配置されます。
- 最初と2番目の間のオフセット、および後続のすべてのハンドラーは、 IntCtl.VSフィールドによって決定されます。 したがって、 IntCtl.VS = 1の場合、このオフセットは0x20になります。
例
起動順序
- main.cファイルに[ S2 ]を設定する必要があることを除いて、下位互換性モードの場合とまったく同じです。
#define RUNTYPE VECTOR
プログラムとシステム構成の説明
- RTLシステム構成は、下位互換性モードの構成と似ています。
- 同じexceptions.Sファイルが使用されます[ S4 、 S5 ]および完全に同一のタイマー初期化順序[ S0 ];
割り込み操作は、次のように構成されます[ S11 ]:
//vector mode, multiple handlers // Status.BEV 0 - place handlers in kseg0 (0x80000000) mips32_bicsr (SR_BEV); // Cause.IV, 1 - special int vector (offset 0x200), // where 0x200 - base for other vectors mips32_biscr (CR_IV); // get IntCtl reg value uint32_t intCtl = mips32_getintctl(); // set interrupt table vector spacing (0x20 in our case) // see exceptions.S for details mips32_setintctl(intCtl | INTCTL_VS_32); // interrupt enable, HW5 and SW0,SW1 - unmasked mips32_bissr (SR_IE | SR_HINT5 | SR_SINT0 | SR_SINT1);
プログラムの操作手順は、タイマー割り込み(HW5)でフラグが1つではなく2つのプログラム割り込み(SW0およびSW1)に設定され、優先順位[ S12 ]で処理されることを除いて、前述とまったく同じです。
void __attribute__ ((interrupt, keep_interrupts_masked)) __mips_isr_hw5 () { MFP_RED_LEDS = MFP_RED_LEDS | 0x4; n++; mipsTimerReset(); mips32_biscr(CR_SINT0); //request for software interrupt 0 mips32_biscr(CR_SINT1); //request for software interrupt 1 MFP_RED_LEDS = MFP_RED_LEDS & ~0x4; }
割り込みSW0を処理するには、別のベクター[ S13 ]が使用されます。
void __attribute__ ((interrupt, keep_interrupts_masked)) __mips_isr_sw0 () { MFP_RED_LEDS = MFP_RED_LEDS | 0x2; mips32_biccr(CR_SINT0); //clear software interrupt 0 flag MFP_RED_LEDS = MFP_RED_LEDS & ~0x2; }
- SW1は、下位互換性モードの場合と同じ_mips_general_exceptionで処理されますが、重要な追加があります。この関数への移行は、プロセッサがすぐにオフセット0x180になったためではありません。 実行は0x220に渡されますが、 mips_isr_sw1関数は宣言されず 、 general_exceptionに移行します(これは、上記のexceptions.Sのアセンブラコードによって実行されます)[ S14 ]。
- プログラムの結果は、次のような信号図です。
外部割り込みコントローラーモード
外部割り込みコントローラー
外部割り込みコントローラーモードでの操作の説明に進む前に、このモジュールがプロセッサーコアとどのように相互作用するか、そしてそれが何であるかを検討します。
コントローラのタスクは、外部割り込みを登録し、それらの最高優先順位に関する情報をバスに発行することです(割り込みインターフェイス)。
- SI_EICPresent-外部割り込みコントローラーの存在の兆候。
- SI_Int [7:0] -要求された割り込みの優先度。
- SI_EISS [3:0] -シャドウセット番号の数を定義します。MIPSfpgaの場合-使用されません。
- SI_EICVector-要求された割り込みのベクトル番号。
- SI_Offset [17:1] -要求された割り込みのオフセット。
次の割り込み要求を処理に取り込むと、プロセッサーはコントローラーに次のように伝えます。
- SI_IAck単一パルスは、割り込み処理の開始を通知します。
- SI_IPL [7:0] -処理された割り込みの優先度。
- SI_IVN [5:0] -処理された割り込みのベクトル番号。
- SI_ION [17:0] -処理された割り込みのオフセット。
コントローラとプロセッサコア間の一般的な相互作用を以下に示します。
次のことも考慮する必要があります。
- なぜなら この場合、割り込みの優先順位付けはプロセッサコアによって実行されないため、それによって生成されるすべての割り込みは、コントローラ入力にも送られる必要があります:システムタイマー割り込み( SI_TimerInt信号、 Cause.TIフラグ)、プログラム割り込み( SI_SWInt信号[1:0] 、 Cause.IP1フラグ- IP0 )およびその他-[ D2 ]により詳細に反映されます。
- カーネルがハンドラーのオフセットアドレスを計算する方法: SI_Offset [17:1]から直接取得するか、 SI_EICVectorから変換するかは、現在アクティブになっているオプション「Option 1-Explicit Vector Number」または「Option 2-Explicit Vector Offset」によって決まります。 最初の場合-64個のベクターが使用可能です。2番目の場合-ベースから256Kのメモリーがカウントされ、ベクターを配置します。これは、割り込みの数に関して最も要求の厳しいタスクにも十分なはずです。 MIPS microAptivコアの商用顧客は、グラフィカルコンフィギュレーターでこのパラメーターを設定します。 MIPSfpgaでは使用できませんが、この設定はファイルm14k_cpz_eicoffset_stub.v:84で実行できます。 これを行うには、 eic_offset値を1に置き換えます。
assign eic_offset = 1'b1;
- コントローラによって要求された割り込みを処理する決定は、最小許容優先度( Status.IPLで設定)に基づいてプロセッサによって行われ、指定された優先度より低い優先度を持つすべての割り込みは無視されます。
MIPSfpga-plus割り込みコントローラー
主な機能:
- MIPSfpga-plus [ L3 ]システムの一部です。
- 最大64個の割り込みが使用可能で、その正確な数は構成ファイル(mfp_eic_core.vh)で設定できます[ S15 ]。
- 2つのタイプの入力チャネルが実装されています。直接(直接チャネル)と感度設定(検出チャネル)です。 まず、割り込み要求の兆候は高信号レベルです。 2つ目は、このパラメーターを構成できます。フロント、フォール、低信号レベル、信号変化。
- タイプセンスチャネルのチャネルの最大数は32です。
- コントローラーのシンプルさにより、必要に応じて、さらに多くの割り込みを実装できます;このためには、コードに小さな変更を加える必要があり、特に構成レジスタを追加する必要があります。
- コントローラの入力で受信されるすべての信号は同期する必要があります。
- 「オプション1-明示的なベクトル番号」モードと「オプション2-明示的なベクトルオフセット」モードの両方で作業をサポートします。
- プロセッサコアによる処理の開始時に割り込みフラグを自動的に下げる機能は、プログラムで構成できます。
- 必要に応じて、コントローラーを備えた別のサンドボックスをgithubで利用できます。この場合、その作業はデバッグされます[ L6 ]。
- コントローラーは上位レベルのMIPSfpga-plus(mfp_system.v)、 EIC_inputでプロセッサーコアに接続されます-割り込みソースからの信号、I / Oの残りはプロセッサー割り込みインターフェイス[ S21 ]を参照します。
`ifdef MFP_USE_IRQ_EIC .EIC_input ( EIC_input ), .EIC_Offset ( SI_Offset ), .EIC_ShadowSet ( SI_EISS ), .EIC_Interrupt ( SI_Int ), .EIC_Vector ( SI_EICVector ), .EIC_Present ( SI_EICPresent ), .EIC_IAck ( SI_IAck ), .EIC_IPL ( SI_IPL ), .EIC_IVN ( SI_IVN ), .EIC_ION ( SI_ION ), `endif //MFP_USE_IRQ_EIC
コントローラーには次のファイルが含まれます。
- mfp_eic_core.v-コントローラーコア[ S17 ];
- mfp_eic_core.vh-メイン構成ファイル(内部のコメントを参照)[ S15 ];
- mfp_eic_handler.v-割り込み番号をベクトル/オフセットに、またはその逆に変換するためのロジックが含まれています(内部のコメントを参照)[ S18 ];
- mfp_eic_priority_encoder.v-階層的な(ツリーのような)組織を持つ優先順位エンコーダー[ S19 ];
- mfp_ahb_lite_eic.vは、AHB-Liteバス[ S20 ]とのインターフェースを提供する最上位モジュールです。
コントローラー構成の一般的な考え方を形成するために、構成レジスターとその完全な説明を[ D5 ]にリストします。 EICR 、 EISMSK_0およびEISMSK_1を除くすべてのレジスタでは、ビット番号がコントローラーの入力番号に対応すると想定されています。 したがって、たとえば、 EIFR_0 [3] = 1-入力3は未処理の割り込みを予期することを意味します。
例
起動順序
- 次のモード[ S1 ]がmfp_ahb_lite_matrix_config.vhファイルで設定されていることを確認します。
`define MFP_USE_IRQ_EIC `define MFP_USE_WORD_MEMORY
- パラメーターがm14k_cpz_eicoffset_stub.vファイルで設定されていることを確認します。
assign eic_offset = 1'b0;
- ディレクトリmipsfpga-plus / Programs / 07_eic /;に移動します。
- プログラムをビルドし、シミュレーターで実行します。
02_compile_and_link.bat 05_generate_verilog_readmemh_file.bat 06_simulate_with_modelsim.bat
- シミュレーションスクリプトの完了後、シミュレータが閉じないようにするには「いいえ」をクリックします。
プログラムとシステム構成の説明
RTLヘッダーファイルで設定された設定は、次の構成につながります[ S16 ]:
wire [ `EIC_CHANNELS - 1 : 0 ] EIC_input; assign EIC_input[`EIC_CHANNELS - 1:8] = {`EIC_CHANNELS - 6 {1'b0}}; assign EIC_input[7] = SI_TimerInt; assign EIC_input[6] = 1'b0; assign EIC_input[5] = uart_interrupt; assign EIC_input[4:2] = 3'b0; assign EIC_input[1] = SI_SWInt[1]; assign EIC_input[0] = SI_SWInt[0]; assign SI_IPTI = 3'h0;
- 割り込みインターフェイスバス信号は、上記のようにmfp_ahb_lite_eicモジュールによって処理されます。
exceptions.Sファイルは、割り込みの名前と番号を除いて、前の2つの例に似ています。したがって、最新のHW63はオフセット0x9E0 [ S22 ]にあります。
.org 0x9E0 .weak __mips_isr_eic63 __isr_vec_eic63: la $k1, __mips_isr_eic63 beqz $k1, __general_exception nop jr $k1 nop
- コントローラのレジスタを操作するために必要なすべてのマクロは、eic.hファイルに転送されます[ S23 ]。
- main.cのタイマーの初期化は、以前と同じ方法で実行されます。
割り込みの初期化[ S24 ]:
//eic mode //unmask interrupt MFP_EIC_EIMSK_0 = (1 << IRQSW0) | (1 << IRQSW1) | (1 << IRQTIMER); MFP_EIC_EIMSK_1 = (1 << IRQ63); //enable auto clear MFP_EIC_EIACM_0 = (1 << IRQSW0) | (1 << IRQSW1) | (1 << IRQTIMER); //set interrupt on rising edge of the signal MFP_EIC_EISMSK_0 = (SMSK_RIZE << SMSKSW0) | (SMSK_RIZE << SMSKSW1) | (SMSK_RIZE << SMSKTIMER); // Status.BEV 0 - vector interrupt mode mips32_bicsr (SR_BEV); // Cause.IV, 1 - special int vector (0x200) // where 0x200 - base when Status.BEV = 0; mips32_biscr (CR_IV); // get IntCtl reg value uint32_t intCtl = mips32_getintctl(); // set interrupt table vector spacing (0x20 in our case) // see exceptions.S for details mips32_setintctl(intCtl | INTCTL_VS_32); // enable external interrupt controller // enable interrupts MFP_EIC_EICR = 0x1; mips32_bissr (SR_IE);
- RTL : interrupt_sence — [ S28 ], interrupt_channel — EIFR [ S29 ]. priority_encoder — EIC_input , [ S19 ]. handler_params_encoder [ S18 ], /;
, (Option 2 — Explicit Vector Offset), (m14k_cpz_eicoffset_stub.v), mfp_eic_core.vh [ S15 ]
`define EIC_USE_EXPLICIT_VECTOR_OFFSET
- / , .. , mfp_eic_handler.v IntCtl.VS = 1 (32 ) [ S25 ];
, [ S26 ]:
ISR(IH_SW0) { MFP_RED_LEDS = MFP_RED_LEDS | 0x1; mips32_biccr(CR_SINT0); //clear software interrupt 0 flag MFP_RED_LEDS = MFP_RED_LEDS & ~0x1; }
- ISR EH_GENERAL eic.h [ S27 ];
- :
- :
void __attribute__ ((interrupt)) v0 (); void __attribute__ ((interrupt, use_shadow_register_set)) v1 (); void __attribute__ ((interrupt, keep_interrupts_masked)) v2 (); void __attribute__ ((interrupt, use_debug_exception_return)) v3 (); void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) v4 (); void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) v5 (); void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) v6 (); void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked, use_debug_exception_return)) v7 (); void __attribute__ ((interrupt("eic"))) v8 (); void __attribute__ ((interrupt("vector=hw3"))) v9 ();
:
- use_shadow_register_set , .. MIPSfpga;
- interrupt("vector=hw3") ;
- , (interrupt, keep_interrupts_masked), :
void __attribute__ ((interrupt, keep_interrupts_masked)) __mips_isr_sw0 () { 80001544: 401b7000 mfc0 k1,c0_epc 80001548: 27bdfff0 addiu sp,sp,-16 8000154c: afbb000c sw k1,12(sp) 80001550: 401b6000 mfc0 k1,c0_status 80001554: afbb0008 sw k1,8(sp) // k1 status.exl,.erl,.um, .ie; 80001558: 7c1b2004 ins k1,zero,0x0,0x5 // status 8000155c: 409b6000 mtc0 k1,c0_status 80001560: afbe0004 sw s8,4(sp) 80001564: 03a0f025 move s8,sp ... } 80001568: 03c0e825 move sp,s8 8000156c: 8fbe0004 lw s8,4(sp) 80001570: 8fbb000c lw k1,12(sp) 80001574: 409b7000 mtc0 k1,c0_epc 80001578: 8fbb0008 lw k1,8(sp) 8000157c: 27bd0010 addiu sp,sp,16 80001580: 409b6000 mtc0 k1,c0_status 80001584: 42000018 eret
- , (interrupt), :
void __attribute__ ((interrupt)) __mips_isr_hw5 () { 80001588: 401a6800 mfc0 k0,c0_cause 8000158c: 401b7000 mfc0 k1,c0_epc 80001590: 27bdfff0 addiu sp,sp,-16 80001594: afbb000c sw k1,12(sp) 80001598: 401b6000 mfc0 k1,c0_status // k0 cause.ip7-ip2 8000159c: 001ad282 srl k0,k0,0xa 800015a0: afbb0008 sw k1,8(sp) // k1 cause.ip6-ip2 status.im7-im2 800015a4: 7f5b7a84 ins k1,k0,0xa,0x6 // k1 status.exl,.erl,.um; // .ie ( 1) 800015a8: 7c1b2044 ins k1,zero,0x1,0x4 // status 800015ac: 409b6000 mtc0 k1,c0_status 800015b0: afbe0004 sw s8,4(sp) 800015b4: 03a0f025 move s8,sp ... } 800015b8: 03c0e825 move sp,s8 800015bc: 8fbe0004 lw s8,4(sp) //disable interrupts (status.ie = 0) 800015c0: 41606000 di 800015c4: 000000c0 ehb 800015c8: 8fbb000c lw k1,12(sp) // epc 800015cc: 409b7000 mtc0 k1,c0_epc 800015d0: 8fbb0008 lw k1,8(sp) 800015d4: 27bd0010 addiu sp,sp,16 // status 800015d8: 409b6000 mtc0 k1,c0_status 800015dc: 42000018 eret
- , keep_interrupts_masked, , . .
謝辞
« », Imagination Technologies YuriPanchul MIPSfpga.
参照資料
[L1] — ;
[L2] — MIPSfpga ;
[L3] — MIPSfpga-plus github ;
[L4] — FPGA Terasic DE10-Lite ;
[L5] — Embedded Linux System Design and Development P. Raghavan, Amol Lad, Sriram Neelakandan ( );
[L6] — ahb_lite_eic github ;
[L7] — Codescape MIPS SDK ;
ドキュメント
[D1] — MIPS32 microAptiv UP Processor Core Family Integrator's Guide ;
[D2] — MIPS32 microAptiv UP Processor Core Family Software User's Manual ;
[D3] — Codescape GNU Tools for MIPS Programmer's Guide ;
[D4] — MIPS32 Architecture For Programmers Volume III: The MIPS32 Privileged Resource Architecture ;
[D5] — MIPSfpga+ External Interrupt Controller ;
[D6] — MIPS32 microAptiv UP Processor Core Family Datasheet ;
[P0] — MIPS 32 microAptiv UP Core Block Diagram (: D6 );
[P1] — ;
[P2] — MIPS. ();
[P3] — (: L5 );
[P4] — . ();
[P5] — (: D2 );
[P6] — (: D2 );
[P7] — (: D2 );
[P8] — . ();
[P9] — (: D2 );
[P10] — (: D1 );
[P11] — (: L6 );
[P12] — , ();
[P13] — , ().
[S0] — ;
[S1] — mipsfpga-plus ;
[S2] — 06_timer_irq ;
[S3] — mipsfpga-plus ;
[S4] — ;
[S5] — ;
[S6] — ;
[S7] — ;
[S8] — ;
[S9] — ;
[S10] — main 06_timer_irq ;
[S11] — ;
[S12] — ;
[S13] — ;
[S14] — ;
[S15] — mipsfpga-plus ;
[S16] — mipsfpga-plus ;
[S17] — ;
[S18] — ;
[S19] — ;
[S20] — AHB-Lite ;
[S21] — ;
[S22] — HW63 ;
[S23] — ;
[S24] — ;
[S25] — 外部割り込みのコントローラーモードでのベクトルオフセット増分の設定。
[S26]- 外部割り込みのコントローラーモードでの割り込みハンドラー。
[S27]- マクロISRおよびEH_GENERAL ;
[S28]- モジュールinterrupt_sence ;
[S29]-interrupt_channel モジュール。