Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Xilinx ZynqMP SoC VIP の中を調べる(その6)

はじめに

Xilinx ZynqMP SoC VIP の中を調べる(その6)

今回は、 zynq_ultra_ps_e_vip_v1_0_12_apis.sv の割り込み関連を見ていきます。

VIPなのに、割り込み処理

Zynq Ultrascale+ MPSoC なので、割り込みを受けます。

APIとして提供されているのは、

  • 割り込み状態を見る : read_interrupt
  • 割り込みが来るまで待つ : wait_interrupt

の2つです。

read_interrupt

read_interrupt は、task で引数 irq_status が戻り値です。この irq_status が 割り込みの状態になります。下位8ビットがPLPSIRQ0、上位8ビットがPLPSIRQ1 の状態です。

  /* API to read interrupt status */
  task automatic read_interrupt;
    output[irq_width-1:0] irq_status;
    begin
      irq_status = {PLPSIRQ1,PLPSIRQ0};
      if(DEBUG_INFO) $display("[%0d] : %0s : Reading Interrupt Status as 0x%0h",$time, DISP_INFO,  irq_status);
    end
  endtask

irq_width は、zynq_ultra_ps_e_vip_v1_0_12_local_params.sv の中で以下のように 16 になっています。16ビットのステータスになるということです。

parameter irq_width = 16;

wait_interrupt

wait_interrupt も task で入力 irq[3:0] と 出力 irq_status [irq_width-1:0] の2つの引数を持ちます。irq_status は、read_interrupt と同じです。入力の irq の割り込みが入ってくるまでウエイトします。入力は4ビットなので、16ステートを区別できます。この16は出力の irq_status のビット幅と同じになります。irq のデコードは、irq_status の LSB から順になっています。

  /* API to wait on interrup */
  task automatic wait_interrupt;
    input [3:0] irq;
    output[irq_width-1:0] irq_status;
    begin
      if(DEBUG_INFO) $display("[%0d] : %0s : Waiting on Interrupt irq[%0d]",$time, DISP_INFO,  irq);

      case(irq)
      0 :  wait(PLPSIRQ0[0] === 1'b1);
      1 :  wait(PLPSIRQ0[1] === 1'b1);
      2 :  wait(PLPSIRQ0[2] === 1'b1);
      3 :  wait(PLPSIRQ0[3] === 1'b1);
      4 :  wait(PLPSIRQ0[4] === 1'b1);
      5 :  wait(PLPSIRQ0[5] === 1'b1);
      6 :  wait(PLPSIRQ0[6] === 1'b1);
      7 :  wait(PLPSIRQ0[7] === 1'b1);
      8 :  wait(PLPSIRQ1[0] === 1'b1);
      9 :  wait(PLPSIRQ1[1] === 1'b1);
      10:  wait(PLPSIRQ1[2] === 1'b1);
      11:  wait(PLPSIRQ1[3] === 1'b1);
      12:  wait(PLPSIRQ1[4] === 1'b1);
      13:  wait(PLPSIRQ1[5] === 1'b1);
      14:  wait(PLPSIRQ1[6] === 1'b1);
      15:  wait(PLPSIRQ1[7] === 1'b1);
      default : $display("[%0d] : %0s : Only 16 Interrupt lines (irq_fp0:irq_fp15) are supported",$time, DISP_ERR);
      endcase
      if(DEBUG_INFO) $display("[%0d] : %0s : Received Interrupt irq[%0d]",$time, DISP_INFO,  irq);
      irq_status = {PLPSIRQ1,PLPSIRQ0};
    end

おわりに

今回は、以下の2つの割り込み関連をみてみました

  • read_interrupt
  • wait_interrupt