FC2カウンター FPGAの部屋 Vivado HLS 2013.4でラプラシアン・フィルタ関数をaxi masterモジュールにする7(ソース公開)
FC2ブログ

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

FPGAの部屋

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

Vivado HLS 2013.4でラプラシアン・フィルタ関数をaxi masterモジュールにする7(ソース公開)

”Vivado HLS 2013.4でラプラシアン・フィルタ関数をaxi masterモジュールにする6(実機でテスト)”の続き。

前回までのソースを公開します。使用は自己責任でお願いします。なお、バグを見つけたらコメント欄で教えて下さい。よろしくお願いします。

まずは、Vivado HLS 2013.4 のCソースから公開します。(laplacian_filter.c)

// laplacian_filter.c
// lap_filter_axim()

#include <stdio.h>
#include <string.h>

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);

int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb)
{
    #pragma HLS RESOURCE variable=cam_addr core=AXI4LiteS metadata="-bus_bundle LiteS"
    #pragma HLS RESOURCE variable=lap_addr core=AXI4LiteS metadata="-bus_bundle LiteS"
    #pragma HLS RESOURCE variable=return core=AXI4LiteS metadata="-bus_bundle LiteS"
    
    #pragma HLS INTERFACE ap_bus port=cam_fb depth=480000
    #pragma HLS INTERFACE ap_bus port=lap_fb depth=480000
    #pragma HLS RESOURCE variable=cam_fb core=AXI4M
    #pragma HLS RESOURCE variable=lap_fb core=AXI4M

    unsigned int line_buf[3][HORIZONTAL_PIXEL_WIDTH];
    unsigned int lap_buf[HORIZONTAL_PIXEL_WIDTH];
    int x, y;
    int lap_fil_val;
    int a, b;
    int fl, sl, tl;
    unsigned int offset_cam_addr, offset_lap_addr;
    int *cam_fb_addr, *lap_fb_addr;

    offset_cam_addr = cam_addr/sizeof(int);
    offset_lap_addr = lap_addr/sizeof(int);
    
    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        fl = (y-1)%3;    // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
        sl = y%3;        // 2番めのライン
        tl = (y+1)%3;    // 3番目のライン
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (y==0 || y==VERTICAL_PIXEL_WIDTH-1){ // 縦の境界の時の値は0とする
                lap_fil_val = 0;
            }else if (x==0 || x==HORIZONTAL_PIXEL_WIDTH-1){ // 横の境界の時も値は0とする
                lap_fil_val = 0;
            }else{
                 if (x == 1){ // ラインの最初でラインの画素を読み出す
                    if (y == 1){ // 最初のラインでは3ライン分の画素を読み出す
                        for (a=0; a<3; a++){ // 3ライン分
                            cam_fb_addr = (int*)(cam_fb+offset_cam_addr+(a*(HORIZONTAL_PIXEL_WIDTH)));
                            memcpy(&line_buf[a][0], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                            for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
                                line_buf[a][b] = conv_rgb2y(line_buf[a][b]);    // カラーから白黒へ
                            }
                        }
                    } else { // 最初のラインではないので、1ラインだけ読み込む。すでに他の2ラインは読み込まれている
                        cam_fb_addr = (int*)(cam_fb+offset_cam_addr+((y+1)*(HORIZONTAL_PIXEL_WIDTH)));
                         memcpy(line_buf[(y+1)%3], (const int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
                        for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
                            line_buf[(y+1)%3][b] = conv_rgb2y(line_buf[(y+1)%3][b]);    // カラーから白黒へ
                        }
                    }
                }
                lap_fil_val = laplacian_fil(line_buf[fl][x-1], line_buf[fl][x], line_buf[fl][x+1], line_buf[sl][x-1], line_buf[sl][x], line_buf[sl][x+1], line_buf[tl][x-1], line_buf[tl][x], line_buf[tl][x+1]);
            }
            lap_buf[x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
        }
        lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(y*(HORIZONTAL_PIXEL_WIDTH)));
        memcpy(lap_fb_addr, (const int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int));
    }
    return(7);
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


Cのテストベンチです。(lap_filter_tb.c)

// Testbench of laplacian_filter.c
// M系列データをハードウェアとソフトウェアで、ラプラシアン・フィルタを掛けて、それを比較する
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

int laplacian_fil_soft(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y_soft(int rgb);
int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb);    // hardware
void laplacian_filter_soft(volatile int *cam_fb, volatile int *lap_fb); // software

int mseq_po[ALL_PIXEL_VALUE];
int hw_lap_po[ALL_PIXEL_VALUE];
int sf_lap_po[ALL_PIXEL_VALUE];

