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

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

FPGAの部屋

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

Bambu で実装した hls stream インターフェースのメディアン・フィルタに tlast を追加する3

Bambu で実装した hls stream インターフェースのメディアン・フィルタに tlast を追加する2”の続き。

median_hlsst_RGB24 に tlast を追加するということで、前回は、median_hlsst_RGB24.cpp を Bambu で高位合成して、median_hlsst_RGB24.v を生成した。今回は、Cocotb でシミュレーションを行って、tlast が正常に出力できているのが確認できた。

PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリにある Makefile とテストベンチの test_median.py はそのまま使用することができる。

tlast 付きで生成された median_hlsst_RGB24.v を PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリにコピーした。
シミュレーション時に VCD ファイルを出力するため、median_hlsst_RGB24.v の endmodule の前に以下の文を追加した。

// the "macro" to dump signals
`ifdef COCOTB_SIM
initial begin
  $dumpfile ("median_hlsst_RGB24.vcd");
  $dumpvars (0, median_hlsst_RGB24);
  #1;
end
`endif


bambu_257_240124.png

これで、準備が終わったので、PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリに行って、make を実行し、シミュレーションを行った。
ログを示す。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb$ make
rm -f results.xml
make -f Makefile results.xml
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb' に入ります
rm -f results.xml
MODULE=test_median TESTCASE= TOPLEVEL=median_hlsst_RGB24 TOPLEVEL_LANG=verilog \
         /usr/bin/vvp -M /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb/libs -m libcocotbvpi_icarus   sim_build/sim.vvp 
     -.--ns INFO     gpi                                ..mbed/gpi_embed.cpp:76   in set_program_name_in_venv        Did not detect Python virtual environment. Using system-wide Python interpreter
     -.--ns INFO     gpi                                ../gpi/GpiCommon.cpp:101  in gpi_print_registered_impl       VPI registered
     0.00ns INFO     cocotb                             Running on Icarus Verilog version 11.0 (stable)
     0.00ns INFO     cocotb                             Running tests with cocotb v1.7.0 from /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb
     0.00ns INFO     cocotb                             Seeding Python random module with 1706039891
     0.00ns INFO     cocotb.regression                  Found test test_median.test_median
     0.00ns INFO     cocotb.regression                  running test_median (1/1)
VCD info: dumpfile median_hlsst_RGB24.vcd opened for output.
674111.00ns INFO     cocotb.regression                  test_median passed
674111.00ns INFO     cocotb.regression                  **************************************************************************************
                                                        ** TEST                          STATUS  SIM TIME (ns)  REAL TIME (s)  RATIO (ns/s) **
                                                        **************************************************************************************
                                                        ** test_median.test_median        PASS      674111.00          76.64       8795.42  **
                                                        **************************************************************************************
                                                        ** TESTS=1 PASS=1 FAIL=0 SKIP=0             674111.00          77.01       8753.08  **
                                                        **************************************************************************************
                                                        
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb' から出ます


median.jpg が生成された。median.jpg は”Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する3”と同じ結果だった。
bambu_199_240111.png

median_hlsst_RGB24.vcd ファイルが生成されたので、GTKWave で確認した。
bambu_258_240124.png

始まりの部分を拡大する。
bambu_259_240124.png

outs_write の間隔は 14 クロックだった。Vitis HLS で実装した場合の 1/14 のスループットということが言える。

最後の部分を拡大した。
bambu_260_240124.png

done_port に 1 が出る前の最後のトランザクションで、outs_din が 0x18E826A になっていて、tlast が 1 になっているのが分かった。最後以外の tlast は 0 のようだ。
  1. 2024年01月24日 05:17 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0

Bambu で実装した hls stream インターフェースのメディアン・フィルタに tlast を追加する1

Bambu で高位合成した median_hlsst_RGB24 を ZUBoard 1CG の PYNQ で試してみる6”で AXI DMA を正常に動作させるためには AXI4-Stream インターフェースの tlast が必要ということが分かった。よって、”Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する1”で実装した median_hlsst_RGB24 に tlast を追加する。

tlast の実装方法について、いろいろと検討した。
ap_uint<24> tdata と ap_uint<1> tlast の構造体の hls stream を作って、tdata と tlast のポートが出れば良かったのだが、出なかったのでボツにした。
こんな感じだ。

typedef struct AXIS_STREAM_FORMAT {
    ap_uint<24> tdata;
    ap_uint<1> tlast;
} AXIS_STREAM;

