FC2カウンター FPGAの部屋 Zynq
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Zynq のベアメタル・アプリケーションによるキャッシュの操作3(ACPポート2)

”Zynq のベアメタル・アプリケーションによるキャッシュの操作2(ACPポート)”で ACP ポートのキャッシュ・コヒーレンシがうまく行ってないようだったが、今回、HDLabで開催する予定の Zynq + Vivado HLS セミナの例題を作っていて、同じ結果になってしまった。そこで、 ACP ポートを使用して、キャッシュ・コヒーレンシを取れる DMA を使用するために調査した。Vivado HLS と Vivado のバージョンは 2019.2 です。

今回は、平方数の和を出力する Vivado HLS で作成した AXI4-Stream の s_squares_axis IP を使用している。8 ビットの x 入力と 8 ビットの y 入力を 2 乗して加算する。 8 ビットの x 入力と y 入力に 1 個ずつ DMA2axis8 IP が接続されている。また s_squares_axis IP の出力は32 ビットの result を受けて axis2DMA する IP も接続されている。各 DMA は AXI4 Master で ACP ポートに接続されている。
ACP_cache_1_210429.png

ここで、Zynq Processing System7 は ACP ポートを活かしてあるが、Tie off AxUSERにはチェックを入れていない。
ACP_cache_2_210429.png

各 DMA する IP は Enable USER ports にチェックを入れて、width を 1 にしてある。
CACHE value は "1111"にしてある。
USER value は 0x00000001 にしてある。
ACP_cache_3_210429.png

これで、このアプリケーション・ソフトウェアを走らせた。

// sums_ex6.c 2019/09/14 by marsee

#include <stdio.h>
#include <stdint.h>
#include "xaxis2dma.h"
#include "xdma2axis8.h"
#include "xs_squares_axis.h"

