FC2カウンター FPGAの部屋 Watchdog timer を Vitis HLS 2020.1 で実装する1(Vitis HLS 2020.1)
fc2ブログ

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

FPGAの部屋

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

Watchdog timer を Vitis HLS 2020.1 で実装する1(Vitis HLS 2020.1)

GPS と 3軸加速度センサーを使ったシステム5(Vivado 2020.1 のプロジェクトを作成中)”(現在は、3軸加速度センサーが 9 個付くようになっている)に Watchdog Timer を実装することにした。そこで、Vitis HLS 2020.1 で Watchdog Timer を作成することにした。

(2020/12/26:追記)
実機で動作しなかったため enable ポートを追加しました。詳しくは、”Watchdog timer を Vitis HLS 2020.1 で実装する3(デバック修正)”を参照してください。


Watchdog Timer については、”ウォッチドッグタイマ(WDT)とは?”を参照して欲しい。
3軸加速度センサーを 9 個搭載するので、信頼性が 1/9 になるのを心配しているので、 3軸加速度センサーからのデータが途絶えても、MicroBlaze 毎に自動的にリセットできるようにしたい。(3軸加速度センサーの I2C 部分のケーブル長による波形の変化については、”GPS と 3軸加速度センサーを使ったシステム8(LAN ケーブルを 5m, 7m, 10m に伸ばした)”参照)

ウォッチドックタイマのソースコード WDTimer.cpp を示す。
動作クロックは 100 MHz なので、524289 クロックカウントしてしまったら(つまり、約 5.24 ms)、 rst_out を 1 にして、自分自身や、MicroBlaze 、AXI IIC IP などをリセットする。通常は、MicroBlaze のアプリケーション・ソフトで、 3.333 ms に 1 回は、 rst_in に 1 を入力する。

/// WDTimer.cpp
// 2020/12/23 by marsee
//

#include <ap_int.h>

int WDTimer(ap_uint<1> *rst_in, volatile ap_uint<1> *rst_out){
#pragma HLS INTERFACE ap_none register port=rst_out
#pragma HLS INTERFACE ap_ctrl_none port=return

    ap_uint<20> i;

    *rst_out = 0;
    for(i=0; i<1048575; i++){
        if(*rst_in == ap_uint<1>(1))
            i = 0;
        else
            i = i;

        if(i>524288){
            *rst_out = 1;
            --i;
        }else{
            *rst_out = 0;
        }
    }

    return(0);
}


このソースコードだと、C シミュレーションや C/RTL 協調シミュレーションはできないので、Vivado 2020.1 で RTL シミュレーションをやってみる。

Vitis HLS 2020.1 の WDTimer プロジェクトを示す。
WDTimer_1_201225.png

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

合成された WDTimer.v を示す。
WDTimer_3_201225.png

// ==============================================================
// RTL generated by Vitis HLS - High-Level Synthesis from C, C++ and OpenCL
// Version: 2020.1
// Copyright (C) 1986-2020 Xilinx, Inc. All Rights Reserved.
// 
// ===========================================================

