Cmod A7ボード(FPGA)を使って、オリジナル16ビットCPUコアMoscoviumの開発を進めています。
前々回から、1つのマイコン上に多数のCPUコアを集積する、多コア化をテーマに考察を重ねています。
前回までに、多数CPU → 1系統メモリバスに関する検討は終わりました。
今度は、多数割り込み要因 → 複数CPUコアへの割り込み要求について検討して行きましょう。
現在のデュアルコア対応版割り込みコントローラINTC322DVLでは、以下の様な、高水準割り込み機能に対応しています。
INTC322DVLはデュアルコア対応版で、各CPU毎に割り込み要因をマスク😷することができます(下図)。
I/Oユニットから要求される割り込み要因毎に、どちらのCPUに割り込みを要求するのか、割り込みマスクintmskレジスタによって選択可能なのです。
これらの高水準な割り込み機能を14コア全てに適用するのは困難です。困難だし、そもそも14コア全てがセマフォなどの排他制御をこなした上でI/Oユニットにアクセスするプログラムなんて、複雑すぎて作りたくありません。ですよね?
I/Oユニットからの割り込みを受け付けられるCPUは、1個か2個に限定して良いはずです。INTC322DVLはデュアルコア対応の割り込みコントローラなので、最大14個のCPUの内、最初の2個、CPU1とCPU2だけがINTC322DVLからの割り込みを受け、全機能を使用可能とします。
その他のCPU3〜CPU14は、別途、ポリコア専用の割り込み(POLYC144ユニット、詳細は次節)を作って、その割り込み要因だけを受け付けられる様にしておきます(下図)。
ポリコア専用割り込みだけを受けるCPU3〜CPU14は、割り込みレベルおよびベクタ割り込みには非対応とします。十分許容可能な仕様制限だと考えられます。
なお、本節で議論した通り、今回のポリコア版では割り込みに関して対称ではありません。と言って、AMP(Asymmetric Multi-Processing)か?と言うと、そこまでの非対称性は無いので、どちらかと言うなら、SMP(Symmetric Multi-Processing)と言う事になるはずです。
ポリコア専用割り込みの他にも、共有リソースの管理を実施するセマフォなど、必要となる機能を1つのI/Oユニットにまとめて持たせようと思います。これをポリコア制御POLYC144ユニットと呼び、以下の様な機能を盛り込みます。
ポリコアは、4コア〜14コアまでのコンパイルオプションに対応します。プログラムを作成するに当たって、搭載されたコア数を動的に把握したいはずです。
この要求に対応するため、搭載されたコア数を読み出し可能なレジスタを用意しておきたいと思います。
14個ものCPUコアに協調動作させるためには、互いのCPU間で通信しながらプログラムを実行する必要が生じます。
特定の共有RAM領域に通信エリアを確保して、各CPUがポーリングするのも1つの解でしょう。しかし、ポーリングでは定期的に共有メモリへのアクセスが発生し、メモリバスのボトルネックによってパフォーマンスを落としてしまう恐れがあります。
そこで、CPU間の割り込みにより、通信する機構が必要だと考えました。ポリコア(14コア)用のCPU間割り込みを用意しなくてはなりません。
デュアルコア用に作成したセマフォSEMPH5R12Uユニットは、CPUコア数が2個であることが前提です。ポリコア版でも使えない事は無いのですが、全く機能が不足しています。よって、ポリコア(14コア)用のセマフォを作っておく必要があります。
こちらも、セマフォの取得や返却に於いてバストラフィックを増加させない様、取得要求に待ち行列を作ったり、取得できた時に割り込みで知らせる機構を作り込んでおきます。
ポリコア用の必要機能を統合した、ポリコア制御POLYC144ユニットを設計しました。以下にブロック図を示し、解説を続けます。
※薄黄色の箱はCPUからアクセス可能なI/Oレジスタです。
以下表にI/Oレジスタマップを示し、解説を続けます。
Addr | Name | R/W | Bit:15〜8 | Bit:7〜0 | Memo | ||||||||||||||
0xf1a0 | polyctl | RW | − | − | − | − | − | − | − | − |
SE RR |
− |
PC IE |
PS IE |
NCPU[3:0] | poly-core control | |||
0xf1a2 | − | − | − | − | − | − | − | − | − | − | − | − | − | − | − | − | − | − | reserved |
0xf1a4 | polyintr | R | − | FLAG[14:1] | − | poly-core inter cpu interrupt | |||||||||||||
W | − | − | − | − | − | − | − | − | CMD[3:0] | CID[3:0] | |||||||||
0xf1a6 | polyintm | R | − | MASK[14:1] | − | poly-core interrupt mask | |||||||||||||
W | − | − | − | − | − | − | − | − | CMD[3:0] | CID[3:0] | |||||||||
0xf1a8 | polysmph0 | RW | − | − | − | − | − | − | − | − | CMD[3:0] | CID[3:0] | poly-core semaphore 0 | ||||||
0xf1aa | polysmph1 | RW | − | − | − | − | − | − | − | − | CMD[3:0] | CID[3:0] | poly-core semaphore 1 | ||||||
0xf1ac | polysmph2 | RW | − | − | − | − | − | − | − | − | CMD[3:0] | CID[3:0] | poly-core semaphore 2 | ||||||
0xf1ae | polysmph3 | RW | − | − | − | − | − | − | − | − | CMD[3:0] | CID[3:0] | poly-core semaphore 3 |
BUSC出力のセレクト信号はbcs_poly_nです。上表の範囲でアサートされるので、POLYC144ユニット内では、アドレスbadr[3:0]を復号してレジスタを特定しています。このI/Oユニットはバイトアクセス禁止です。必ずワードアクセスしてください。
I/Oレジスタ仕様:
メインCPU(CPU1)とサブCPU(CPU2)は、通常の割り込みコントローラINTC322DVLと接続されていて、I/Oユニットからの割り込みを受けたり、ベクタ割り込み機能や割り込みレベルなどの高水準な割り込み処理が可能なCPUです。
他のポリコアCPU(CPU3〜CPU14)と同様、ポリコアCPU間割り込みの対象でもあり、polyintrレジスタを使ったポリコアCPU間割り込みを受け付けることができます。ただし、CPU1とCPU2は、ポリコア制御POLYC144ユニットからのポリコアCPU間割り込みを、割り込みコントローラINTC322DVLが持つCPU間割り込みICR1,ICR2として受け取ります。
従って、CPU1,CPU2に於いて、ICR1,ICR2割り込みを受け付けた場合、intcpuレジスタと、polyintrレジスタやpolysmphレジスタを確認して、ポリコアCPU間割り込みとの切り分けを実行する必要があることに注意してください。
それ以外のポリコアCPU(CPU3〜CPU14)は、割り込みコントローラINTC322DVLからの割り込みを受け付けることができず、ポリコア専用割り込みだけを受け付け可能なので、polyintrレジスタおよびpolysmphレジスタだけを確認すれば、割り込み要因を特定できます。
POLYC144ユニットを含むI/Oユニットへのアクセスはメモリバス経由です。最大14個のCPUがバス権調停を経て、メモリバスにアクセスする事ができます。
セマフォを取得するために、特定のレジスタをポーリングするような構成にしてしまうと、メモリバスのボトルネックによって、ポーリングだけでバスサイクルが溢れてしまう事が予想されます。
バスボトルネック対策:
上の対策二点によって、ポーリングせずにセマフォの取得を実行することができ、メモリバスのトラフィックを減らすことができるでしょう。
同じCPUが同じセマフォに対して、セマフォ取得を2回以上連続して要求する必要は無いので、FIFOはCPUのコア数以上あれば十分なはずです。今回、POLYC144ユニットでは最大コア数が14個なので、2冪数で16段FIFOとしてあります。
同じCPUが、同じセマフォに対して、同時に二回以上の取得要求を出すと、FIFOフルとなってエラーが発生する場合があります。エラーが発生すると、polyctlレジスタのSERRフラグに1が立って、ポリコアセマフォが動作を停止します。
SERRビットが経つと、ポリコアセマフォをリセットするしか手が無くなってしまうので、エラーが発生しない様に使うのは、ソフトウェア(ユーザプログラム)側の責任です。
周辺回路の設計も終わりましたので、次回は全体を組み上げて、ポリコア版Moscoviumマイコンを実現してみます。