FC2カウンター FPGAの部屋 PmodHB5 のセンサー・フィードバック処理IP を作ってみた

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

FPGAの部屋

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

PmodHB5 のセンサー・フィードバック処理IP を作ってみた

PmodHB5 のPWM 部分は”Vivado HLS で PWM モジュールIP を作ってみた”で完成したが、センサー・フィードバック・ピンの処理は作っていなかったので、作成する。

2016/06/25 : Cコードを修正しました。詳しくは、”PmodHB5 のセンサー・フィードバック処理IP を作ってみた2”を参照ください)

PmodHB5™ Reference Manual によると、モーターのセンサー・フィードバック・ピンの SA, SB があるので、それを処理するIP を作成することにする。Project 10: Frequency Measurement Using Input Captureに PmodHB5のPWM、SA、SBの波形が13ページに載っているが、これを見るとモーターの回転速度が速くなると、SA や SB のパルスの周波数が高くなり、回転方向が変わると SA と SB の相対位置が変化するようだ。

このPmodHB5 のセンサー・フィードバック処理IP をVivado HLS で作る際には、どのような方法でC ソースコードを書くか迷った。通常の ap_uint<1> SA, SB で書いたのでは、C ソースコードは書けるのだが、テストベンチは書くことができなかった。それは、なぜか?というと、通常のC では、関数をコールするときには、引数はステーブルになっていて、引数によって導かれる答えを返す。ところが、SA や SB は関数コールされてからもハードウェアなので、値が変動する。それに応じて処理を行う必要があるため、通常のC コードではテストベンチを書くことができない。
配列渡しにしても、インターフェースはRAM インターフェースになってしまって、うまく行かなかった。
そこで、HLSストリームライブラリを使うことにした。HLSストリームライブラリを使用すると、Valid, Ack 信号が生成されてしまう。Valid 信号は 1 固定とし、Ack 信号は無視することにしようと思う。

それではソースを貼っておく。
まずは、motor_monitor.h から。

// motor_monitor.h
// 2016/06/16 by marsee
//

#ifndef __MOTOR_MONITOR___
#define __MOTOR_MONITOR___

#include <ap_int.h>

typedef ap_uint<1> ap_uint_1;
#endif


次に、ソースの motor_monitor.cpp を貼っておく。

// motor_monitor.cpp
// 2016/06/15 by marsee
//

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

#include "motor_monitor.h"

int motor_monitor(hls::stream<ap_uint_1 >& sa, hls::stream<ap_uint_1 >& sb,
        ap_uint<32> & sa_count, ap_uint_1 & sb_level, ap_uint_1 & overflow){
#pragma HLS INTERFACE s_axilite port=overflow
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE s_axilite port=sb_level
#pragma HLS INTERFACE s_axilite port=sa_count
#pragma HLS INTERFACE ap_hs port=sb
#pragma HLS INTERFACE ap_hs port=sa

    ap_uint_1 sad;
    ap_uint_1 sbd;

    overflow = 0;
    for (sa_count=0; sa_count!=0xffffffff; sa_count++){ // sa=1の間はループ
#pragma HLS PIPELINE II=1
        sa >> sad;
        sb >> sbd;
        if (sa_count == 0xfffffffe) // overflow
            overflow = 1;
        if (!sad)
            break;
    }

    for (sa_count=1; sa_count!=0xffffffff; sa_count++){ // sa=0の間はループ
#pragma HLS PIPELINE II=1
        sa >> sad;
        sb >> sbd;
        if (sa_count == 0xfffffffe) // overflow
            overflow = 1;
        if (sad)
            break;
    }

    sb_level = sbd; // saが立ち上がった時のsbの値

    for (sa_count++; sa_count!=0xffffffff; sa_count++){ // sa=1の間はループ
#pragma HLS PIPELINE II=1
        sa >> sad;
        sb >> sbd;
        if (sa_count == 0xfffffffe) // overflow
            overflow = 1;
        if (!sad)
            break;
    }

    return 0;
}


次に、テストベンチの motor_monitor_tb.cpp を貼っておく。

// motor_monitor_tb.cpp
// 2016/06/15 by marsee
//

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

#include "motor_monitor.h"

#define DATASIZE 20

int motor_monitor(hls::stream<ap_uint_1 >& sa, hls::stream<ap_uint_1 >& sb,
        ap_uint<32> & sa_count, ap_uint_1 & sb_level, ap_uint_1 & overflow);

int main(){
    using namespace std;

    ap_uint_1 saa[DATASIZE] = {1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1};
    ap_uint_1 sba[DATASIZE] = {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1};

    hls::stream<ap_uint_1> sa;
    hls::stream<ap_uint_1> sb;

    ap_uint<32> sa_count;
    ap_uint_1 sb_level;
    ap_uint_1 overflow;

    for (int i=0; i<DATASIZE; i++){
        sa << saa[i];
        sb << sba[i];
    }
    motor_monitor(sa, sb, sa_count, sb_level, overflow);

    printf("*sa_count = %d, *sb_level = %d, overflow = %d\n",
            (unsigned int)sa_count, (unsigned int)sb_level, (unsigned int)overflow);

    return 0;
}


これでC シミュレーションを行った。
reg_write_read_22_160618.png

C コードの合成を行った。
reg_write_read_23_160618.png

C/RTLコシミュレーションを行った。
reg_write_read_24_160618.png

C/RTLコシミュレーション波形を確認したl。
reg_write_read_25_160618.png

1 + 2 = 3 クロック分Wait が入っているが、後で、sa_count の値に +3 すればよいだろう。
  1. 2016年06月18日 08:16 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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