はじめに
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