FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-VのPlatform Level Interrupt Controller(PLIC)の構造について (2. 仕様書を読み解く)

以下のPLICのオープンソース実装を使って自作CPUに接続していたのだが、どうもメモリマップが違う気がする。 かなり古い実装なので、現在の仕様と違うのはやむなしか...

github.com

なんか結局は自分で実装しなければならないような気がしているので、一生懸命仕様書を読んでいる。

github.com

仕様書を読み漁って、なんとなく必要なレジスタ群が分かってきた。

  • Priorityレジスタ (割り込みソースの数だけ用意される)
    • 割り込みソースの優先度を指定するレジスタ。 1要素毎に4バイトの領域を確保される。優先度のサイズに応じて書き込めるレジスタの大きさは異なる。
    • 例えばSiFiveの実装だと、HARTの数に応じてPriorityの最大値が変わるようだ。
    • Priority = 0は割り込み禁止に相当する。
base + 0x000000: Reserved (interrupt source 0 does not exist)
base + 0x000004: Interrupt source 1 priority
base + 0x000008: Interrupt source 2 priority
...
base + 0x000FFC: Interrupt source 1023 priority
  • Pendingレジスタ (割り込み要求が通知され、まだCompleteしていない状態)
    • 割り込みソースの数だけ定義される。ビット列としてレジスタ定義される。つまり、32ビットレジスタで32個の割り込みソースを表現する。
base + 0x001000: Interrupt Pending bit 0-31
...
base + 0x00107C: Interrupt Pending bit 992-1023
  • Enableビット (割り込み要求許可をしたソースおよびHARTの組)
    • 各HARTにつき定義される。割り込み要求許可をしたソースをビット列として定義する。つまり、32ビットレジスタで32ビットの割り込みソースを表現する。

    • HART0向けのEnableレジスタ

base + 0x002000: Enable bits for sources 0-31 on context 0
base + 0x002004: Enable bits for sources 32-63 on context 0
...
base + 0x00207C: Enable bits for sources 992-1023 on context 0
base + 0x002080: Enable bits for sources 0-31 on context 1
base + 0x002084: Enable bits for sources 32-63 on context 1
...
base + 0x0020FC: Enable bits for sources 992-1023 on context 1
base + 0x1FFFFC: Reserved
base + 0x200000: Priority threshold for context 0
base + 0x200004: Claim/complete for context 0
base + 0x200008: Reserved
base + 0x201000: Priority threshold for context 1
base + 0x201004: Claim/complete for context 1
...

RISC-VのPlatform Level Interrupt Controller(PLIC)の構造について (1. 仕様書を読み解く)

以下のPLICのオープンソース実装を使って自作CPUに接続していたのだが、どうもメモリマップが違う気がする。 かなり古い実装なので、現在の仕様と違うのはやむなしか...

github.com

なんか結局は自分で実装しなければならないような気がしているので、一生懸命仕様書を読んでいる。

github.com

割り込み

  • 以下の図は、PLICを介して割り込みを処理するときにエージェント間を流れるメッセージを示している。
    • グローバル割り込みは、各ソースから割り込みゲートウェイに送信される。
    • 次に、割り込みゲートウェイは単一の割り込み要求をPLICコアに送信しし、コア割り込み保留中のビット(IP)を設定する。
    • PLICコアは、Pending通知を1つ以上のターゲットに転送する。ターゲットには保留中のPendingが有効になっており、保留中のPendingにおける優先順位はターゲットごとのしきい値を超えている場合に送信される。
    • ターゲットが外部割り込みを取得すると、割り込みClaimを送信する。最優先のグローバル割り込みの識別子を取得するように要求する。
    • PLICコアは、対応する割り込みソースを保留中のビットをクリアする
    • ターゲットが割り込みを処理した後、ゲートウェイはPending完了メッセージを送信する。
    • 割り込みゲートウェイは初期状態に戻る。
  • 割り込みゲートウェイ 割り込みの数だけ用意される。外部から割込みが挿入されると、それをレジスタに格納する。PLICのCompleteが入力されるとレジスタは解放される。 Completeが入力されるまでの間はInflightとなり、同じ割込みポートから新たな割り込みを挿入できない。