volatile uint8_t data0[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
volatile uint8_t data1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
volatile uint32_t result[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

int main(){
    XDma2axis8 xdma2axis8_ap0, xdma2axis8_ap1;
    XAxis2dma xaxis2dma_ap;
    XS_squares_axis XS_squares_axis_ap;

    XDma2axis8_Initialize(&xdma2axis8_ap0, 0);
    XDma2axis8_Initialize(&xdma2axis8_ap1, 1);
    XAxis2dma_Initialize(&xaxis2dma_ap, 0);
    XS_squares_axis_Initialize(&XS_squares_axis_ap, 0);

    XDma2axis8_Set_in_V(&xdma2axis8_ap0, (u32)data0);
    XDma2axis8_Set_in_V(&xdma2axis8_ap1, (u32)data1);
    XAxis2dma_Set_out_V(&xaxis2dma_ap, (u32)result);

    XAxis2dma_Start(&xaxis2dma_ap);
    XS_squares_axis_Start(&XS_squares_axis_ap);
    XDma2axis8_Start(&xdma2axis8_ap0);
    XDma2axis8_Start(&xdma2axis8_ap1);

    while(!XAxis2dma_IsDone(&xaxis2dma_ap));

    for(int i=0; i<10; i++){
        printf("data0[%d] = %d, data1[%d] = %d, result[%d] = %d\n", i, (int)data0[i], i, (int)data1[i], i, (int)result[i]);
    }

    return(0);
}


結果を示す。
最後の 3 個の結果が正しくない。
ACP_cache_4_210429.png

この結果は”Zynq のベアメタル・アプリケーションによるキャッシュの操作2(ACPポート)”と同じだ。

さて、ここからすべての DMA IP の Enable USER ports のチェックボックスのチェックを外した。
ACP_cache_5_210429.png

これでアプリケーション・ソフトウェアを走らせたところ、同じ結果だった。
ACP_cache_6_210429.png

Zynq Processing System7 は ACP ポートを活かして、Tie off AxUSERにもチェックを入れた。
ACP_cache_7_210429.png

すると、アプリケーション・ソフトウェアを走らせたところ、今度はすべての結果が正しい。
ACP_cache_8_210429.png

もしかして、DMA IP の AxUSER が Zynq Processing System7 まで回っていないのか?
Zynq Processing System7 は ACP ポートを活かしてあるが、Tie off AxUSERにはチェックを入れていない。しかも、各 DMA IP の Enable USER ports にチェックを入れた状態に戻して、各 AXI ポートを展開してみた。
ACP_cache_9_210429.png

DMA IP には AxUSER ポートがある。その対向している AXI Interconnect の AXI ポートには AxUSER がない。。。これか原因は AXI Interconnect まで AxUSER が回っていない?

ちなみに Zynq Processing System7 の AXI ポートには、 AxUSER ポートがあって、その対向の AXI Interconnect の AXI ポートにも AxUSER がある。。。

Vivado HLS で作った IP は AxUSER 無視されるか?設定があるのかな?
自分で HDL で書いて IP Packager でパッケージした IP はどうなんだろうか?

とりあえずは、Zynq Processing System7 の ACP ポートを使う場合は、Tie off AxUSERにチェックを入れて使った方が良さそうだ。

(2021/04/30:追記)
ikwzm さんに Zynq Processing System7 ポートの AxUSER 信号は 5 ビット幅なので、Vivado HLS で作成した IP の AxUSER信号も 5 ビットにしてはどうか?という提案があったので、やってみた。

Vivado HLS で作成した IP の AWUSER と ARUSER 信号を 5 ビットに変更した。
ACP_cache_10_210429.png

ポートを見ると、Vivado HLS IP と接続された AXI Interconnect の AXI インターフェース・ボートにも AxUSER のポートが確認できた。
ACP_cache_11_210429.png

これでアプリケーション・ソフトウェアを走らせたところ、今までと同様に最後の 3 個が誤っている。
ACP_cache_12_210429.png

最後に同じ設定で Vivado HLS IP の AXI4 Master 用の AXI Interconnect を AXI SmartConnect に変更した。
ACP_cache_13_210430.png

SmartConnect の Vivado HLS IP と接続された AXI ポートを見ると AxUSER 信号が存在する。 Zynq Processing System7 との対向 AXI ポートにも AxUSER が存在する。
ACP_cache_14_210430.png

これでアプリケーション・ソフトウェアを走らせたところ、すべての結果が正しくなった。
ACP_cache_15_210430.png

AXI Interconnect は AxUSER を伝搬しないが、AXI SmartConnect だったら問題なく伝搬するのかな?
  1. 2021年04月29日 20:40 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

Zynq で PL から PS に割り込みを掛ける3

Zynq で PL から PS に割り込みを掛ける2”の続き。

FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”の second プロジェクトを改造して、プッシュボタンスイッチを押した時に割り込みを掛けて RGB LED のON/OFF 制御をしてみようということで、前回は、 second プロジェクトのブロックデザインに押しボタンスイッチによって PL から PS への割り込みを追加して、動作を確認することができた。今回は、”Zynq で PL から PS に割り込みを掛ける1”で、 IRQ_F2P 割り込みはレベル割り込みとエッジ割り込みの 2 種類から選べるはずだが、どちらになっているか?を確認してみよう。

まずは、”Zynq-7000 SoC テクニカル リファレンス マニュアル UG585 (v1.10) 2015 年 2 月 23 日”の219ページの図 7-4のICD ICFR 2~ICD ICFR 5を引用する。
second_58_210218.png

ピンクの枠で囲ったところが、 IRQ_F2P 割り込みに対応する部分だ。
ICD ICFR レジスタの該当する割り込みの番号に割り当てる割り込みの種類は

01: High-level active
11: Rising-edge active


ということだ。

また、embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic_hw.h にも Interrupt Configuration Register 0xC00-0xCFC の記述があるので、引用する。
second_59_210218.png

embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic.c には、

void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, u8 Priority, u8 Trigger)

void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, u8 *Priority, u8 *Trigger)

がある。これでプライオリティと割り込みのトリガーを指定することができる。

プライオリティと割り込みのトリガーを指定する方法は、武内先生の”Xilinx の XAxiDma ドライバのサンプルを読む”を参照のこと。