int median_hlsst_RGB24(hls::stream<ap_uint<24> >& ins,
        hls::stream<AXIS_STREAM >& outs,
         int32_t row_size, int32_t col_size){


結局、出力の hls stream を 24 ビットから 25 ビットにして、最上位の 1 ビットを tlast にすることにした。
修正した median_hlsst_RGB24.cpp を示す。

// median_hlsst_RGB24.cpp
// 2024/01/09 by marsee
// 2024/01/21 : outs の 25 ビット目に tlast を割り当てた

// bmp_header.h
// BMP ファイルフォーマットから引用させて頂きました
// http://www.kk.iij4u.or.jp/~kondo/bmp/
//
// 2017/05/04 : takseiさんのご指摘によりintX_tを使った宣言に変更。takseiさんありがとうございました
//              変数の型のサイズの違いによってLinuxの64ビット版では動作しなかったためです
//              http://marsee101.blog19.fc2.com/blog-entry-3354.html#comment2808
//

#include <stdio.h>
#include <stdint.h>

// BITMAPFILEHEADER 14bytes
typedef struct tagBITMAPFILEHEADER {
    uint16_t bfType;
    uint32_t bfSize;
    uint16_t bfReserved1;
    uint16_t bfReserved2;
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

// BITMAPINFOHEADER 40bytes
typedef struct tagBITMAPINFOHEADER{
    uint32_t biSize;
    int32_t biWidth;
    int32_t biHeight;
    uint16_t biPlanes;
    uint16_t biBitCount;
    uint32_t biCompression;
    uint32_t biSizeImage;
    int32_t biXPixPerMeter;
    int32_t biYPixPerMeter;
    uint32_t biClrUsed;
    uint32_t biClrImporant;
} BITMAPINFOHEADER;

typedef struct BMP24bitsFORMAT {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} BMP24FORMAT;

// medain_axis_RGB24.cpp
// 2024/01/09 by marsee
// 2024/01/21 : outs の 25 ビット目に tlast を割り当てた

#include <cstdint>
#include <stdint.h>
#include <ap_int.h>
#include <hls_stream.h>

constexpr int size = 3;

struct pix_st{
    uint32_t pix;
    uint32_t index;
};

const char BMP_FILE_NAME[] = "test2.bmp";
const char MEDIAN_FILE_NAME[] = "median.bmp";

void median_fil(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result);
void pixel_sort(pix_st *y);
ap_uint<32> conv_rbg2y(ap_uint<32> rbg);

int median_hlsst_RGB24(hls::stream<ap_uint<24> >& ins,
        hls::stream<ap_uint<25> >& outs,
         int32_t row_size, int32_t col_size){
    ap_uint<25> madianat;
    ap_uint<24> pix;
    ap_uint<24> median;
    ap_uint<24> val;

    ap_int<32> line_buf[2][1920];
    ap_int<32> pix_mat[size][size];

    LOOP_Y: for(int y=0; y<row_size; y++){
        LOOP_X: for(int x=0; x<col_size; x++){
            pix = ins.read(); // AXI4-Stream からの入力

            LOOP_PIX_MAT_K: for(int k=0; k<3; k++){
                LOOP_PIX_MAT_M: for(int m=0; m<2; m++){
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];
            ap_int<32> y_val = pix;
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            median_fil(pix_mat, val);
            median = val;
            if(x<2 || y<2)
                median = 0;

            madianat = (ap_uint<25>)median;
            if(y==(row_size-1) && x==(col_size-1))
                madianat |= 0x1000000; // tlast を加えた

            outs.write(madianat);
        }
    }
    return(0);
}

// median filter
//
// x0y0 x1y0 x2y0
// x0y1 x1y1 x2y1
// x0y2 x1y2 x2y2
//
void median_fil(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result){
    pix_st pixst[size*size];
    uint32_t index;

    for(int i=0; i<size*size; i++){
        pixst[i].pix = (uint32_t)conv_rbg2y(pix_mat[i/size][i%size]);
        pixst[i].index = i;
    }

    pixel_sort(pixst);
    
    index = pixst[4].index; // 中央値
    result = (ap_uint<24>)pix_mat[index/size][index%size];
}

// pixel_sort()
// bubble sort
// ”メジアン(中央値)、範囲(レンジ)、ヒストグラムを求める”参照
// https://cgengo.sakura.ne.jp/arg04.html
void pixel_sort(pix_st *y){
#pragma HLS ARRAY_PARTITION variable=y dim=1 complete
    pix_st tmp;

    for(int i=1; i<size*size; i++){
        for(int j=0; j<size*size-i; j++){
            if(y[j].pix < y[j+1].pix){
                tmp = y[j];
                y[j] = y[j+1];
                y[j+1] = tmp;
            }
        }
    }
}

// RBGからYへの変換
// RBGのフォーマットは、{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 にした
ap_uint<32> conv_rbg2y(ap_uint<32> rbg){
    ap_uint<32> r, g, b, y_f;
    ap_uint<32> y;

    b = rbg & 0xff;
    g = (rbg>>8) & 0xff;
    r = (rbg>>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);
}

int main(){
    hls::stream<ap_uint<24>> ins;
    hls::stream<ap_uint<25>> outs;
    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw, *fbmpwf;
    uint32_t *rd_bmp, *hw_median;
    uint32_t blue, green, red;
    uint32_t pix, val;
    uint32_t tlast;

    if ((fbmpr = fopen(BMP_FILE_NAME, "rb")) == NULL){ // BMP ファイル をオープン
        fprintf(stderr, "Can't open %s by binary read mode\n", BMP_FILE_NAME);
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(uint32_t *)malloc(sizeof(uint32_t) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_median =(uint32_t *)malloc(sizeof(uint32_t) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_median memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);
        
    // ins に入力データを用意する
    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            pix = (uint32_t)rd_bmp[(j*bmpihr.biWidth)+i];
            ins.write(pix);
        }
    }
    
    median_hlsst_RGB24(ins, outs, bmpihr.biHeight, bmpihr.biWidth); // メディアン・フィルタ
    
    // メディアン・フィルタ処理後の値をhw_medianバッファに代入
    for (int y=0; y<bmpihr.biHeight; y++){ // 結果の画像サイズはx-2, y-2
        for (int x=0; x<bmpihr.biWidth; x++){
            val = (uint32_t)outs.read();
            if(val >= 0x1000000)
                tlast = 1;
            else
                tlast = 0;
            val &= 0xffffff;
            hw_median[y*bmpihr.biWidth+x] = val;
        }
    }
    
    // 元画像の出力結果を temp_org.bmp へ出力する
    if ((fbmpw=fopen(MEDIAN_FILE_NAME, "wb")) == NULL){
        fprintf(stderr, "Can't open %s by binary write mode\n", MEDIAN_FILE_NAME);
        exit(1);
    }
    // BMPファイルヘッダの書き込み
    fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);

    // RGB データの書き込み、逆順にする
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = hw_median[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
            green = (hw_median[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
            red = (hw_median[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

            fputc(blue, fbmpw);
            fputc(green, fbmpw);
            fputc(red, fbmpw);
        }
    }
    fclose(fbmpw);
    free(rd_bmp);
    free(hw_median);
    
    return(0);
}


median_hlsst_RGB24.cpp を g++ コンパイラでコンパイルした。
g++ -o median_hlsst_RGB24 -I/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/etc/libbambu/ac_types/include median_hlsst_RGB24.cpp

median_hlsst_RGB24 実行形式ファイルが生成された。

ノイズ入りの test2.bmp ファイルを用意した。
bambu_186_240110.jpg

median_hlsst_RGB24 を実行した。
./median_hlsst_RGB24

median.bmp ファイルが生成された。
median.bmp を見ると、ノイズが除去されているのが分かった。
bambu_189_240110.jpg
  1. 2024年01月22日 04:42 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する3

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する2”の続き。

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成してみようということで、前回は、median_hlsst_RGB24.cpp を Bambu で高位合成して、median_hlsst_RGB24.v を生成した。今回は、前回、シミュレーションができなかったので、Cocotb でシミュレーションを行った。

前回、シミュレーションができなかったので、Cocotb でシミュレーションを行う。
Python のテストベンチは OpenCV を使用して、80 x 60 ピクセルの test2.jpg をメモリにロードし、それにメディアン・フィルタを掛けて median.jpg ファイルに出力する。
test2.jpg はノイズの入った画像となっている。
PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリを作成し、移動して、作業を行った。

まずは、Makefile から示す。

# Makefile
# 2024/01/11 by marsee

SIM ?= icarus

VERILOG_SOURCES = $(shell pwd)/median_hlsst_RGB24.v
TOPLEVEL = median_hlsst_RGB24
MODULE = test_median

include $(shell cocotb-config --makefiles)/Makefile.sim


テストベンチの test_median.py を示す。

# test_median.py
# 2024/01/11 by marsee

import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, RisingEdge

import cv2
import numpy as np

@cocotb.test()
async def test_median(dut):
    img = cv2.imread('test2.jpg')
    img2 = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
    
    dut.row_size.value = img.shape[0]
    dut.col_size.value = img.shape[1]
    
    dut.reset.value = 0 # Reset
    dut.start_port.value = 0

    clock = Clock(dut.clock, 10, units="ns")  # Create a 10ns period clock on port clk
    cocotb.start_soon(clock.start())  # Start the clock

    await Timer(21, units='ns')

    dut.reset.value = 1 # Normal Operation
    dut.ins_empty_n.value = 1
    dut.outs_full_n.value = 1

    for i in range(3):
        await RisingEdge(dut.clock)
    await Timer(1, units='ns')
    
    dut.start_port.value = 1
    for row in range(img.shape[0]):
        for col in range(img.shape[1]):
            pixel = int(img[row, col, 0]) + int((img[row, col, 1] << 8)) + int((img[row, col, 2] << 16)) # RGB
            dut.ins_dout.value = pixel
            if i == 1:
                dut.start_port = 0
            await RisingEdge(dut.clock)
            await Timer(1, units='ns')
            while dut.ins_read.value == 0:
                await RisingEdge(dut.clock)
                await Timer(1, units='ns')
            #print("row = {0}, col = {1}".format(row, col))
            img2[row, col, 2] = (int(dut.outs_din.value) / 65536) % 256
            img2[row, col, 1] = (int(dut.outs_din.value) / 256) % 256
            img2[row, col, 0] = int(dut.outs_din.value) % 256
    
    for i in range(100):
        await RisingEdge(dut.clock)
        await Timer(1, units='ns')
    
    cv2.imwrite('median.jpg', img2)


前回生成された median_hlsst_RGB24.v を PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリにコピーした。
シミュレーション時に VCD ファイルを出力するため、median_hlsst_RGB24.v の endmodule の前に以下の文を追加した。

// the "macro" to dump signals
`ifdef COCOTB_SIM
initial begin
  $dumpfile ("median_hlsst_RGB24.vcd");
  $dumpvars (0, median_hlsst_RGB24);
  #1;
end
`endif


bambu_195_240111.png

ノイズ入 80 x 60 ピクセルの test2.jpg を加えた現在の PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリを示す。
bambu_194_240111.png

PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリに行って、make を実行し、シミュレーションを行った。
bambu_196_240111.png

bambu_197_240111.png

成功した。
ログを示す。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb$ make
rm -f results.xml
make -f Makefile results.xml
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb' に入ります
/usr/bin/iverilog -o sim_build/sim.vvp -D COCOTB_SIM=1 -s median_hlsst_RGB24 -f sim_build/cmds.f -g2012   /media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb/median_hlsst_RGB24.v
rm -f results.xml
MODULE=test_median TESTCASE= TOPLEVEL=median_hlsst_RGB24 TOPLEVEL_LANG=verilog \
         /usr/bin/vvp -M /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb/libs -m libcocotbvpi_icarus   sim_build/sim.vvp 
     -.--ns INFO     gpi                                ..mbed/gpi_embed.cpp:76   in set_program_name_in_venv        Did not detect Python virtual environment. Using system-wide Python interpreter
     -.--ns INFO     gpi                                ../gpi/GpiCommon.cpp:101  in gpi_print_registered_impl       VPI registered
     0.00ns INFO     cocotb                             Running on Icarus Verilog version 11.0 (stable)
     0.00ns INFO     cocotb                             Running tests with cocotb v1.7.0 from /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb
     0.00ns INFO     cocotb                             Seeding Python random module with 1704914826
     0.00ns INFO     cocotb.regression                  Found test test_median.test_median
     0.00ns INFO     cocotb.regression                  running test_median (1/1)
VCD info: dumpfile median_hlsst_RGB24.vcd opened for output.
674111.00ns INFO     cocotb.regression                  test_median passed
674111.00ns INFO     cocotb.regression                  **************************************************************************************
                                                        ** TEST                          STATUS  SIM TIME (ns)  REAL TIME (s)  RATIO (ns/s) **
                                                        **************************************************************************************
                                                        ** test_median.test_median        PASS      674111.00          68.94       9777.69  **
                                                        **************************************************************************************
                                                        ** TESTS=1 PASS=1 FAIL=0 SKIP=0             674111.00          79.22       8509.74  **
                                                        **************************************************************************************
                                                        
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb' から出ます


シミュレーション後の PandA-bambu-2023.1/examples/median_hlsst_RGB24/cocotb ディレクトリを示す。
bambu_202_240111.png

median.jpg が生成されていた。
median.jpg を元画像の test2.jpg と比較してみよう。
bambu_199_240111.png

ノイズは除去されているようだ。

median_hlsst_RGB24.vcd ファイルが生成されたので、GTKWave で確認してみた。
bambu_200_240111.png

拡大する。
bambu_201_240111.png

1 ピクセルの処理に 14 クロック掛かっているようだ。遅い。。。
  1. 2024年01月12日 05:07 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する2

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する1”の続き。

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成してみようということで、前回は、C++ ソースコードの median_hlsst_RGB24.cpp を示して、g++ コンパイラでコンパイルし動作を確認した。今回は、median_hlsst_RGB24.cpp を Bambu で高位合成して、median_hlsst_RGB24.v を生成した。

median_hlsst_RGB24.cpp を Bambu で高位合成した。
bambu median_hlsst_RGB24.cpp --top-fname=median_hlsst_RGB24 -I/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/etc/libbambu/ac_types/include --compiler=I386_CLANG13 -O5 --generate-tb=test.xml --simulator=ICARUS --print-dot --simulate --generate-vcd --generate-interface=INFER --registered-inputs=no -p=mult=1
bambu_190_240111.png

bambu_191_240111.png

ログを示す。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/median_hlsst_RGB24$ bambu median_hlsst_RGB24.cpp --top-fname=median_hlsst_RGB24 -I/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/etc/libbambu/ac_types/include --compiler=I386_CLANG13 -O5 --generate-tb=test.xml --simulator=ICARUS --print-dot --simulate --generate-vcd --generate-interface=INFER --registered-inputs=no -p=mult=1
 ==  Bambu executed with: /tmp/.mount_bambumuXWS6/usr/bin/bambu --top-fname=median_hlsst_RGB24 -I/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/etc/libbambu/ac_types/include --compiler=I386_CLANG13 -O5 --generate-tb=test.xml --simulator=ICARUS --print-dot --simulate --generate-vcd --generate-interface=INFER --registered-inputs=no -p=mult=1 median_hlsst_RGB24.cpp 


********************************************************************************
                    ____                  _
                   | __ )  __ _ _ __ ___ | |_   _   _
                   |  _ \ / _` | '_ ` _ \| '_ \| | | |
                   | |_) | (_| | | | | | | |_) | |_| |
                   |____/ \__,_|_| |_| |_|_.__/ \__,_|

********************************************************************************
                         High-Level Synthesis Tool

                         Politecnico di Milano - DEIB
                          System Architectures Group
********************************************************************************
                Copyright (C) 2004-2023 Politecnico di Milano
 Version: PandA 2023.1 - Revision 04336c437a53bc96ae90b74052c455629946ec8b-main

Target technology = FPGA
  Analyzing function _Z18median_hlsst_RGB24R10ac_channelI6ac_intILi24ELb0EEES3_ii
    Interface specification:
      Protocol  : fifo
      Bitwidth  : 24
      Alignment : 8
    Interface specification:
      Protocol  : fifo
      Bitwidth  : 24
      Alignment : 8
  Analyzed function _Z18median_hlsst_RGB24R10ac_channelI6ac_intILi24ELb0EEES3_ii

  Functions to be synthesized:
    median_hlsst_RGB24


  Memory allocation information:
    BRAM bitsize: 32
    Spec may not exploit DATA bus width
    All the data have a known address
    Internal data is not externally accessible
    DATA bus bitsize: 64
    ADDRESS bus bitsize: 17
    SIZE bus bitsize: 7
    ALL pointers have been resolved
    Internally allocated memory (no private memories): 65536
    Internally allocated memory: 96328
  Time to perform memory allocation: 0.00 seconds


  Memory allocation information:
    BRAM bitsize: 32
    Spec may not exploit DATA bus width
    All the data have a known address
    Internal data is not externally accessible
    DATA bus bitsize: 64
    ADDRESS bus bitsize: 17
    SIZE bus bitsize: 7
    ALL pointers have been resolved
    Internally allocated memory (no private memories): 65536
    Internally allocated memory: 96328
  Time to perform memory allocation: 0.00 seconds


  Memory allocation information:
    BRAM bitsize: 32
    Spec may not exploit DATA bus width
    All the data have a known address
    Internal data is not externally accessible
    DATA bus bitsize: 64
    ADDRESS bus bitsize: 17
    SIZE bus bitsize: 7
    ALL pointers have been resolved
    Internally allocated memory (no private memories): 65536
    Internally allocated memory: 96328
  Time to perform memory allocation: 0.00 seconds


  Module allocation information for function median_hlsst_RGB24:
    Number of complex operations: 26
    Number of complex operations: 26
  Time to perform module allocation: 0.38 seconds


  Scheduling Information of function median_hlsst_RGB24:
    Number of control steps: 21
    Minimum slack: 0.16582799699998785
    Estimated max frequency (MHz): 101.686242593168
  Time to perform scheduling: 0.14 seconds


  State Transition Graph Information of function median_hlsst_RGB24:
    Number of states: 21
    Done port is registered
  Time to perform creation of STG: 0.07 seconds


  Easy binding information for function median_hlsst_RGB24:
    Bound operations:168/842
  Time to perform easy binding: 0.00 seconds


  Storage Value Information of function median_hlsst_RGB24:
    Number of storage values inserted: 115
  Time to compute storage value information: 0.00 seconds

  Slack computed in 0.01 seconds
  Weight computation completed in 0.02 seconds
  False-loop computation completed in 0.00 seconds

  Register binding information for function median_hlsst_RGB24:
    Register allocation algorithm obtains a sub-optimal result: 111 registers(LB:48)
  Time to perform register binding: 0.00 seconds


  Register binding information for function median_hlsst_RGB24:
    Register allocation algorithm obtains a sub-optimal result: 111 registers(LB:48)
  Time to perform register binding: 0.01 seconds

  Clique covering computation completed in 0.01 seconds

  Module binding information for function median_hlsst_RGB24:
    Number of modules instantiated: 826
    Number of performance conflicts: 2485
    Estimated resources area (no Muxes and address logic): 9694
    Estimated area of MUX21: 349
    Total estimated area: 10043
    Estimated number of DSPs: 0
  Time to perform module binding: 0.05 seconds


  Register binding information for function median_hlsst_RGB24:
    Register allocation algorithm obtains a sub-optimal result: 111 registers(LB:48)
  Time to perform register binding: 0.00 seconds


  Connection Binding Information for function median_hlsst_RGB24:
    Number of allocated multiplexers (2-to-1 equivalent): 24
  Time to perform interconnection binding: 0.02 seconds

  Total number of flip-flops in function median_hlsst_RGB24: 2328
error -> Value of ins is missing in test vector

Please report bugs to <panda-info@polimi.it>


PandA-bambu-2023.1/examples/median_hlsst_RGB24 ディレクトリの様子を示す。
bambu_192_240111.png

median_hlsst_RGB24.v が生成されている。
bambu_193_240111.png

median_hlsst_RGB24 モジュールの入力ポート、出力ポートを示す。

  // IN
  input clock;
  input reset;
  input start_port;
  input [23:0] ins_dout;
  input [31:0] row_size;
  input [31:0] col_size;
  input ins_empty_n;
  input outs_full_n;
  // OUT
  output done_port;
  output [31:0] return_port;
  output ins_read;
  output [23:0] outs_din;
  output outs_write;


PandA-bambu-2023.1/examples/median_hlsst_RGB24/HLS_output/simulation ディレクトリは空で、VCD ファイルが生成されていなかった。
  1. 2024年01月11日 03:42 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成する1

Bambu で hls stream インターフェースのメディアン・フィルタを高位合成してみよう。今回は、C++ ソースコードの median_hlsst_RGB24.cpp を示して、g++ コンパイラでコンパイルし、動作を確認した。

PandA-bambu-2023.1/examples ディレクトリに median_hlsst_RGB24 ディレクトリを作成した。
PandA-bambu-2023.1/examples/median_hlsst_RGB24 ディレクトリに行った。

median_hlsst_RGB24.cpp を作成した。
Bambu の hls stream インターフェースで入力と出力を行う。今回は、簡単化のため、画像をスルーで出力するモードは省いてある。
main() 関数を持っていて、そのままコンパイルが可能だ。
median_hlsst_RGB24.cpp を示す。

// median_hlsst_RGB24.cpp
// 2024/01/09 by marsee

// bmp_header.h
// BMP ファイルフォーマットから引用させて頂きました
// http://www.kk.iij4u.or.jp/~kondo/bmp/
//
// 2017/05/04 : takseiさんのご指摘によりintX_tを使った宣言に変更。takseiさんありがとうございました
//              変数の型のサイズの違いによってLinuxの64ビット版では動作しなかったためです
//              http://marsee101.blog19.fc2.com/blog-entry-3354.html#comment2808
//

#include <stdio.h>
#include <stdint.h>

// BITMAPFILEHEADER 14bytes
typedef struct tagBITMAPFILEHEADER {
    uint16_t bfType;
    uint32_t bfSize;
    uint16_t bfReserved1;
    uint16_t bfReserved2;
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

// BITMAPINFOHEADER 40bytes
typedef struct tagBITMAPINFOHEADER{
    uint32_t biSize;
    int32_t biWidth;
    int32_t biHeight;
    uint16_t biPlanes;
    uint16_t biBitCount;
    uint32_t biCompression;
    uint32_t biSizeImage;
    int32_t biXPixPerMeter;
    int32_t biYPixPerMeter;
    uint32_t biClrUsed;
    uint32_t biClrImporant;
} BITMAPINFOHEADER;

typedef struct BMP24bitsFORMAT {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
} BMP24FORMAT;

// medain_axis_RGB24.cpp
// 2024/01/09 by marsee
//

#include <cstdint>
#include <stdint.h>
#include <ap_int.h>
#include <hls_stream.h>

constexpr int size = 3;

struct pix_st{
    uint32_t pix;
    uint32_t index;
};

const char BMP_FILE_NAME[] = "test2.bmp";
const char MEDIAN_FILE_NAME[] = "median.bmp";

void median_fil(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result);
void pixel_sort(pix_st *y);
ap_uint<32> conv_rbg2y(ap_uint<32> rbg);

int median_hlsst_RGB24(hls::stream<ap_uint<24> >& ins,
        hls::stream<ap_uint<24> >& outs,
         int32_t row_size, int32_t col_size){
    ap_uint<24> pix;
    ap_uint<24> median;
    ap_uint<24> val;

    ap_int<32> line_buf[2][1920];
    ap_int<32> pix_mat[size][size];

    LOOP_Y: for(int y=0; y<row_size; y++){
        LOOP_X: for(int x=0; x<col_size; x++){
            pix = ins.read(); // AXI4-Stream からの入力

            LOOP_PIX_MAT_K: for(int k=0; k<3; k++){
                LOOP_PIX_MAT_M: for(int m=0; m<2; m++){
                    pix_mat[k][m] = pix_mat[k][m+1];
                }
            }
            pix_mat[0][2] = line_buf[0][x];
            pix_mat[1][2] = line_buf[1][x];
            ap_int<32> y_val = pix;
            pix_mat[2][2] = y_val;

            line_buf[0][x] = line_buf[1][x];    // 行の入れ替え
            line_buf[1][x] = y_val;

            median_fil(pix_mat, val);
            median = val;
            if(x<2 || y<2)
                median = 0;

            outs.write(median);
        }
    }
    return(0);
}

// median filter
//
// x0y0 x1y0 x2y0
// x0y1 x1y1 x2y1
// x0y2 x1y2 x2y2
//
void median_fil(ap_int<32> (&pix_mat)[size][size], ap_uint<24> &result){
    pix_st pixst[size*size];
    uint32_t index;

    for(int i=0; i<size*size; i++){
        pixst[i].pix = (uint32_t)conv_rbg2y(pix_mat[i/size][i%size]);
        pixst[i].index = i;
    }

    pixel_sort(pixst);
    
    index = pixst[4].index; // 中央値
    result = (ap_uint<24>)pix_mat[index/size][index%size];
}

// pixel_sort()
// bubble sort
// ”メジアン(中央値)、範囲(レンジ)、ヒストグラムを求める”参照
// https://cgengo.sakura.ne.jp/arg04.html
void pixel_sort(pix_st *y){
#pragma HLS ARRAY_PARTITION variable=y dim=1 complete
    pix_st tmp;

    for(int i=1; i<size*size; i++){
        for(int j=0; j<size*size-i; j++){
            if(y[j].pix < y[j+1].pix){
                tmp = y[j];
                y[j] = y[j+1];
                y[j+1] = tmp;
            }
        }
    }
}

// RBGからYへの変換
// RBGのフォーマットは、{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 にした
ap_uint<32> conv_rbg2y(ap_uint<32> rbg){
    ap_uint<32> r, g, b, y_f;
    ap_uint<32> y;

    b = rbg & 0xff;
    g = (rbg>>8) & 0xff;
    r = (rbg>>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);
}

int main(){
    hls::stream<ap_uint<24>> ins, outs;
    BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
    BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
    FILE *fbmpr, *fbmpw, *fbmpwf;
    uint32_t *rd_bmp, *hw_median;
    uint32_t blue, green, red;
    uint32_t pix, val;

    if ((fbmpr = fopen(BMP_FILE_NAME, "rb")) == NULL){ // BMP ファイル をオープン
        fprintf(stderr, "Can't open %s by binary read mode\n", BMP_FILE_NAME);
        exit(1);
    }
    // bmpヘッダの読み出し
    fread(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpr);
    fread(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpr);
    fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);

    // ピクセルを入れるメモリをアロケートする
    if ((rd_bmp =(uint32_t *)malloc(sizeof(uint32_t) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate rd_bmp memory\n");
        exit(1);
    }
    if ((hw_median =(uint32_t *)malloc(sizeof(uint32_t) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
        fprintf(stderr, "Can't allocate hw_median memory\n");
        exit(1);
    }

    // rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = fgetc(fbmpr);
            green = fgetc(fbmpr);
            red = fgetc(fbmpr);
            rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
        }
    }
    fclose(fbmpr);
        
    // ins に入力データを用意する
    for(int j=0; j < bmpihr.biHeight; j++){
        for(int i=0; i < bmpihr.biWidth; i++){
            pix = (uint32_t)rd_bmp[(j*bmpihr.biWidth)+i];
            ins.write((ap_uint<24>)pix);
        }
    }
    
    median_hlsst_RGB24(ins, outs, bmpihr.biHeight, bmpihr.biWidth); // メディアン・フィルタ
    
    // メディアン・フィルタ処理後の値をhw_medianバッファに代入
    for (int y=0; y<bmpihr.biHeight; y++){ // 結果の画像サイズはx-2, y-2
        for (int x=0; x<bmpihr.biWidth; x++){
            val = (uint32_t)outs.read();
            hw_median[y*bmpihr.biWidth+x] = val;
        }
    }
    
    // 元画像の出力結果を temp_org.bmp へ出力する
    if ((fbmpw=fopen(MEDIAN_FILE_NAME, "wb")) == NULL){
        fprintf(stderr, "Can't open %s by binary write mode\n", MEDIAN_FILE_NAME);
        exit(1);
    }
    // BMPファイルヘッダの書き込み
    fwrite(&bmpfhr.bfType, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfSize, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved1, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfReserved2, sizeof(uint16_t), 1, fbmpw);
    fwrite(&bmpfhr.bfOffBits, sizeof(uint32_t), 1, fbmpw);
    fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);

    // RGB データの書き込み、逆順にする
    for (int y=0; y<bmpihr.biHeight; y++){
        for (int x=0; x<bmpihr.biWidth; x++){
            blue = hw_median[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
            green = (hw_median[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
            red = (hw_median[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0xff;

            fputc(blue, fbmpw);
            fputc(green, fbmpw);
            fputc(red, fbmpw);
        }
    }
    fclose(fbmpw);
    free(rd_bmp);
    free(hw_median);
    
    return(0);
}


median_hlsst_RGB24.cpp を g++ コンパイラでコンパイルした。
g++ -o median_hlsst_RGB24 -I/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/etc/libbambu/ac_types/include median_hlsst_RGB24.cpp
bambu_185_240110.png

median_hlsst_RGB24 実行形式ファイルが生成された。

ノイズ入りの test2.bmp ファイルを用意した。
bambu_186_240110.jpg

median_hlsst_RGB24 を実行した。
./median_hlsst_RGB24
bambu_187_240110.png

median.bmp ファイルが生成された。
bambu_188_240110.png

median.bmp を見ると、ノイズが除去されているのが分かる。
bambu_189_240110.jpg
  1. 2024年01月10日 03:50 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0

Bambu で自作の乗算コード(mult_axim.cpp)を高位合成する3

Bambu で自作の乗算コード(mult_axim.cpp)を高位合成する2”の続き。

前回は、AXI4 Master インターフェースの乗算をいろいろな最適化オプションで試してみた。コンパイラは Clang だった。今回は、コンパイラに GCC を使って、いろいろな最適化オプションを試した。

コンパイラに I386_GCC49 を使用して、Bambu で高位合成を行った。
bambu mult_axim.cpp --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_GCC49 --registered-inputs=no
bambu_175_240109.png

bambu_176_240109.png

シミュレーションは 122 クロックで終了した。

ログを示す。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/mult/mult_axim$ bambu mult_axim.cpp --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_GCC49 --registered-inputs=no
 ==  Bambu executed with: /tmp/.mount_bambu2lkBJI/usr/bin/bambu --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_GCC49 --registered-inputs=no mult_axim.cpp 


********************************************************************************
                    ____                  _
                   | __ )  __ _ _ __ ___ | |_   _   _
                   |  _ \ / _` | '_ ` _ \| '_ \| | | |
                   | |_) | (_| | | | | | | |_) | |_| |
                   |____/ \__,_|_| |_| |_|_.__/ \__,_|

********************************************************************************
                         High-Level Synthesis Tool

                         Politecnico di Milano - DEIB
                          System Architectures Group
********************************************************************************
                Copyright (C) 2004-2023 Politecnico di Milano
 Version: PandA 2023.1 - Revision 04336c437a53bc96ae90b74052c455629946ec8b-main

Target technology = FPGA
  Analyzing function _Z4multPiS_S_
    Interface specification:
      Protocol  : m_axi
      Bitwidth  : 32
      Alignment : 4
    Interface specification:
      Protocol  : m_axi
      Bitwidth  : 32
      Alignment : 4
    Interface specification:
      Protocol  : m_axi
      Bitwidth  : 32
      Alignment : 4
  Analyzed function _Z4multPiS_S_

  Functions to be synthesized:
    mult


  Memory allocation information:
    BRAM bitsize: 32
    Spec may not exploit DATA bus width
    All the data have a known address
    Internal data is not externally accessible
    DATA bus bitsize: 32
    ADDRESS bus bitsize: 5
    SIZE bus bitsize: 6
    Code has LOADs or STOREs with unaligned accesses
    Internally allocated memory (no private memories): 0
    Internally allocated memory: 0
  Time to perform memory allocation: 0.00 seconds


  Module allocation information for function mult:
    Number of complex operations: 4
    Number of complex operations: 4
  Time to perform module allocation: 0.01 seconds


  Scheduling Information of function mult:
    Number of control steps: 7
    Minimum slack: 1.0553999979999997
    Estimated max frequency (MHz): 111.79929787541103
  Time to perform scheduling: 0.00 seconds


  State Transition Graph Information of function mult:
    Number of states: 7
    Done port is registered
  Time to perform creation of STG: 0.01 seconds


  Easy binding information for function mult:
    Bound operations:14/22
  Time to perform easy binding: 0.00 seconds


  Storage Value Information of function mult:
    Number of storage values inserted: 9
  Time to compute storage value information: 0.00 seconds

  Slack computed in 0.00 seconds
  Weight computation completed in 0.00 seconds
  False-loop computation completed in 0.00 seconds

  Register binding information for function mult:
    Register allocation algorithm obtains a sub-optimal result: 8 registers(LB:7)
  Time to perform register binding: 0.00 seconds

  Clique covering computation completed in 0.00 seconds

  Module binding information for function mult:
    Number of modules instantiated: 21
    Number of performance conflicts: 0
    Estimated resources area (no Muxes and address logic): 150
    Estimated area of MUX21: 104
    Total estimated area: 254
    Estimated number of DSPs: 3
  Time to perform module binding: 0.00 seconds


  Register binding information for function mult:
    Register allocation algorithm obtains a sub-optimal result: 8 registers(LB:7)
  Time to perform register binding: 0.00 seconds


  Connection Binding Information for function mult:
    Number of allocated multiplexers (2-to-1 equivalent): 7
  Time to perform interconnection binding: 0.00 seconds

  Total number of flip-flops in function mult: 225
Icarus Verilog Preprocessor version 11.0 (stable) ()

Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Using language generation: IEEE1800-2012,no-specify,xtypes,icarus-misc
PARSING INPUT
LOCATING TOP-LEVEL MODULES
   mult_tb_top
 ... done, 0 seconds.
ELABORATING DESIGN
 ... done, 0 seconds.
RUNNING FUNCTORS
 -F cprop ...
 ... Iteration detected 3 optimizations.
 ... Iteration detected 0 optimizations.
 ... Look for dangling constants
 ... done
 -F nodangle ...
 ... scan for dangling signal and event nodes. (scomplete=F, ecomplete=F)
 ... 1 iterations deleted 157 dangling signals and 0 events.
 ... scan for dangling signal and event nodes. (scomplete=T, ecomplete=F)
 ... 2 iterations deleted 157 dangling signals and 20 events.
 ... done
CALCULATING ISLANDS
 ... done, 0.02 seconds.
CODE GENERATION
 ... invoking target_design
 ... done, 0 seconds.
STATISTICS
lex_string: add_count=2477 hit_count=13391
Icarus Verilog version 11.0 (stable) ()

Copyright 1998-2020 Stephen Williams

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

translate: /usr/lib/x86_64-linux-gnu/ivl/ivlpp  -v -L -F"/tmp/ivrlg24740ff" -f"/tmp/ivrlg4740ff" -p"/tmp/ivrli4740ff" | /usr/lib/x86_64-linux-gnu/ivl/ivl -v -C"/tmp/ivrlh4740ff" -C"/usr/lib/x86_64-linux-gnu/ivl/vvp.conf" -- -
VCD info: dumpfile /media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/mult/mult_axim/HLS_output//simulation/test.vcd opened for output.
VCD warning: $dumpvars: Unsupported argument type (vpiPackage)
Start reading vector           1's values from input file.

Reading of vector values from input file completed. Simulation started.
Simulation ended after                  122 cycles.

Simulation FAILED

error -> Simulation not correct!

Please report bugs to <panda-info@polimi.it>


examples/mult/mult_axim/HLS_output/simulation/test.vcd ファイルが生成された。
GTKWave で test.vcd を確認する。
なお、データは Decimal にしてある。
bambu_177_240109.png
bambu_178_240109.png

AXI4 Master の Read と Write が交互になっている。
Write と Write 間は 12 クロックだった。

次に最適化オプションの -O0 を追加した。
bambu mult_axim.cpp --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_GCC49 --registered-inputs=no -O0
bambu_179_240109.png

シミュレーションは 123 クロックで終了した。
GTKWave で test.vcd を確認する。
なお、データは Decimal にしてある。
bambu_180_240109.png
bambu_181_240109.png

Write と Write 間は最適化オプション無しと同じ 12 クロックだった。
最初に出てくるデータのレイテンシだけ増加したのだと思う。

-O1, -O2 は最適化オプション無しと同じだった。

-O3 の最適化オプションを追加して、Bambu で高位合成を行った。
bambu mult_axim.cpp --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_GCC49 --registered-inputs=no -O3
bambu_182_240109.png

シミュレーションは 111 クロックで終了した。
GTKWave で test.vcd を確認する。
なお、データは Decimal にしてある。
bambu_183_240109.png

bambu_184_240109.png

AXI4 Master の Read と Write が交互になっている。
Write と Write 間は 11 クロックだった。
GCC では、Read を全部行ってから、Write を行うことは無いようだ。

-O4, -O5 は -O3 と同様の結果だった。
  1. 2024年01月09日 04:03 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0

Bambu で自作の乗算コード(mult_axim.cpp)を高位合成する2

Bambu で自作の乗算コード(mult_axim.cpp)を高位合成する1”の続き。

今回は、Bambu では AXI4-Master インターフェースの Verilog HDL コードを出力できるので、いつもの乗算コードで試してみた。今回は、AXI4 Master インターフェースの乗算をいろいろな最適化オプションで試してみた。

最適化オプション -O0 を付加して、Bambu で高位合成を行った。
bambu mult_axim.cpp --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_CLANG13 --registered-inputs=no -O0
bambu_165_240108.png

ログを示す。

(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/mult/mult_axim$ bambu mult_axim.cpp --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_CLANG13 --registered-inputs=no -O0
 ==  Bambu executed with: /tmp/.mount_bambu7pTfUq/usr/bin/bambu --top-fname=mult --generate-tb=test.xml --generate-interface=INFER --simulator=ICARUS --simulate --generate-vcd --compiler=I386_CLANG13 --registered-inputs=no -O0 mult_axim.cpp 


********************************************************************************
                    ____                  _
                   | __ )  __ _ _ __ ___ | |_   _   _
                   |  _ \ / _` | '_ ` _ \| '_ \| | | |
                   | |_) | (_| | | | | | | |_) | |_| |
                   |____/ \__,_|_| |_| |_|_.__/ \__,_|

********************************************************************************
                         High-Level Synthesis Tool

                         Politecnico di Milano - DEIB
                          System Architectures Group
********************************************************************************
                Copyright (C) 2004-2023 Politecnico di Milano
 Version: PandA 2023.1 - Revision 04336c437a53bc96ae90b74052c455629946ec8b-main

Target technology = FPGA
  Analyzing function _Z4multPiS_S_
    Interface specification:
      Protocol  : m_axi
      Bitwidth  : 32
      Alignment : 4
    Interface specification:
      Protocol  : m_axi
      Bitwidth  : 32
      Alignment : 4
    Interface specification:
      Protocol  : m_axi
      Bitwidth  : 32
      Alignment : 4
  Analyzed function _Z4multPiS_S_

  Functions to be synthesized:
    mult


  Memory allocation information:
    BRAM bitsize: 32
    Spec may not exploit DATA bus width
    All the data have a known address
    Internal data is not externally accessible
    DATA bus bitsize: 32
    ADDRESS bus bitsize: 5
    SIZE bus bitsize: 6
    Code has LOADs or STOREs with unaligned accesses
    Internally allocated memory (no private memories): 0
    Internally allocated memory: 0
  Time to perform memory allocation: 0.00 seconds


  Module allocation information for function mult:
    Number of complex operations: 4
    Number of complex operations: 4
  Time to perform module allocation: 0.01 seconds


  Scheduling Information of function mult:
    Number of control steps: 7
    Minimum slack: 1.0063999980000145
    Estimated max frequency (MHz): 111.19017965860404
  Time to perform scheduling: 0.01 seconds


  State Transition Graph Information of function mult:
    Number of states: 7
    Done port is registered
  Time to perform creation of STG: 0.00 seconds


  Easy binding information for function mult:
    Bound operations:11/19
  Time to perform easy binding: 0.00 seconds


  Storage Value Information of function mult:
    Number of storage values inserted: 9
  Time to compute storage value information: 0.00 seconds

  Slack computed in 0.00 seconds
  Weight computation completed in 0.00 seconds
  False-loop computation completed in 0.00 seconds

  Register binding information for function mult:
    Register allocation algorithm obtains a sub-optimal result: 8 registers(LB:7)
  Time to perform register binding: 0.00 seconds

  Clique covering computation completed in 0.00 seconds

  Module binding information for function mult:
    Number of modules instantiated: 18
    Number of performance conflicts: 0
    Estimated resources area (no Muxes and address logic): 148
    Estimated area of MUX21: 104
    Total estimated area: 252
    Estimated number of DSPs: 3
  Time to perform module binding: 0.00 seconds


  Register binding information for function mult:
    Register allocation algorithm obtains a sub-optimal result: 8 registers(LB:7)
  Time to perform register binding: 0.00 seconds


  Connection Binding Information for function mult:
    Number of allocated multiplexers (2-to-1 equivalent): 7
  Time to perform interconnection binding: 0.00 seconds

  Total number of flip-flops in function mult: 225
Icarus Verilog Preprocessor version 11.0 (stable) ()

Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Using language generation: IEEE1800-2012,no-specify,xtypes,icarus-misc
PARSING INPUT
LOCATING TOP-LEVEL MODULES
   mult_tb_top
 ... done, 0 seconds.
ELABORATING DESIGN
 ... done, 0.01 seconds.
RUNNING FUNCTORS
 -F cprop ...
 ... Iteration detected 3 optimizations.
 ... Iteration detected 0 optimizations.
 ... Look for dangling constants
 ... done
 -F nodangle ...
 ... scan for dangling signal and event nodes. (scomplete=F, ecomplete=F)
 ... 1 iterations deleted 154 dangling signals and 0 events.
 ... scan for dangling signal and event nodes. (scomplete=T, ecomplete=F)
 ... 2 iterations deleted 154 dangling signals and 20 events.
 ... done
CALCULATING ISLANDS
 ... done, 0 seconds.
CODE GENERATION
 ... invoking target_design
 ... done, 0 seconds.
STATISTICS
lex_string: add_count=2475 hit_count=13086
Icarus Verilog version 11.0 (stable) ()

Copyright 1998-2020 Stephen Williams

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

translate: /usr/lib/x86_64-linux-gnu/ivl/ivlpp  -v -L -F"/tmp/ivrlg2f8b434a" -f"/tmp/ivrlgf8b434a" -p"/tmp/ivrlif8b434a" | /usr/lib/x86_64-linux-gnu/ivl/ivl -v -C"/tmp/ivrlhf8b434a" -C"/usr/lib/x86_64-linux-gnu/ivl/vvp.conf" -- -
VCD info: dumpfile /media/masaaki/Ubuntu_Disk/PandA-bambu-2023.1/examples/mult/mult_axim/HLS_output//simulation/test.vcd opened for output.
VCD warning: $dumpvars: Unsupported argument type (vpiPackage)
Start reading vector           1's values from input file.

Reading of vector values from input file completed. Simulation started.
Simulation ended after                  122 cycles.

Simulation FAILED

error -> Simulation not correct!

Please report bugs to <panda-info@polimi.it>


examples/mult/mult_axim/HLS_output/simulation/test.vcd ファイルが生成された。
GTKWave で test.vcd を確認する。
なお、データは Decimal にしてある。
bambu_166_240108.png
bambu_167_240108.png

AXI4 Master の Read と Write が交互になっている。
Write と Write 間は 12 クロックだった。
Write の値が見えなかったので、拡大した。値的には問題ないようだ。
bambu_168_240108.png

最適化オプション -O1 は -O0 と同じだった。
最適化オプション -O2, -O3, -O4, -O5 は最適化オプション無しの前回と同じ結果だった。

  1. 2024年01月08日 04:45 |
  2. Bambu
  3. | トラックバック:0
  4. | コメント:0
»