LiteXによるSoC環境構築を試行する (PLICの接続作業)

https://raw.githubusercontent.com/enjoy-digital/litex/master/doc/litex.png

PLICの接続について、ひたすらバスをつなげて実装している。とりあえずコンパイルが通るようになったが、 まだシミュレーションが止まってしまうので、波形を見て要解析だな...

[serial2console] loaded (0x55e25615cef0)
[gmii_ethernet] loaded (0x55e25615cef0)
[ethernet] loaded (0x55e25615cef0)
[clocker] loaded
[xgmii_ethernet] loaded (0x55e25615cef0)
[serial2tcp] loaded (0x55e25615cef0)
[spdeeprom] loaded (addr = 0x0)
[clocker] sys_clk: freq_hz=1000000, phase_deg=0
------------------------------------------------------------
 ,------.                    ,--.                ,--.
 |  .--. ' ,---.  ,--,--.    |  |    ,---. ,---. `--' ,---.
 |  '--'.'| .-. |' ,-.  |    |  |   | .-. | .-. |,--.| .--'
 |  |\  \ ' '-' '\ '-'  |    |  '--.' '-' ' '-' ||  |\ `--.
 `--' '--' `---'  `--`--'    `-----' `---' `-   /`--' `---'
                                           `---'
 RISC-V Platform Level Interrupt Controller
- Configuration Report -------------------------------------
 Sources | Targets | Priority-lvl | Threshold? | Event-Cnt
    64   |    4    |      8       |    YES     |    8
- Register Map ---------------------------------------------
 Address  Function               Mapping
 0x00000000   Configuration          15'h0,TH,PRIORITES,TARGETS,SOURCES
 0x00000010   Edge/Level             64'h0, EL[63:0]
 0x00000020   Interrupt Priority     1'b0,P[31][2:0],1'b0,P[30][2:0],1'b0,P[29][2:0],1'b0,P[28][2:0],1'b0,P[27][2:0],1'b0,P[26][2:0],1'b0,P[25][2:0],1'b0,P[24][2:0],1'b0,P[23][2:0],1'b0,P[22][2:0],1'b0,P[21][2:0],1'b0,P[20][2:0],1'b0,P[19][2:0],1'b0,P[18][2:0],1'b0,P[17][2:0],1'b0,P[16][2:0],1'b0,P[15][2:0],1'b0,P[14][2:0],1'b0,P[13][2:0],1'b0,P[12][2:0],1'b0,P[11][2:0],1'b0,P[10][2:0],1'b0,P[9][2:0],1'b0,P[8][2:0],1'b0,P[7][2:0],1'b0,P[6][2:0],1'b0,P[5][2:0],1'b0,P[4][2:0],1'b0,P[3][2:0],1'b0,P[2][2:0],1'b0,P[1][2:0],1'b0,P[0][2:0]
 0x00000030   Interrupt Priority     1'b0,P[63][2:0],1'b0,P[62][2:0],1'b0,P[61][2:0],1'b0,P[60][2:0],1'b0,P[59][2:0],1'b0,P[58][2:0],1'b0,P[57][2:0],1'b0,P[56][2:0],1'b0,P[55][2:0],1'b0,P[54][2:0],1'b0,P[53][2:0],1'b0,P[52][2:0],1'b0,P[51][2:0],1'b0,P[50][2:0],1'b0,P[49][2:0],1'b0,P[48][2:0],1'b0,P[47][2:0],1'b0,P[46][2:0],1'b0,P[45][2:0],1'b0,P[44][2:0],1'b0,P[43][2:0],1'b0,P[42][2:0],1'b0,P[41][2:0],1'b0,P[40][2:0],1'b0,P[39][2:0],1'b0,P[38][2:0],1'b0,P[37][2:0],1'b0,P[36][2:0],1'b0,P[35][2:0],1'b0,P[34][2:0],1'b0,P[33][2:0],1'b0,P[32][2:0]
 0x00000040   Interrupt Enable       64'h0, IE[0][63:0]
 0x00000050   Interrupt Enable       64'h0, IE[1][63:0]
 0x00000060   Interrupt Enable       64'h0, IE[2][63:0]
 0x00000070   Interrupt Enable       64'h0, IE[3][63:0]
 0x00000080   Priority Threshold     125'h0, Th[0][2:0]
 0x00000090   Priority Threshold     125'h0, Th[1][2:0]
 0x000000a0   Priority Threshold     125'h0, Th[2][2:0]
 0x000000b0   Priority Threshold     125'h0, Th[3][2:0]
 0x000000c0   ID                     121'h0, ID[0][6:0]
 0x000000d0   ID                     121'h0, ID[1][6:0]
 0x000000e0   ID                     121'h0, ID[2][6:0]
 0x000000f0   ID                     121'h0, ID[3][6:0]