int main()
{
//    int *mseq_po, *hw_lap_po, *sf_lap_po;
    int *s, *h;
    int x, y;
    int lfsr = 1;
    int cam_addr, lap_addr;
    
    // ピクセルデータ領域にM系列データを入力
    for (y=0, s=mseq_po; y<VERTICAL_PIXEL_WIDTH; y++){
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            lfsr = (lfsr >> 1) ^ (-(lfsr & 1) & 0xd0000001); /* taps 32 31 29 1 */
            // ”線形帰還シフトレジスタ ”参照 : http://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E5%B8%B0%E9%82%84%E3%82%B7%E3%83%95%E3%83%88%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF
            *s = lfsr;
            s++;
        }
    }
    
    cam_addr = (int)mseq_po;
    lap_addr = (int)hw_lap_po;
    lap_filter_axim(cam_addr, lap_addr, (volatile int *)0, (volatile int *)0);    // ハードウェアのラプラシアン・フィルタ
    laplacian_filter_soft(mseq_po, sf_lap_po);    // ソフトウェアのラプラシアン・フィルタ
    
    // ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
    for (y=0, h=hw_lap_po, s=sf_lap_po; y<VERTICAL_PIXEL_WIDTH; y++){
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (*h != *s){
                printf("ERROR HW and SW results mismatch HW = %d, SW = %d\n", *h, *s);
                return(1);
            } else {
                h++;
                s++;
            }
        }
    }
    printf("Success HW and SW results match\n");
}

void laplacian_filter_soft(volatile int *cam_fb, volatile int *lap_fb)
{
    int x, y;
    int lap_fil_val;
    int xy[3][3];
    int a, b;
    
    // RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
    for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
        for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
            if (y==0 || y==VERTICAL_PIXEL_WIDTH-1){ // 縦の境界の時の値は0とする
                lap_fil_val = 0;
            }else if (x==0 || x==HORIZONTAL_PIXEL_WIDTH-1){ // 横の境界の時も値は0とする
                lap_fil_val = 0;
            }else{
                for (a=0; a<3; a++){
                    for (b=0; b<3; b++){
                        xy[a][b] = conv_rgb2y_soft(cam_fb[((y+b-1)*HORIZONTAL_PIXEL_WIDTH)+x+a-1]);
                    }
                }
                lap_fil_val = laplacian_fil_soft(xy[0][0], xy[1][0], xy[2][0],  xy[0][1], xy[1][1], xy[2][1],  xy[0][2], xy[1][2], xy[2][2]);
            }
            lap_fb[y*HORIZONTAL_PIXEL_WIDTH+x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
        }
    }
}

// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y_soft(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1  8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil_soft(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
    int y;

    y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
    if (y<0)
        y = 0;
    else if (y>255)
        y = 255;
    return(y);
}


次は、SDKの Vivado HLSで作ったラプラシアンフィルタAXI Master IP制御用のCソフトウェアです。4つファイルがあって、lap_fil_hls_axim.c、lap_fil_axim_uty.c、lap_fil_axim_uty.h、xlap_filter_axim_hw.hです。

最初に、lap_fil_hls_axim.cから公開します。

// lap_filter_axim.c
// AXI4 Master のVivado HLS出力ハードウェア・バージョン
// RGBをYに変換後にラプラシアンフィルタを掛ける。
// ピクセルのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 2013/10/15

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <ctype.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/kernel.h>
#include "lap_fil_axim_uty.h"

#define LAP_FILTER_AXIM_HW_ADDRESS    0x49000000    // ラプラシアン・フィルタのAXI4 Masterハードウェアのアドレス

#define HORIZONTAL_PIXEL_WIDTH    800
#define VERTICAL_PIXEL_WIDTH    600
#define ALL_PIXEL_VALUE    (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

#define BUFSIZE    1024

#define MEASURE_COUNT    5000

int conv_rgb2y(int rgb);
int chkhex(char *str);
volatile unsigned *setup_io(off_t mapped_addr, unsigned int *buf_addr);