さて、それでは、XScuGic_GetPriorityTriggerType() を second_lef_off.c に追加して、プライオリティと割り込みのトリガーが何になっているか?を見てみよう。(second_led_off.c については”Zynq で PL から PS に割り込みを掛ける2”を参照のこと)
追加したコードを示す。

    XScuGic_GetPriorityTriggerType(&IntcInstance,XPS_FPGA0_INT_ID,
            &Priority, &Trigger);
    xil_printf("XPS_FPGA0_INT_ID Priority = %x, Trigger = %x\n", (int)Priority, (int)Trigger);

    XScuGic_GetPriorityTriggerType(&IntcInstance,XPS_FPGA1_INT_ID,
            &Priority, &Trigger);
    xil_printf("XPS_FPGA1_INT_ID Priority = %x, Trigger = %x\n", (int)Priority, (int)Trigger);


second_60_210218.png

ビルドして Run するとプライオリティと割り込みのトリガーの種類が表示された。
second_61_210218.png

XPS_FPGA0_INT_ID Priority = A0, Trigger = 1
XPS_FPGA1_INT_ID Priority = A0, Trigger = 1


よって、現在の割り込みのプライオリティは 0xA0 で、割り込みのトリガーの種類はハイ・レベルによる割り込みであるということが確認できた。
  1. 2021年02月19日 03:27 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

Zynq で PL から PS に割り込みを掛ける2

Zynq で PL から PS に割り込みを掛ける1”の続き。

FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”の second プロジェクトを改造して、プッシュボタンスイッチを押した時に割り込みを掛けて RGB LED のON/OFF 制御をしてみようということで、前回は、前振りとして、PL から PS への割り込み方法について調査した。今回は、 second プロジェクトのブロックデザインに押しボタンスイッチによって PL から PS への割り込みを追加する。

まずは second プロジェクトのブロックデザインで processing_system7_0 をダブルクリックして設定画面を開く。

Page Navigator で Interrupt をクリックする。
Fabric Interrupt -> PL-PS Interrupt Ports を展開する。
IRG_F2P[15:0] にチェックを入れる。
second_53_210214.png

processing_system7_0 に IRQ_F2P[0:0] が増えた。
BTN[1:0] を IRQ_F2P[0:0] に接続するのだが、”Zynq で PL から PS に割り込みを掛ける1”に書いたとおりに、 Slice で BTN[1] と BTN{0] に分けてから Concat でまとめて IRQ_F2P[0:0] に入れる。まだ IRQ_F2P[0:0] のままになっている。(なお、このブロックデザインでは、 Slice を接続する Concat のポートが間違っている。Sletected_bit1 の Slice が Concat の In1 に接続されるはずだ)
second_54_210214.png

論理合成、インプリメンテーション、ビットストリームの生成後のブロックデザインを示す。(この時は、Sletected_bit1 の Slice が Concat の In1 に接続されていて、バグが修正されている)
second_55_210214.png

IRQ_F2P[1:0] に修正されていて、正常なビット長になっている。

Project Summary を示す。
second_56_210214.png

ハードウェアをエクスポートして、 XSA ファイルを更新した。

Vitis で design_1_wrapper プラットフォームを右クリックし右クリックメニューから Update Hardware Specification を選択する。
Update Hardware Specification ダイアログが表示される。更新した XSA ファイルを指定して、プラットフォームをアップデートする。
プラットフォームを再度ビルドする。
second_lef_off アプリケーション・プロジェクトを新規作成した。
second_led_off_system -> second_led_off -> src を右クリックし右クリックメニューから New -> File を選択して、 second_led_off.c を新規作成した。
ソースコードは ”FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”の second.c を改造して使用している。
second_57_210215.png

これで、アプリケーション・ソフトウェアを Run すると、 second プロジェクトと同様に RGB LED が色を変えながら点灯する。
そして、BTN0 で RGB LED の点灯が停止して、 BTN1 で RGB LED の点灯が再開した。成功だ。

最後に、小林様のご厚意で、 second_lef_off.c の全文を掲載させていただく。

/* Copyright(C) 2020 Cobac.Net All Rights Reserved. */
/* chapter: 第5章                  */
/* Vivado : second                 */
/* Vitis  : second                 */
/* outline: タイマー割り込みテスト */