`timescale 1 ns / 1 ps 

(* CORE_GENERATION_INFO="WDTimer_WDTimer,hls_ip_2020_1,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z020-clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=8.522000,HLS_SYN_LAT=-1,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=27,HLS_SYN_LUT=195,HLS_VERSION=2020_1}" *)

module WDTimer (
        ap_clk,
        ap_rst,
        rst_in,
        rst_out,
        ap_return
);

parameter    ap_ST_fsm_state1 = 4'd1;
parameter    ap_ST_fsm_state2 = 4'd2;
parameter    ap_ST_fsm_pp0_stage0 = 4'd4;
parameter    ap_ST_fsm_state5 = 4'd8;

input   ap_clk;
input   ap_rst;
input  [0:0] rst_in;
output  [0:0] rst_out;
output  [31:0] ap_return;

reg   [0:0] rst_out_1_data_reg;
reg   [0:0] rst_out_1_data_in;
reg    rst_out_1_vld_reg;
reg    rst_out_1_vld_in;
reg    rst_out_1_ack_in;
reg   [19:0] empty_reg_67;
(* fsm_encoding = "none" *) reg   [3:0] ap_CS_fsm;
wire    ap_CS_fsm_state2;
wire   [0:0] icmp_ln882_fu_87_p2;
wire    ap_CS_fsm_pp0_stage0;
wire    ap_block_state3_pp0_stage0_iter0;
wire    ap_block_state4_pp0_stage0_iter1;
wire    ap_block_pp0_stage0_11001;
wire   [0:0] icmp_ln890_fu_101_p2;
wire   [19:0] add_ln695_fu_114_p2;
reg    ap_enable_reg_pp0_iter0;
wire    ap_block_pp0_stage0_subdone;
reg    ap_condition_pp0_exit_iter0_state3;
reg    ap_enable_reg_pp0_iter1;
reg   [19:0] ap_phi_mux_empty_8_phi_fu_81_p4;
wire   [19:0] select_ln16_fu_93_p3;
wire   [19:0] ap_phi_reg_pp0_iter0_empty_8_reg_78;
wire   [19:0] add_ln696_fu_107_p2;
wire    ap_CS_fsm_state1;
wire    ap_block_pp0_stage0_01001;
wire    ap_block_pp0_stage0;
wire    ap_CS_fsm_state5;
reg   [3:0] ap_NS_fsm;
reg    ap_idle_pp0;
wire    ap_enable_pp0;

// power-on initialization
initial begin
#0 rst_out_1_data_reg = 1'd0;
#0 rst_out_1_vld_reg = 1'b0;
#0 ap_CS_fsm = 4'd1;
#0 ap_enable_reg_pp0_iter0 = 1'b0;
#0 ap_enable_reg_pp0_iter1 = 1'b0;
end

always @ (posedge ap_clk) begin
    if (ap_rst == 1'b1) begin
        ap_CS_fsm <= ap_ST_fsm_state1;
    end else begin
        ap_CS_fsm <= ap_NS_fsm;
    end
end

always @ (posedge ap_clk) begin
    if (ap_rst == 1'b1) begin
        ap_enable_reg_pp0_iter0 <= 1'b0;
    end else begin
        if (((1'b0 == ap_block_pp0_stage0_subdone) & (1'b1 == ap_condition_pp0_exit_iter0_state3) & (1'b1 == ap_CS_fsm_pp0_stage0))) begin
            ap_enable_reg_pp0_iter0 <= 1'b0;
        end else if ((1'b1 == ap_CS_fsm_state2)) begin
            ap_enable_reg_pp0_iter0 <= 1'b1;
        end
    end
end

always @ (posedge ap_clk) begin
    if (ap_rst == 1'b1) begin
        ap_enable_reg_pp0_iter1 <= 1'b0;
    end else begin
        if (((1'b0 == ap_block_pp0_stage0_subdone) & (1'b1 == ap_condition_pp0_exit_iter0_state3))) begin
            ap_enable_reg_pp0_iter1 <= (1'b1 ^ ap_condition_pp0_exit_iter0_state3);
        end else if ((1'b0 == ap_block_pp0_stage0_subdone)) begin
            ap_enable_reg_pp0_iter1 <= ap_enable_reg_pp0_iter0;
        end else if ((1'b1 == ap_CS_fsm_state2)) begin
            ap_enable_reg_pp0_iter1 <= 1'b0;
        end
    end
end

always @ (posedge ap_clk) begin
    if ((1'b1 == ap_CS_fsm_state2)) begin
        empty_reg_67 <= 20'd0;
    end else if (((ap_enable_reg_pp0_iter0 == 1'b1) & (1'b0 == ap_block_pp0_stage0_11001) & (icmp_ln882_fu_87_p2 == 1'd0) & (1'b1 == ap_CS_fsm_pp0_stage0))) begin
        empty_reg_67 <= add_ln695_fu_114_p2;
    end
end

always @ (posedge ap_clk) begin
    if ((((1'b1 == 1'b1) & (rst_out_1_vld_in == 1'b1) & (rst_out_1_vld_reg == 1'b1)) | ((rst_out_1_vld_in == 1'b1) & (rst_out_1_vld_reg == 1'b0)))) begin
        rst_out_1_data_reg <= rst_out_1_data_in;
    end
end

always @ (*) begin
    if ((icmp_ln882_fu_87_p2 == 1'd1)) begin
        ap_condition_pp0_exit_iter0_state3 = 1'b1;
    end else begin
        ap_condition_pp0_exit_iter0_state3 = 1'b0;
    end
end

always @ (*) begin
    if (((ap_enable_reg_pp0_iter1 == 1'b0) & (ap_enable_reg_pp0_iter0 == 1'b0))) begin
        ap_idle_pp0 = 1'b1;
    end else begin
        ap_idle_pp0 = 1'b0;
    end
end

always @ (*) begin
    if ((icmp_ln882_fu_87_p2 == 1'd0)) begin
        if ((icmp_ln890_fu_101_p2 == 1'd1)) begin
            ap_phi_mux_empty_8_phi_fu_81_p4 = add_ln696_fu_107_p2;
        end else if ((icmp_ln890_fu_101_p2 == 1'd0)) begin
            ap_phi_mux_empty_8_phi_fu_81_p4 = select_ln16_fu_93_p3;
        end else begin
            ap_phi_mux_empty_8_phi_fu_81_p4 = ap_phi_reg_pp0_iter0_empty_8_reg_78;
        end
    end else begin
        ap_phi_mux_empty_8_phi_fu_81_p4 = ap_phi_reg_pp0_iter0_empty_8_reg_78;
    end
end

always @ (*) begin
    if (((rst_out_1_vld_reg == 1'b0) | ((1'b1 == 1'b1) & (rst_out_1_vld_reg == 1'b1)))) begin
        rst_out_1_ack_in = 1'b1;
    end else begin
        rst_out_1_ack_in = 1'b0;
    end
end

always @ (*) begin
    if (((ap_enable_reg_pp0_iter0 == 1'b1) & (icmp_ln890_fu_101_p2 == 1'd1) & (1'b0 == ap_block_pp0_stage0_01001) & (icmp_ln882_fu_87_p2 == 1'd0) & (1'b1 == ap_CS_fsm_pp0_stage0))) begin
        rst_out_1_data_in = 1'd1;
    end else if (((1'b1 == ap_CS_fsm_state1) | ((ap_enable_reg_pp0_iter0 == 1'b1) & (icmp_ln890_fu_101_p2 == 1'd0) & (1'b0 == ap_block_pp0_stage0_01001) & (icmp_ln882_fu_87_p2 == 1'd0) & (1'b1 == ap_CS_fsm_pp0_stage0)))) begin
        rst_out_1_data_in = 1'd0;
    end else begin
        rst_out_1_data_in = 'bx;
    end
end

always @ (*) begin
    if (((1'b1 == ap_CS_fsm_state1) | ((ap_enable_reg_pp0_iter0 == 1'b1) & (icmp_ln890_fu_101_p2 == 1'd1) & (1'b0 == ap_block_pp0_stage0_11001) & (icmp_ln882_fu_87_p2 == 1'd0) & (1'b1 == ap_CS_fsm_pp0_stage0)) | ((ap_enable_reg_pp0_iter0 == 1'b1) & (icmp_ln890_fu_101_p2 == 1'd0) & (1'b0 == ap_block_pp0_stage0_11001) & (icmp_ln882_fu_87_p2 == 1'd0) & (1'b1 == ap_CS_fsm_pp0_stage0)))) begin
        rst_out_1_vld_in = 1'b1;
    end else begin
        rst_out_1_vld_in = 1'b0;
    end
end

always @ (*) begin
    case (ap_CS_fsm)
        ap_ST_fsm_state1 : begin
            ap_NS_fsm = ap_ST_fsm_state2;
        end
        ap_ST_fsm_state2 : begin
            ap_NS_fsm = ap_ST_fsm_pp0_stage0;
        end
        ap_ST_fsm_pp0_stage0 : begin
            if (~((ap_enable_reg_pp0_iter0 == 1'b1) & (1'b0 == ap_block_pp0_stage0_subdone) & (icmp_ln882_fu_87_p2 == 1'd1))) begin
                ap_NS_fsm = ap_ST_fsm_pp0_stage0;
            end else if (((ap_enable_reg_pp0_iter0 == 1'b1) & (1'b0 == ap_block_pp0_stage0_subdone) & (icmp_ln882_fu_87_p2 == 1'd1))) begin
                ap_NS_fsm = ap_ST_fsm_state5;
            end else begin
                ap_NS_fsm = ap_ST_fsm_pp0_stage0;
            end
        end
        ap_ST_fsm_state5 : begin
            if (((1'b1 == ap_CS_fsm_state5) & (rst_out_1_ack_in == 1'b1))) begin
                ap_NS_fsm = ap_ST_fsm_state1;
            end else begin
                ap_NS_fsm = ap_ST_fsm_state5;
            end
        end
        default : begin
            ap_NS_fsm = 'bx;
        end
    endcase
end

assign add_ln695_fu_114_p2 = (ap_phi_mux_empty_8_phi_fu_81_p4 + 20'd1);

assign add_ln696_fu_107_p2 = ($signed(select_ln16_fu_93_p3) + $signed(20'd1048575));

assign ap_CS_fsm_pp0_stage0 = ap_CS_fsm[32'd2];

assign ap_CS_fsm_state1 = ap_CS_fsm[32'd0];

assign ap_CS_fsm_state2 = ap_CS_fsm[32'd1];

assign ap_CS_fsm_state5 = ap_CS_fsm[32'd3];

assign ap_block_pp0_stage0 = ~(1'b1 == 1'b1);

assign ap_block_pp0_stage0_01001 = ~(1'b1 == 1'b1);

assign ap_block_pp0_stage0_11001 = ~(1'b1 == 1'b1);

assign ap_block_pp0_stage0_subdone = ~(1'b1 == 1'b1);

assign ap_block_state3_pp0_stage0_iter0 = ~(1'b1 == 1'b1);

assign ap_block_state4_pp0_stage0_iter1 = ~(1'b1 == 1'b1);

assign ap_enable_pp0 = (ap_idle_pp0 ^ 1'b1);

assign ap_phi_reg_pp0_iter0_empty_8_reg_78 = 'bx;

assign ap_return = 32'd0;

assign icmp_ln882_fu_87_p2 = ((empty_reg_67 == 20'd1048575) ? 1'b1 : 1'b0);

assign icmp_ln890_fu_101_p2 = ((select_ln16_fu_93_p3 > 20'd524288) ? 1'b1 : 1'b0);

assign rst_out = rst_out_1_data_reg;

assign select_ln16_fu_93_p3 = ((rst_in[0:0] === 1'b1) ? 20'd0 : empty_reg_67);

endmodule //WDTimer


  1. 2020年12月25日 04:13 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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