int main()
{
    FILE *fd;
    unsigned int bitmap_dc_reg_addr;
    unsigned int read_num;
    volatile unsigned *bm_disp_cnt_reg;
    unsigned int fb_addr, next_frame_addr;
    int return_val;
    struct timeval start_time, end_time;
    unsigned int rmmap_cnt=0, wmmap_cnt=0;
    unsigned int lap_fil_hw, *lap_fil_hw_addr;
    char buf[BUFSIZE], *token;
    unsigned int val;
    unsigned int bitmap_buf;

    gettimeofday(&start_time, NULL);    // プログラム起動時の時刻を記録

    // fb_start_addr.txt の内容をパイプに入れる
    memset(buf, '\0', sizeof(buf)); // buf すべてに\0 を入れる
    // fb_start_addr.txt を開く
    fd = popen("cat /Apps/fb_start_addr.txt", "r");
    if (fd != NULL){
        read_num = fread(buf, sizeof(unsigned char), BUFSIZE, fd);
        if (read_num > 0){
            sscanf(buf, "%x\n", &fb_addr);
        }
    }
    pclose(fd);

    // ラプラシアンフィルタの結果を入れておくフレーム・バッファ
    next_frame_addr = ((fb_addr + (ALL_PIXEL_VALUE*4)) & (~(int)(PAGE_SIZE-1))) + PAGE_SIZE;

    // Vivado HLS で作製したラプラシアン・フィルタIPのアドレスを取得
    lap_fil_hw_addr = setup_io((off_t)LAP_FILTER_AXIM_HW_ADDRESS, &lap_fil_hw);

    lap_fil_initialize(lap_fil_hw_addr);    // ラプラシアン・フィルタIPの初期化とap_start
    // ラプラシアン・フィルタAXI4 Master IPスタート
    return_val = laplacian_fil_hw(lap_fil_hw_addr, fb_addr, next_frame_addr);
    printf("return Value = %d\n", return_val);
    
    munmap((unsigned int *)lap_fil_hw_addr, BLOCK_SIZE);
    free((unsigned int *)lap_fil_hw);

    // bitmap-disp-cntrler-axi-master のアドレスを取得
    memset(buf, '\0', sizeof(buf)); // buf すべてに\0 を入れる
    // ls /sys/devices/axi.0 の内容をパイプに入れる
    fd = popen("ls /sys/devices/axi.0", "r");
    if (fd != NULL){
        read_num = fread(buf, sizeof(unsigned char), BUFSIZE, fd);
        if (read_num > 0){
            token = buf;
            if ((token=strtok(token, ".\n")) != NULL){
                do {
                    if (chkhex(token)){ // 16進数
                        sscanf(token, "%x", &val);
                    } else {
                        if (strcmp(token, "bitmap-disp-cntrler-axi-master") == 0)
                            bitmap_dc_reg_addr = val;
                    }
                }while((token=strtok(NULL, ".\n")) != NULL);
            }
        }
    }
    pclose(fd);

    // ラプラシアンフィルタの掛かった画像のスタートアドレスを bitmap-disp-cntrler-axi-master にセット
    bm_disp_cnt_reg = setup_io((off_t)bitmap_dc_reg_addr, &bitmap_buf);
    *bm_disp_cnt_reg = next_frame_addr;

    munmap((unsigned int *)bm_disp_cnt_reg, BLOCK_SIZE);
    free((unsigned int *)bitmap_buf);

    gettimeofday(&end_time, NULL);
    printf("rmmap_cnt = %d\n", rmmap_cnt);
    printf("wmmap_cnt = %d\n", wmmap_cnt);
    if (end_time.tv_usec < start_time.tv_usec) {
        printf("total time = %d.%d sec\n", end_time.tv_sec - start_time.tv_sec - 1, 1000000 + end_time.tv_usec - start_time.tv_usec);
    }
    else {
        printf("total time = %d.%d sec\n", end_time.tv_sec - start_time.tv_sec, end_time.tv_usec - start_time.tv_usec);
    }
    return(0);
}


// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y =  0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
    int r, g, b, y_f;
    int y;

    b = rgb & 0xff;
    g = (rgb>>8) & 0xff;
    r = (rgb>>16) & 0xff;

    y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
    y = y_f >> 8; // 256で割る

    return(y);
}

//
// Set up a memory regions to access GPIO
//
volatile unsigned *setup_io(off_t mapped_addr, unsigned int *buf_addr)
// void setup_io()
{
    int  mem_fd;
    char *gpio_mem, *gpio_map;

   /* open /dev/mem */
   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
      printf("can't open /dev/mem \n");
      printf("mapped_addr = %x\n", mapped_addr);
      exit (-1);
   }

   /* mmap GPIO */

   // Allocate MAP block
   if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
      printf("allocation error \n");
      exit (-1);
   }
    *buf_addr = gpio_mem;    // mallocしたアドレスをコピー

   // Make sure pointer is on 4K boundary
   if ((unsigned long)gpio_mem % PAGE_SIZE)
     gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);

   // Now map it
   gpio_map = (unsigned char *)mmap(
      (caddr_t)gpio_mem,
      BLOCK_SIZE,
      PROT_READ|PROT_WRITE,
      MAP_SHARED|MAP_FIXED,
      mem_fd,
      mapped_addr
   );

   if ((long)gpio_map < 0) {
      printf("mmap error %d\n", (int)gpio_map);
      printf("mapped_addr = %x\n", mapped_addr);
      exit (-1);
   }

   close(mem_fd); // /dev/mem のクローズ

   // Always use volatile pointer!
   // gpio = (volatile unsigned *)gpio_map;
   return((volatile unsigned *)gpio_map);

} // setup_io

// 文字列が16進数かを調べる
int chkhex(char *str){
    while (*str != '\0'){
        if (!isxdigit(*str))
            return 0;
        str++;
    }
    return 1;
}