- End Configuration Report ---------------------------------

DIGITAL ELECTRONICS NOTESをやってみる

以下のデジタル回路の問題をやってみる。 あんまり時間がないので、DeepLで翻訳してメモしてみようかな。

lancamentomerlo.my.canva.site

  • Q1. ある数体系から他の数体系への変換

16進数の0x3Aは10進数で何ですか? 10進数以外の数字から10進数への変換は、次の手順で行います。 最下位桁から始まり、最上位桁へ移動します。 各桁に「乗」をかけます.<ベース><ビット位置>のべき乗 各桁の結果を合計する

Therefore: 0x3A = [0xA * 16^0] + [0x3 * 16^1] = [10*1 + 3*16] = 58

グレイコードは、2つの連続する値が1ビットだけ異なる2進数のシステムです。反射型とも呼ばれます。バイナリコード 次の表は、0から7までの値に対するグレイコードとバイナリコードを示しています。

バイナリコードでは、2つの値の間の遷移は2つ以上のビットで遷移する可能性があり、これは時に曖昧さにつながる可能性があります。曖昧さが生じる場合があります。例えば、2進数で3から4へ遷移する場合(011から100)。 は、すべてのビットがトグルする必要があります。このため、例えば3つのビットの切り替え時間が異なる場合、中間値が発生することがあります。 しかし、グレイコードでは、常に1ビットしか変化しないため、このような曖昧さが生じない。 グレイコードのもう一つの利点は、トグルするビットの数が少ないため、グレイコードを使用した設計は消費電力が少ないことです。グレーコードではトグルするビットが少ないため、バイナリコードに比べて消費電力が少なくなります。

LiteXによるSoC環境構築を試行する (シリアルコンソールの解析)

https://raw.githubusercontent.com/enjoy-digital/litex/master/doc/litex.png

シリアルコンソールが反応しない問題、FSTを吐いているときに、前回間違ってfstのdump()を入れてしまっており 処理が非常に遅くなってしまっていた。dump()を解除するとFSTを取得しながらキーボードを叩くことができるようになった。

interruptがかからない問題は、UARTのメモリマップドレジスタがAXI経由で正しくアクセスできていなかったせいだった。 AXIに載せるときは、32-bitのバス幅の場合は書き込みメモリアドレスは32-bit alignにして、ストローブなどの場所を調整する必要があるということか。

これでPLICから割込みを受け付けることができるようになった。 コード自体が動作していなかったので確認したが、PLICをメモリマップに配置する必要があるらしい。これも実装しなきゃな...

github.com

LiteXによるSoC環境構築を試行する (シリアルコンソールの解析)

https://raw.githubusercontent.com/enjoy-digital/litex/master/doc/litex.png

シリアルコンソールが反応しない問題、FSTを吐いているときに、前回間違ってfstのdump()を入れてしまっており 処理が非常に遅くなってしまっていた。dump()を解除するとFSTを取得しながらキーボードを叩くことができるようになった。

波形を取得すると、serialインタフェースは動いているようだが、interruptがかかっていない? ここの動作は、解析が必要だと思うので、やっていこう。

LiteXによるSoC環境構築を試行する (シリアルコンソールの解析)

https://raw.githubusercontent.com/enjoy-digital/litex/master/doc/litex.png

シリアルコンソールが反応しない問題、FSTを吐きながらキーボードを叩こうとするとかなり遅くなった挙句、キーボードが反応しない。

これはもうちょっとデバッグの方法を考えなければならない。 一つはVCD出力にして、波形の出力をしやすくしなければ。