FC2カウンター FPGAの部屋 Vivado HLS で PWM モジュールIP を作ってみた

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

FPGAの部屋

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

Vivado HLS で PWM モジュールIP を作ってみた

Zybot のモーターコントロール用Hブリッジ回路のPmodの Digilent PmodHB5 を制御するPWM モジュールIP をVivado HLS 2016.1 で作ってみた。

2016/06/24 : 更新: PWMモジュールのC コードにバグがあったので、”Vivado HLS で PWM モジュールIP を作ってみた2”で修正しました)

PmodHB5 のマニュアルによると、2KHz の周期(500 us)でPWMをすれば良さそうだ。Vivado HLS で作るとすると、100MHz のクロックを使用して、0 ~ 100 の出力を変化させることにしよう。まずは 100回ループしてスイッチング・レート の値まで PWM出力に 1 を出力するのだが、それだけだと速すぎてしまうので、Waiting Loop として 500 カウントする。それすれば、合計 50000 カウントするので、500 us になる予定だ。

PWMmodule というVivado HLS 2016.1 のプロジェクトを作成した。
PWMmodule_1_160609.png

次に、ソースファイルのPWMmodule.cpp を示す。なるべくPWM の精度を高めたかったので、PIPELINEディレクティブの rewind オプションを追加した。なお、このPWM モジュールはLinux から使おうと思っているので、AXI4-Lite のSlave デバイスにした。
sw_late 入力には、スイッチグ・レートを入力する。0 ~ 100 までだ。PWM出力のパーセンテージを設定する。これは、AXI4-Lite のレジスタにマップする。
pwm_out はPWM出力で、これはポートである必要があるので、インターフェースを ap_none とした。

// PWMmodule.cpp
// 2016/06/08 by marsee
// PmodHB5のPWM用モジュール
// 100MHzのクロックで2KHz(500us)のPWM出力(最初に500分周する)

#include <ap_int.h>

void pwm(ap_uint<7> sw_late, volatile ap_uint<1> *pwm_out){
#pragma HLS INTERFACE ap_none register port=pwm_out
#pragma HLS INTERFACE s_axilite port=sw_late
#pragma HLS INTERFACE s_axilite port=return

    for (int i=1; i<=100; i++){
        for (int n=0; n<500; n++){
#pragma HLS PIPELINE II=1 rewind
            if (sw_late == 0){
                *pwm_out = 0;
            } else if(i==1){
                *pwm_out = 1;
            } else if (sw_late < i){
                *pwm_out = 0;
            }
        }
    }
}


テストベンチのPWMmodule_tb.cpp を示す。

// PWMmodule_tb.cpp
// 2016/06/08 by marsee
// PWMmodule用テストベンチ
//

#include <ap_int.h>

void pwm(ap_uint<7> sw_late, volatile ap_uint<1> *pwm_out);

int main(){
    ap_uint<1> pwmo, *pwm_out;

    pwm_out = &pwmo;

    pwm(0, pwm_out);
    pwm(50, pwm_out);
    pwm(100, pwm_out);

    return 0;
}


これで、C シミュレーションを行っても意味がないので、C コードの合成を行った。結果を示す。
PWMmodule_2_160609.png

Estimated は 5.24 ns なので、100MHz クロックで使用するには、全く問題ない。
Interval はPIPELINEディレクティブのrewind オプションのために 50000 クロックぴったりになっている。

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

C/RTL コシミュレーションの波形を観察した。
PWMmodule_4_160609.png

1つのPWM 出力が 500.32 us 掛かっているので、500 / 500.32 ≒ 0.999 よって、0.1 % 程度の誤差だったので、問題ないだろう?と思う。それにオートリスタートの場合は 500 us ぴったりになることが期待できる。

最後にIP 化を行った。
PWMmodule_5_160609.png

PWM モジュールもViado HLS でAXI4-Lite バスのSlave として、数時間で書くことができた。50000 クロックにするのにいろいろと試行錯誤をしたので、少し時間がかかったが、HDL で書いていたら、AXI4-Lite のSlave を書いたりするので、2,3日はかかると思う。
Vivado HLS を使用して C で実装したので、とっても速くできたと思う。
  1. 2016年06月09日 04:46 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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