// second_led_off.c 2021/02/14 by marsee
// second.c にPLの割り込みを追加して BTN0 でLED OFF、BTN1で LED ON するようにコードを変更した

#include "xparameters.h"
#include "xgpio.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"

#define TIMER_LOAD_VALUE 333333333  /* CPU周波数667MHzの1/2 */
#define LED_CHANNEL      1          /* ch1:LED ch2:BTN      */

/* 各周辺回路のインスタンス変数 */
XGpio Gpio;
XScuTimer TimerInstance;
XScuGic IntcInstance;

int led_stat = 1;

/* LED表示パターン作成 */
int led_rgb(int cnt)
{
    int led;
    switch ( cnt%5 ) {
        case 0: led = 0x4; break;
        case 1: led = 0x2; break;
        case 2: led = 0x1; break;
        case 3: led = 0x7; break;
        case 4: led = 0x0; break;
        default:led = 0x0;
    }
    return led;
}

/* タイマー割り込み関数 */
void TimerCounterHandler(void *CallBackRef)
{
    volatile static int cnt;
    XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;

    if (XScuTimer_IsExpired(TimerInstancePtr)) {
        XScuTimer_ClearInterruptStatus(TimerInstancePtr);
        if (led_stat == 1){
            if ( ++cnt>9 ) cnt = 0;
        }else{
            cnt = 4;
        }
        xil_printf("cnt=%d\n", cnt);
        XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, led_rgb(cnt));
    }
}

// LED_on 割り込み関数
void LED_ON_Handler(void *CallBackRef){
    led_stat = 1;
}

// LED_off 割り込み関数
void LED_OFF_Handler(void *CallBackRef){
    led_stat = 0;
}

/* 割り込みコントローラのドライバ初期化 */
int ScuGicInt_Init( void )
{
    int Status;
    XScuGic_Config *ConfigPtr;
    ConfigPtr = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
    Status = XScuGic_CfgInitialize(&IntcInstance, ConfigPtr,
            ConfigPtr->CpuBaseAddress);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler) XScuGic_InterruptHandler,
            &IntcInstance);
    Xil_ExceptionEnable();
    return XST_SUCCESS;
}

/* 割り込み処理関数の登録 */
int ScuGicInt_Reg(u32 Int_Id, void *InstancePtr, void *IntHandler)
{
    int Status;
    Status = XScuGic_Connect(&IntcInstance,
            Int_Id,
            (Xil_ExceptionHandler)IntHandler,
            (void *)InstancePtr);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, Int_Id);
    return XST_SUCCESS;
}

int main()
{
    int Status;
    XScuTimer_Config *ConfigPtr;

    xil_printf("Timer Interrupt Test.\n\n");

    /* GPIOの初期化 */
    Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);
    XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, led_rgb(0));

    /* タイマーのドライバ初期化 */
    ConfigPtr = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);
    Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr,
                    ConfigPtr->BaseAddr);
    if (Status != XST_SUCCESS) return XST_FAILURE;

    /* 割り込み関連初期化と割り込み処理関数の登録 */
    Status = ScuGicInt_Init();
    if (Status != XST_SUCCESS) return XST_FAILURE;
    Status = ScuGicInt_Reg(XPAR_SCUTIMER_INTR, &TimerInstance,
                           TimerCounterHandler);
    if (Status != XST_SUCCESS) return XST_FAILURE;

    // BTN 1 , LED ON
    Status = XScuGic_Connect(&IntcInstance,
            XPS_FPGA1_INT_ID,
            (Xil_ExceptionHandler)LED_ON_Handler,
            (void *)NULL);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, XPS_FPGA1_INT_ID);

    // BTN 0 , LED OFF
    Status = XScuGic_Connect(&IntcInstance,
            XPS_FPGA0_INT_ID,
            (Xil_ExceptionHandler)LED_OFF_Handler,
            (void *)NULL);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, XPS_FPGA0_INT_ID);

    /* タイマーの初期設定と開始 */
    XScuTimer_EnableAutoReload(&TimerInstance);
    XScuTimer_LoadTimer(&TimerInstance, TIMER_LOAD_VALUE);
    XScuTimer_EnableInterrupt(&TimerInstance);
    XScuTimer_Start(&TimerInstance);

    while(1);
    return 0;
}


  1. 2021年02月18日 03:35 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

