FPGA開発日記

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

LiteXによるSoC環境構築を試行する (割込みの接続)

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

PLICの実装を試している。自作CPUのSoC環境にPLICをインスタンスして接続する。

PLICの実装は、どこからかオープンソースのものを取ってこようと思う。

github.com

とりあえず以下のように接続する。

logic [ 7: 0] w_ie       [1];  // Interrupt enable per source, for each target
logic [ 2: 0] w_ipriority[8];  // Priority for each source (priority is a reserved keyword)
logic [ 2: 0] w_threshold[1];  // Priority Threshold for each target

logic [ 0: 0] w_int_req;
logic [ 3: 0] w_int_id[1];
logic [ 0: 0] w_int_claim;
logic [ 0: 0] w_int_complete;

assign w_ie[0] = {8{w_plic_if.ie}};
assign w_ipriority[0] = 3'h0;
assign w_ipriority[1] = 3'h0;
assign w_ipriority[2] = 3'h0;
assign w_ipriority[3] = 3'h0;
assign w_ipriority[4] = 3'h0;
assign w_ipriority[5] = 3'h0;
assign w_ipriority[6] = 3'h0;
assign w_ipriority[7] = 3'h0;
assign w_threshold[0] = 3'h0;

assign w_plic_if.int_id = w_int_id[0];


plic_core
  #(
    .SOURCES           (8), //Number of interrupt sources
    .TARGETS           (1), //Number of interrupt targets
    .PRIORITIES        (8), //Number of Priority levels
    .MAX_PENDING_COUNT (0)
    )
u_plic_core
  (
   .clk   (i_clk),     // Input: System clock
   .rst_n (i_reset_n), // Input: Active low asynchronous reset

   .src       (i_interrupts),           // Input: Interrupt request from devices/sources
   .el        (1'b0),                   // Input: Edge/Level sensitive for each source
   .ip        (w_plic_if.ip), // Output: Interrupt Pending for each source

   .ie        (w_ie),                   // Input: Interrupt enable per source, for each target
   .ipriority (w_ipriority),            // Input: Priority for each source (priority is a reserved keyword)
   .threshold (w_threshold),            // Input: Priority Threshold for each target

   .ireq      (w_plic_if.int_valid   ),         // Output: Interrupt request for each target
   .id        (w_int_id              ),         // Output: Interrupt ID (1..SOURCES), for each target
   .claim     (1'b0                  ),         // Input: Interrupt claim
   .complete  (w_plic_if.int_complete)          // Input: Interrupt handling complete
   );

ここで、claimポートについてはなんだかよく分からないのでとりあえず0に設定している。それ以外は、ピンをPLICとCPUの間で接続して、CSRに結び付けている。

PLICの割込みポートの接続は以下のようにする。

        # CPU Instance.
        self.cpu_params = dict(
            # Clk / Rst.
            i_i_clk       = ClockSignal("sys"),
            i_i_reset_n   = ~ResetSignal("sys") | self.reset,

            # Interrupts
            i_i_interrupts = self.interrupt,

これで一応Verilatorのコンパイルが通るようになったので、デバッグ開始だ。