次は、lap_fil_axim_uty.c です。

/*
 * lap_fil_axim_uty.c
 *
 *  Created on: 2013/10/15
 *      Author: Masaaki
 */

#include "xlap_filter_axim_hw.h"

#define AP_START_BIT_POS        1    // ap_start のビット位置 bit0
#define AP_DONE_BIT_POS            2    // ap_done のビット位置 bit1
#define AP_AUTO_RESTART_BIT_POS    0x80    // auto_restart のビット位置 bit7
#define VLD_BIT_POS                1

void lap_fil_initialize(unsigned int *lap_fil_hw_addr)
{
    *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_AP_CTRL) = 0;
    *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_GIE) = 0;
    *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_IER) = 1;    // ap_done=1
}

// ラプラシアン・フィルタ・スタート
int laplacian_fil_hw(unsigned int *lap_fil_hw_addr, unsigned int cam_fb, unsigned int lap_fb)
{
    int ap_status, ap_done;
    int ap_return;

    *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_CAM_ADDR_DATA) = cam_fb;
    *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_LAP_ADDR_DATA) = lap_fb;

    // ap_start enable
    *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_AP_CTRL) = AP_START_BIT_POS;

    // wait ap_done
    do{
        ap_status = *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_AP_CTRL);
        ap_done = ap_status & AP_DONE_BIT_POS;
    }while(!ap_done);
    
    // ap_return read
    ap_return = *(volatile int *)((unsigned int)lap_fil_hw_addr + (unsigned int)XLAP_FILTER_AXIM_LITES_ADDR_AP_RETURN);
    //printf("ap_return = %d\n", ap_return);
    return(ap_return);
}


lap_fil_axim_uty.h です。

/*
* lap_fil_axim_uty.h
*
* Created on: 2013/10/15
* Author: Masaaki
*/

#ifndef LAP_FIL_AXIM_UTY_H_
#define LAP_FIL_AXIM_UTY_H_

void lap_fil_initialize(unsigned int *lap_fil_hw_addr);
int laplacian_fil_hw(unsigned int *lap_fil_hw_addr, unsigned int *cam_fb, unsigned int *lap_fb);

#endif /* LAP_FIL_AXIM_UTY_H_ */


最後に、xlap_filter_axim_hw.h です。これは、Vivado HLSが生成したファイルです。

// ==============================================================
// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
// Version: 2013.4
// Copyright (C) 2013 Xilinx Inc. All rights reserved.
//
// ==============================================================

// LiteS
// 0x00 : Control signals
// bit 0 - ap_start (Read/Write/COH)
// bit 1 - ap_done (Read/COR)
// bit 2 - ap_idle (Read)
// bit 3 - ap_ready (Read)
// bit 7 - auto_restart (Read/Write)
// others - reserved
// 0x04 : Global Interrupt Enable Register
// bit 0 - Global Interrupt Enable (Read/Write)
// others - reserved
// 0x08 : IP Interrupt Enable Register (Read/Write)
// bit 0 - Channel 0 (ap_done)
// bit 1 - Channel 1 (ap_ready)
// others - reserved
// 0x0c : IP Interrupt Status Register (Read/TOW)
// bit 0 - Channel 0 (ap_done)
// bit 1 - Channel 1 (ap_ready)
// others - reserved
// 0x10 : reserved
// 0x14 : Data signal of cam_addr
// bit 31~0 - cam_addr[31:0] (Read/Write)
// 0x18 : reserved
// 0x1c : Data signal of lap_addr
// bit 31~0 - lap_addr[31:0] (Read/Write)
// 0x20 : Data signal of ap_return
// bit 31~0 - ap_return[31:0] (Read)
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)

#define XLAP_FILTER_AXIM_LITES_ADDR_AP_CTRL 0x00
#define XLAP_FILTER_AXIM_LITES_ADDR_GIE 0x04
#define XLAP_FILTER_AXIM_LITES_ADDR_IER 0x08
#define XLAP_FILTER_AXIM_LITES_ADDR_ISR 0x0c
#define XLAP_FILTER_AXIM_LITES_ADDR_CAM_ADDR_DATA 0x14
#define XLAP_FILTER_AXIM_LITES_BITS_CAM_ADDR_DATA 32
#define XLAP_FILTER_AXIM_LITES_ADDR_LAP_ADDR_DATA 0x1c
#define XLAP_FILTER_AXIM_LITES_BITS_LAP_ADDR_DATA 32
#define XLAP_FILTER_AXIM_LITES_ADDR_AP_RETURN 0x20
#define XLAP_FILTER_AXIM_LITES_BITS_AP_RETURN 32

  1. 2014年02月09日 06:11 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/2738-d273ea4c
この記事にトラックバックする(FC2ブログユーザー)