Zynq で PL から PS に割り込みを掛ける1

FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”の second プロジェクトを改造して、プッシュボタンスイッチを押した時に割り込みを掛けて RGB LED のON/OFF 制御をしてみよう。
今回は、Zynq 割り込みコントローラを構造を確認して、 Xilinx のライブラリを使用した設定方法を見ていこう。

まずは、”Zynq-7000 SoC テクニカル リファレンス マニュアル UG585 (v1.10) 2015 年 2 月 23 日”を参照する。

Zynq-7000 SoC テクニカル リファレンス マニュアル UG585 (v1.10) 2015 年 2 月 23 日”の”図 1-1 : Zynq-7000 SoC の概要”を引用する。
zynq_1_210215.png

汎用割り込みコントローラー (GIC) があるのが分かる。

GIC のブロック図の”図 7-2 : 割り込みコントローラーのブロック図”を引用する。
zynq_2_210215.png

ピンクの四角で囲ったのが、 PL からの割り込みを受け付ける SPI だ。

”表 7-4 : PS と PL の共有ペリフェラル割り込み (SPI)”を引用する。
zynq_3_210215.png

PL[7:0] までの割り込みが書かれている。

”表 7-4 : PS と PL の共有ペリフェラル割り込み (SPI) (続き)”を引用する。
zynq_4_210215.png

PL[15:8] の割り込みが書かれている。

これは、IP では何処かと言うと、Zynq Processing System7 の設定画面の Interrupt をクリックし、 Fabric Interrupt の IRQ_F2P[15:0] に相当する。
zynq_5_210215.png

複数の割り込みを実装する場合に、 Fabric Interrupt の IRQ_F2P[15:0] にチェックを入れても、当初は IRQ_F2P[0:0] となってしまい 1 ビット幅のままである。これを適切なビット長にするためには、 Concat IP を使用して、 IRQ_F2P[0:0] に接続すれば良いそうだ。
How to use more than one IRQ_F2P interrupt?”を参照。
なお、Concat IP を接続しても、 IRQ_F2P[0:0] のままだが、論理合成を始めれば、ビット長が変更されるようだ。

ブロックデザインでは、BTN0, BTN1 を Zynq Processing System7 の IRQ_F2P[1:0] に接続する。
Vitis のソフトウェア・プロジェクトでは、 XScuGic_Connect() 関数を利用して、 BTN0 を押した時に RGB LED の点滅が中止するようにプログラムする。BTN1 を押すと RGB LED の点滅が再開する。

    // BTN 1 , LED ON
    Status = XScuGic_Connect(&IntcInstance,
            XPS_FPGA1_INT_ID,
            (Xil_ExceptionHandler)LED_ON_Handler,
            (void *)NULL);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, XPS_FPGA1_INT_ID);

    // BTN 0 , LED OFF
    Status = XScuGic_Connect(&IntcInstance,
            XPS_FPGA0_INT_ID,
            (Xil_ExceptionHandler)LED_OFF_Handler,
            (void *)NULL);
    if (Status != XST_SUCCESS) return XST_FAILURE;
    XScuGic_Enable(&IntcInstance, XPS_FPGA0_INT_ID);


XScuGic_Connect() 関数は、 xscugic.c にある。
zynq_6_210215.png

最初の”XScuGic *InstancePtr”は、GIC のインスタンスへのポインタ、
2番目の”u32 Int_Id”は割り込み番号(後で説明する)
3番目の”Xil_InterruptHandler Handler”が割り込みのコールバック関数を登録する
4番目が割り込みのコールバック関数に渡すポインタ(ScuTimer の場合は、 XScuTimer 構造体へのポインタを渡していたが、LED ON / OFF の場合は必要ないため NULL ポインタを渡している)

2番目の”u32 Int_Id”の番号は、 xparameters_ps.h に定義されている。
zynq_7_210215.png

