FC2カウンター FPGAの部屋 レジスタ設定用AXI4 Master IPをVivado HLS で作ってみた

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

FPGAの部屋

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

レジスタ設定用AXI4 Master IPをVivado HLS で作ってみた

PWM モジュールIP をシミュレーションするために、レジスタ設定用AXI4 Master IPをVivado HLS で作ってみた。

PWM モジュールIP は単体ではVivado HLS のC/RTLコシミュレーションで、PWM がきちんと動作するのを確認した。しかし、AXI4-Lite Slave IP として実際に使用するためには、AXI4 Lite Slave スタートさせた後、オートリスタートにする必要がある。さらに、オートリスタートしている間にPWM の比率を変更できるかどうか?も気になる点だ。よって、HDL レベルでシミュレーションを行いたいのだが、依然作製してある reg_set_axi_lite_master IP では、ある一定時間Wait することができないし、Read もできないので、Vivado HLS で作ってみることにした。

Vivado HLS 2016.2 を使って、reg_write_read プロジェクトを作成した。
reg_write_read_1_160613.png

まずは、レジスタ設定のWrite/Read を指定する配列 reg_ad[AD_ARRAY_LIMIT][4] を reg_write_read.h に書いた。フォーマットを次に示す。

// reg_addr_data フォーマット、
// 第1フィールド(reg_ad[x][0]):Write - 0, Read - 1
// 第2フィールド(reg_ad[x][1]):Delay、単位はクロック数
// 第3フィールド(reg_ad[x][2]):アドレス、16進数
// 第4フィールド(reg_ad[x][3]):データ、16進数
//
// 終了は第2フィールド:Delayに 0xffffffff が書いてあったとき


例えば、{0, 10, 0x104, 2} は、Write、ディレイが10 クロック、0x104 番地に 2 をWrite する。
最初に reg_write_read.h の一部を示す。

// reg_write_read.h
// 2016/06/10 by marsee
//
// reg_addr_data フォーマット、
// 第1フィールド(reg_ad[x][0]):Write - 0, Read - 1
// 第2フィールド(reg_ad[x][1]):Delay、単位はクロック数
// 第3フィールド(reg_ad[x][2]):アドレス、16進数
// 第4フィールド(reg_ad[x][3]):データ、16進数
//
// 終了は第2フィールド:Delayに 0xffffffff が書いてあったとき

#define AD_ARRAY_LIMIT 256
#define REG_WRITE 0
#define REG_READ 1

#define R_W_FIELD 0
#define DELAY_FIELD 1
#define ADDRESS_FIELD 2
#define DATA_FIELD 3

const unsigned int reg_ad[AD_ARRAY_LIMIT][4]={
        {000x1001},
        {1200x1000},
        {0100x1042},
        {0, 0xffffffff, 0, 0},
        {1000},
        {0000},
        {1000},
        {0000},
        {1000},
        {0000},
        {1000},
        {0000},


次に、reg_write_read.cpp を示す。

// reg_write_read.cpp
// 2016/06/11 by marsee
//
// レジスタにWrite or Read する
//

#include "reg_write_read.h"

int reg_write_read(volatile int *axi4m, volatile int *dummy_out){
#pragma HLS INTERFACE ap_none port=dummy_out
#pragma HLS INTERFACE ap_ctrl_hs port=return
#pragma HLS INTERFACE m_axi depth=1024 port=axi4m offset=off

    int ret;

    for(int i=0; i<255; i++){
        if(reg_ad[i][DELAY_FIELD] == 0xffffffff) // end
            break;
        for(unsigned int n=0; n<reg_ad[i][DELAY_FIELD]; n++){ // Delay count
#pragma HLS PIPELINE II=1
            *dummy_out = n;
        }
        int index = reg_ad[i][ADDRESS_FIELD]/sizeof(unsigned int);
        if(reg_ad[i][R_W_FIELD] == REG_WRITE){
            axi4m[index] = reg_ad[i][DATA_FIELD];
        } else { // read
            *dummy_out = axi4m[index];
        }
    }
}


20行弱のコードで書けてしまった。

次にテストベンチのreg_write_read_tb.cpp を示す。

// reg_write_read_tb.cpp
// 2016/06/12 by marsee
//

int reg_write_read(volatile int *axi4m, volatile int *dummy_out);

int main(){
    int axi4m[512];
    int dm_out;

    reg_write_read(axi4m, &dm_out);

    return 0;
}


これで C コードの合成を行った。結果を示す。
reg_write_read_2_160613.png 

Verilog コードを見ると、フィールドごとにROM になっていた。第 3 フィールドのアドレスを見ると、3 桁の16進数になっていた。
reg_write_read_6_160613.png 

アドレスのROM を読み込んでいるVerilog コードを見ると、DWIDTH が 9 ビットになっていた。
reg_write_read_7_160613.png 

これは後で、最大桁のアドレスや、ディレイの値を入れる必要があるようだ。最適なビット数に丸められてしまう。C/RTL コシミュレーションの関係でこのアドレスになったが、後で修正する。

次に、C/RTLコシミュレーションを行った。
reg_write_read_3_160613.png

シミュレーション波形はできたので、見てみよう。
reg_write_read_4_160613.png

reg_write_read_5_160613.png

AXI4 Master の Write と Read がうまくできているようだ。Wait も働いているようだ。

  1. 2016年06月13日 05:52 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3492-9f597de0
この記事にトラックバックする(FC2ブログユーザー)