この場合は、 IRQ_F2P[1] が XPS_FPGA1_INT_ID に、 IRQ_F2P[0] が XPS_FPGA0_INT_ID に対応している。

割り込みのコールバック関数を示す。

// LED_on 割り込み関数
void LED_ON_Handler(void *CallBackRef){
    led_stat = 1;
}

// LED_off 割り込み関数
void LED_OFF_Handler(void *CallBackRef){
    led_stat = 0;
}


void *CallBackRef は使用していない。

最後に、 BTN1, BTN0 はチャタリングはケアしていない。この場合は、チャタリングをケアしなくても大丈夫だ。
それは、BTN1 には LED を ON する機能だけを割り当てて、 BTN0 には LED を OFF する機能だけを割り当てているので、何度も割り込みが入ってもその機能が何度も呼ばれるだけという理由だ。
今のところうまく行っている。もし、チャタリングにより IRQ_F2P 自体が誤動作するようだったら対策を考えることにする。
  1. 2021年02月17日 03:43 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

”FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”をやってみる3

”FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”をやってみる2”の続き。

FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”をやってみるということで、前回は、ラッパー Verilog HDL ファイルのトップファイルを生成し、制約ファイルを追加して、論理合成、インプリメンテーション、ビットストリームの生成を行う。そして、ハードウェアをエクスポートし、 XSA ファイルを生成した。今回は、Vitis 2020.2 を立ち上げて、プラットフォームとアプリケーション・プロジェクトを作成して、ZYBO Z7-10 で実機検証を行う。

Vivado の Tools メニューから Launch Vitis IDE を選択して、 Vitis 2020.2 を起動する。
Vitis IDE Launcher ダイアログが起動する。
Browse... ボタンをクリックして、 second ディレクトリの下に vitis_work ディレクトリを新規作成する。
Vitis IDE Launcher ダイアログに戻って、 Launch ボタンをクリックする。
second_40_210214.png

Vitis IDE が起動した。
Create Application Project をクリックする。
second_41_210214.png

New Application Project ダイアログが表示される。
Next > ボタンをクリックする。
second_42_210214.png

Platform 画面が表示された。
Create a new platform from hardware (XSA) タブをクリックする。
Browse... ボタンをクリックして、 XSA File に second/design_1_wrapper.xsa を指定する。
Next > ボタンをクリックする。
second_43_210214.png

Application Project Details 画面が表示された。
Application Project name に second を入力する。
Next > ボタンをクリックする。
second_44_210214.png

Domain 画面が表示された。
デフォルトのまま、Next > ボタンをクリックする。
second_45_210214.png

Templates 画面では、 Empty Application を選択する。
Finish ボタンをクリックする。
second_46_210214.png

design_1_wrapper プラットフォームと second プロジェクトが生成された。
second_47_210214.png

second.c をインポートする。
Vitis の Explorer の second_system -> second -> src を右クリックし右クリックメニューから Import Sources... を選択する。
サポートページからダウンロードした XilinxFPGA_SE.zip を展開したディレクトリの Zybo_Z7-10/dai5sho/second/VITIS ディレクトリを指定する。
Import Sources ダイアログで second.c にチェックを入れてインポートする。
second_48_210214.png

second.c の日本語コードは Shift JIS だったので、 UTF-8 に変更する。
second/vitis_work/second/src ディレクトリに行って、次のコマンドを実行した。
nkf -Lw -S --overwrite second.c
これで、 second.c の日本語コードは UTF-8 に変更された。
second_49_210214.png

second.c の一部を示す。
second_50_210214.png

トンカチボタンをクリックして、ビルドを行う。
ビルドが成功して、 second.elf ファイルが生成された。

Assistant ウインドウの second_system -> second -> Debug を右クリックし、右クリックメニューから Run -> Launch on Hardware (Single Application Debug) を選択して起動する。
second_51_210214.png

RGB LED が点灯して色が変わって行くのが確認できた。
gtkterm を確認した。
second_52_210214.png
  1. 2021年02月16日 04:12 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

”FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”をやってみる2

FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”をやってみるということで、前回は、Vivado 2020.2 の second プロジェクトを作成して、ブロックデザインを完成させた。今回は、ラッパー Verilog HDL ファイルのトップファイルを生成し、制約ファイルを追加して、論理合成、インプリメンテーション、ビットストリームの生成を行う。そして、ハードウェアをエクスポートし、 XSA ファイルを生成する。

まずはブロックデザインをセーブする。
Source タブをクリックし、 design_1 を右クリックし右クリックメニューから Create HDL Wrapper... を選択して、 HDL Wrapper file を作成する。
second_23_210213.png

desgin_1_wrapper.v が生成された。
second_24_210213.png

制約ファイルを生成する。
Source ウインドウ内で右クリックし右クリックメニューから Add Sources... を選択する。
Add Sources ダイアログが開く。
Add or create constraints のラジオボタンをクリックする。
Next > ボタンをクリックする。
second_25_210214.png

Add or Create Constraints 画面で、 Create File ボタンをクリックする。
second_26_210214.png

Create Constraints File ダイアログが開く。
File name に second を入力する。
OK ボタンをクリックする。
second_27_210214.png

Add or Create Constraints 画面に second.xdc が入った。
Finish ボタンをクリックする。
second_28_210214.png

空の second.xdc が表示された。
サポートページからダウンロードした XilinxFPGA_SE.zip を展開してできた Zybo_Z7-10/dai5sho/second ディレクトリの下の second.xdc から使用する部分だけを引用した。

#RGB LED
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[2] }]; # Red
set_property -dict { PACKAGE_PIN F17 IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[1] }]; # Green
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[0] }]; # Blue

#Buttons
set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { BTN[0] }];
set_property -dict { PACKAGE_PIN P16 IOSTANDARD LVCMOS33 } [get_ports { BTN[1] }];


セーブボタンでセーブした。
second_29_210214.png

左の Flow Navigator 画面から Gererate Bitstream を選択して、論理合成、インプリメンテーション、ビットストリームの生成を行う。
すると、 Launch Runs ダイアログが表示される。
デフォルトのまま OK ボタンをクリックする。
second_30_210214.png

論理合成、インプリメンテーション、ビットストリームの生成を行って終了すると、 Bitstream Generation Completed ダイアログが表示された。
Cancel ボタンをクリックする。
second_31_210214.png

Feedback Request ダイアログが表示された。
Remind me Later をクリックした。
second_32_210214.png

Project Summary を表示するために Project Summary ボタンをクリックする。
second_33_210214.png

Project Summary が表示された。問題ないようだ。
second_34_210214.png

ハードウェアをエクスポートする。
Vivado の File メニューから Export -> Export Hardware... を選択する。

Export Hardware Platform ダイアログが表示された。
Next > ボタンをクリックする。
second_35_210214.png

Output 画面で Include bitstream のラジオボタンをクリックする。
Next > ボタンをクリックする。
second_36_210214.png

Files 画面が表示された。
デフォルトのまま Next > ボタンをクリックする。
second_37_210214.png

Exporting Hardware Platform の Summary が表示された。
Finish ボタンをクリックする。
second_38_210214.png

Vivado 2020.2 の second プロジェクトのディレクトリの下に、 design_1_wrapper.xsa ファイルが生成された。
second_39_210214.png
  1. 2021年02月15日 04:58 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0

”FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”をやってみる1

小林さんから”FPGAプログラミング大全 Xilinx編 第2版”をいただいた。
大変ボリュームがある本で、

Xilinx のツールの使い方
Zynq の使用方法
MicroBlaze の使い方
IP の作り方
AXI バス
Vitis HLS 高位合成ツール


について書かれている凄い本だと思った。本をいただいておいて言うのも何だけど 3,800 円は安い。
その中から私が意図的に使ってこなかった Zynq の割り込みをやってみようと思う。具体的には”5-4 タイマー割り込みとAPIの利用”をやってみようと思う。
割り込みを使ってこなかった理由は、別に割り込みを使わなくても、コードが書けるし、割り込み使うとレジスタの待避に時間がかかるし、複雑に割り込み使うと時間に間に合うか計算するのが大変だし、デバックが面倒だからだ。usleep() などを使って、プログラムすればポーリングでも消費電力を減らせる。割り込み使うようなところはハードウェアにしちゃえば良いし、プログラム負荷が少なくなってポーリングでの実装が楽になる。

使用する FPGA ボードは ZYBO Z7-10 にしようと思う。
サポートページから XilinxFPGA_SE.zip をダウンロードして展開した。ダウンロードに時間がかかるようなので、余裕がある時にダウンロードすることをお勧めする。まだダウンロードが終了していないが Vivado のプロジェクトを作成していこう。

Ubuntu 18.04 LTS の Vivado 2020.2 で ZYBO Z7-10 用の second プロジェクトを作成する。

File メニューから Projcet -> New... を選択して新しいプロジェクトを作成する。
FPGAプログラミング大全 Xilinx編 第2版”の”5-4 タイマー割り込みとAPIの利用”に従ってプロジェクトを作成していく。

Project Name ダイアログを示す。
second_1_210213.png

間のダイアログは飛ばして、 Default Part で Boards をクリックし、Vendor を deiglentinc.com にして、 Zybo Z7-10 を選択する。
second_2_210213.png

New Project Summary を示す。 Finish ボタンをクリックする。
second_3_210213.png

second プロジェクトが生成された。
second_4_210213.png

Create Block Design をクリックして、新しいブロックデザインを生成する。

Create Block Design ダイアログが表示される。デフォルトのまま OK ボタンをクリックする。
second_5_210213.png

ブロックデザインが生成されて、Diagram ウインドウが開く。
真ん中の + ボタンをクリックして、Add IP しよう。
second_6_210213.png

Diagram ウインドウを Float した。
IP をリストするダイアログが開くので、 Zynq と入力すると Zynq Processing System が見つかるので、それをダブルクリックする。
second_7_210213.png

Zynq Processing System が Add IP された。
second_8_210213.png

Run Block Automation をクリックする。

Run Block Automation が表示される。これで ZYBO Z7-10 の設定値が入力される。
OK ボタンをクリックする。
second_9_210213.png

DDR と FIXED_IO が外部に出力され、 M_AXI_GP0 ポートなどが追加されている。
second_10_210213.png

Add IP ボタンをクリックして、 AXI_GPIO を追加する。

Search に GPIO と入れると AXI GPIO がリストされた。ダブルクリックして、 Add IP する。
second_11_210213.png

axi_gpio_0 が追加された。
axi_gpio_0 をダブルクリックして設定画面を表示する。
second_12_210213.png

GPIO の All Outputs にチェックを入れて、 GPIO Width を 3 に設定した。
GPIO 2 の All Inputs にチェックを入れて、 GPIO Width を 2 に設定した。
second_13_210213.png

Run Connection Automation をクリックする。
なお、下図は GPIO と GPIO2 を展開してある。
second_14_210213.png

Run Connection Automation ダイアログが表示された。
axi_gpio_0 の S_AXI にチェックを入れて自動配線する。
second_15_210213.png

Processing System Reset と AXI Interconnect IP が追加されて、自動配線された。
second_16_210213.png

axi_gpio_0 の gpio_io_o[2:0] と gpio2_io_i[1:0] を選択して、右クリックし右クリックメニューから Make External を選択する。

gpio_io_o[2:0] と gpio2_io_i[1:0] ポートができた。
second_17_210213.png

gpio2_io_i[1:0] ポートの名前を BTN に変更する。
second_18_210213.png

gpio_io_o[2:0] の名前を LED_RGB[2:0] に変更した。

Validate Design をクリックして、ブロックデザインが正しいかどうか?調べた。
second_19_210213.png

Critical Messages ダイアログがでたが、DDR の設定値に関することなので、OK だ。
second_20_210213.png

Address Editor 画面を示す。
second_21_210213.png

Address Map 画面を示す。
second_22_210213.png

これでブロックデザインは完成だ。
  1. 2021年02月13日 12:15 |
  2. Zynq
  3. | トラックバック:0
  4. | コメント:0
»