Alveo U250からホストに文字列転送する話

  • Mar 04, 2023
post-thumb

Virtual I/OをUARTの代わりに

なんかAlveoU250でUARTが使えない

うーん.なぜかAlveo U250でUARTが使えない.

ただ文字を表示したいだけだし,UARTモジュールを実装してみたんだけど,動かなかった. なんでや!と思ってXDCファイルを更新したり,ドライバ再インスコしたり,再起動したり,色々したんだけど... 困るのよねえ.何かtipsあればTwitter(@tnk_make)で教えてください...

代わりにVirtual I/Oを使う

マジで嫌々,仕方無〜〜〜くUARTの代わりにVirtual IOで文字列の確認できないかなあと考えた. こんなクソ発想せずにUARTしたいんだが,,,.

Virtual I/O ってなあに

XilinxのVirtual Input/Output (VIO)についてのドキュメントは こちら(https://docs.xilinx.com/v/u/en-US/pg159-vio)

フレームレートに関して,1msとか指定できるけど,なんかよくエラー吐くので使わないようにしよう. まあ100ms程度であれば問題ないかな.うーん,10Hzか.なんだこれ.


動作確認

ひとまずこんな予定

  1. Arty S7で動かしてみる
  2. Alveo U250で動かしてみる

まずは個人の持っているArty S7で正しく動くことを確認する.

その上でもしAlveoU250でうまく動かなければ,多分Clocking Wizardの使い方を間違えている.

AlveoU250で動いたら,まあOK.



設計

設計はこんな感じ.AlveoではこのCLK100MHzClocking Wizardを接続しようかな.


ディレクトリ構成

.
├── consts
│   ├── Arty-S7-50-Master.xdc
│   └── alveo-u250-xdc.xdc
├── rtls
│   ├── clock_gen_for_vio.sv
│   ├── dammy_rtl.sv
│   ├── top_usb_uart_tx.sv
│   ├── top_usb_uart_tx_with_clkwiz.sv
│   └── tx_fifo.sv
└── tcl
    ├── build.tcl
    ├── define.tcl
    ├── show_vio.tcl
    └── sources
        ├── make_clocking_wizard_design.tcl
        └── make_vio_design.tcl

RTL

./rtlsの中身をそれぞれ解説しますわね.

Clocking Wizardなしverのトップモジュール (top_usb_uart_tx.sv)

Artyならこれを使う.

信号名 bit幅[bit] 役割
CLK100MHZ 1 100MHzのクロック信号
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
module top_usb_uart_tx  (
    input  logic        CLK100MHZ
);

logic rst_n;
logic CLK10HZ;
logic [31:0] cnt;
logic tx_en_rtl;
logic [ 7:0] tx_rtl;
logic tx_en_vio;
logic [ 7:0] tx_vio;

design_1 #()vio(
    .clk_i(CLK100MHZ),
    .rst_n(rst_n),
    .tx_en(tx_en_vio),
    .tx(tx_vio)
);

tx_fifo tx_q(
    .rst_n(rst_n),
    .clk_10hz_i(CLK10HZ),
    .clk_i(CLK100MHZ),
    .tx_en_i(tx_en_rtl),
    .tx_i(tx_rtl),
    .tx_en_o(tx_en_vio),
    .tx_o(tx_vio)
);

clock_gen_for_vio clk_gen(
    .rst_n(rst_n),
    .clk_i(CLK100MHZ),
    .clk_10hz_o(CLK10HZ)
);

dammy_rtl dammy(
    .rst_n(rst_n),
    .clk_i(CLK100MHZ),
    .tx_en_rtl(tx_en_rtl),
    .tx_rtl(tx_rtl)
);

endmodule

Clocking Wizardありverのトップモジュール (top_usb_uart_tx_with_clkwiz.sv)

Clocking Wizardを使うver.Alveoで使う.

信号名 bit幅[bit] 役割
SYSCLK0_300_P 1 作動クロック信号のP
SYSCLK0_300_N 1 作動クロック信号のN
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module top_usb_uart_tx_with_clkwiz  (
    input  logic        SYSCLK0_300_P,
    input  logic        SYSCLK0_300_N
);

/* ------追加----- */
logic CLK100MHZ;
design_2 #()clkwiz(
    .SYSCLK0_300_P(SYSCLK0_300_P),
    .SYSCLK0_300_N(SYSCLK0_300_N),
    .CLK100MHZ(CLK100MHZ),
    .rst_n(rst_n)
);
/* ------------- */

logic rst_n;
logic CLK10HZ;
logic [31:0] cnt;
logic tx_en_rtl;
logic [ 7:0] tx_rtl;
logic tx_en_vio;
logic [ 7:0] tx_vio;

design_1 #()vio(
    .clk_i(CLK100MHZ),
    .rst_n(rst_n),
    .tx_en(tx_en_vio),
    .tx(tx_vio)
);

tx_fifo tx_q(
    .rst_n(rst_n),
    .clk_10hz_i(CLK10HZ),
    .clk_i(CLK100MHZ),
    .tx_en_i(tx_en_rtl),
    .tx_i(tx_rtl),
    .tx_en_o(tx_en_vio),
    .tx_o(tx_vio)
);

clock_gen_for_vio clk_gen(
    .rst_n(rst_n),
    .clk_i(CLK100MHZ),
    .clk_10hz_o(CLK10HZ)
);

dammy_rtl dammy(
    .rst_n(rst_n),
    .clk_i(CLK100MHZ),
    .tx_en_rtl(tx_en_rtl),
    .tx_rtl(tx_rtl)
);

endmodule

適当なモジュール (dammy_rtl.sv)

とりあえずRTLの出力はこんな感じ. まあtx_rtltx_en_rtlも出力できりゃあなんでもいいんですよねえ.

信号名 bit幅[bit] 役割
rst_n 1 リセット信号.不論理
clk_i 1 クロック信号
tx_en_rtl 1 tx_dataが有効なら1
tx_data_rtl 8 出力したい文字1個

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module dammy_rtl  (
    input   logic           rst_n,
    input   logic           clk_i,
    output  logic           tx_en_rtl,
    output  logic   [ 7:0]  tx_rtl
);

logic [31:0] cnt;

always_ff @(posedge clk_i) begin
    if(!rst_n)begin
        cnt         <= 32'b0;
        tx_en_rtl   <= 1'b0;
        tx_rtl      <= 8'h72;
    end else begin
        cnt <= (cnt!=32'hFFFFFFFF)?cnt+32'b1:32'b0;
        if (cnt>=32'd100000 && cnt<=32'd100020 ) begin
            tx_en_rtl   <= cnt[0];
            tx_rtl      <= 8'h41 + {7'h0,cnt[0]};
        end else begin
            tx_en_rtl   <= 1'b0; 
            tx_rtl      <= 8'h43;
        end
    end
end

endmodule
Virtual I/Oの速度に合わせたクロック生成モジュール (clock_gen_for_vio.sv)

Virtual I/Oは10Hzで値を更新させるので,その速度に合わせたクロック信号を生成するモジュール. ちなみにArtyもAlveoもベースとなるクロック動作周波数は100MHzとしましたわ.

信号名 bit幅[bit] 役割
rst_n 1 リセット信号.不論理
clk_i 1 ベースとなるクロック信号(100MHz)
clk_10hz_o 1 10Hzのクロック信号
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module clock_gen_for_vio  #(
    parameter MASTER_CLK_HZ = 100000000
)(
    input  logic        rst_n,
    input  logic        clk_i,
    output logic        clk_10hz_o
);

localparam CLK_CNT_MAX = (MASTER_CLK_HZ/10)-1;

logic   [ 29: 0] cnt;

always_ff @(posedge clk_i) begin
    if (!rst_n)begin
        cnt         <= 30'b0;
        clk_10hz_o  <= 1'b0;
    end else begin
        if(cnt==CLK_CNT_MAX)begin
            cnt         <= 30'b0;
            clk_10hz_o  <= ~clk_10hz_o;
        end else begin
            cnt         <= cnt + 30'b1;
        end
    end
end

endmodule
Virtual I/Oの出力データを貯めるFIFO (tx_fifo.sv)

入力は100MHzのクロック信号に合わせて入るものとする. 出力はVIOモジュールに合わせて10Hzです.

信号名 bit幅[bit] 役割
rst_n 1 リセット信号.不論理
clk_i 1 ベースとなるクロック信号(100MHz)
clk_10hz_i 1 10Hzのクロック信号
tx_en_i 1 ダミーのモジュールから入力されたデータが有効か
tx_i 8 ダミーのモジュールから入力されたデータ
tx_en_o 1 出力するデータが有効か
tx_o 8 出力するデータ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module tx_fifo  (
    input   logic           rst_n,
    input   logic           clk_i,
    input   logic           clk_10hz_i,
    input   logic           tx_en_i,
    input   logic   [ 7:0]  tx_i,
    output  logic           tx_en_o,
    output  logic   [ 7:0]  tx_o
);

logic   [ 7: 0] tx_ring_queue   [ 1023:  0];
logic   [ 9: 0] queue_head;
logic   [ 9: 0] queue_tail;

logic   empty;
assign  empty   = (queue_head == queue_tail)?1'b1:1'b0;

logic   full;
assign  full = ((queue_tail==10'd0) && ( queue_head== 10'd1023) )?1'b1 :((queue_tail)==(queue_head+10'd1))?1'b1:1'b0;

logic   clk_10hz_i_old;
logic   posedge_clk_10hz;
assign  posedge_clk_10hz = ((clk_10hz_i==1'b1) && (clk_10hz_i_old==1'b0))?1'b1:1'b0;

always_ff @(posedge clk_i) begin
    if(!rst_n)begin
        queue_head <= 10'b0;
    end else if(!full)begin
        if(tx_en_i)begin
            tx_ring_queue[queue_head]  <= tx_i;
            queue_head                 <= (queue_head==10'd1023)?10'b0:(queue_head+10'b1);
        end
    end
end

always_ff @(posedge clk_i) begin
    if(!rst_n)begin
        queue_tail  <= 10'b0;
        tx_en_o     <= 1'b0;
        tx_o        <= 8'b0;
    end else if (posedge_clk_10hz) begin
        if (empty) begin
            tx_en_o     <= 1'b0;
            tx_o        <= 8'b0;
        end else begin
            tx_en_o     <= 1'b1;
            tx_o        <= tx_ring_queue[queue_tail];
            queue_tail  <= (queue_tail==10'd1023)?10'b0:(queue_tail+10'b1);
        end
    end
    clk_10hz_i_old <= clk_10hz_i;
end

endmodule


Bitstream生成用のTCLファイル

Bitstream生成まで行うTCLファイル(build.tcl)

デザインの作成からbitstream生成まで行うTCLファイルbuild.tclはこんな感じ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
set projectPath [file normalize [file dirname [file dirname [info script]]]]
cd $projectPath

# -----defineファイル追加-------------
source "$projectPath/tcl/define.tcl"  ; # defineファイルを追加

# -----ソースファイル追加-------------
set sourceDir     "$projectPath/tcl/sources"                  ; # ソースファイルの置き場所
set source_files  [glob -directory $sourceDir -type f "*.tcl"]; # ソースのTCLファイル追加
foreach f $source_files {
  source $f
}

# -----元のプロジェクトファイル削除-------------
if {[file exists $outputDir] == 1} {  ; # プロジェクトファイルがあれば
  file delete -force $outputDir       ; # プロジェクトファイルを削除
}

# -----プロジェクトの作成-------------
create_project    $projectName $outputDir -part $partName ; # プロジェクトファイル作成
update_ip_catalog ;   # IPカタログ更新

# -----vio作成-------------
set vio_module_name "design_1"
set vio_ip_link     "xilinx.com:ip:vio:3.0"
make_vio_module     $vio_module_name  $vio_ip_link 100000000  ; # VIOモジュール作成

# -----clkwiz作成-------------
set clkwiz_module_name  "design_2"
set clkwiz_ip_link      "xilinx.com:ip:clk_wiz:6.0"
if { $need_clkwiz == 1 } {                                      ; # Clocking Wizardが必要なら
  make_clkwiz_module      $clkwiz_module_name  $clkwiz_ip_link  ; # Clocking Wizardを作成
}
# -----RTLファイルの追加-------------
add_files $rtl_directory                        ; # RTLファイル追加
add_files -fileset constrs_1 $constraint_file   ; # xdcファイル追加

# -----トップモジュールの設定-------------
if { $need_clkwiz == 1 } {                                          ; # Clocking Wizardを使うなら
  set_property top "top_usb_uart_tx_with_clkwiz" [current_fileset]  ; # Clocking Wizardありverのトップモジュールを指定
} else {                                                            ; # そうでないなら
  set_property top "top_usb_uart_tx" [current_fileset]              ; # Clocking Wizardなしverのトップモジュールを指定
}

# -----ファイルセットの更新-------------
update_compile_order -fileset sources_1 ; # 更新

# -----Run Synthesis-------------
launch_runs synth_1 -jobs $howManyThread  ; # Synthesis実行開始
wait_on_run synth_1                       ; # Synthesis実行終了待ち

# -----Run Implementation-------------
launch_runs impl_1  -jobs $howManyThread  ; # Run Implementation開始
wait_on_run impl_1                        ; # Run Implementation終了待ち

# -----Generate bitstream-------------
launch_runs impl_1 -to_step write_bitstream -jobs $howManyThread  ; # bitstream生成開始
wait_on_run impl_1                                                ; # bitstream終了待ち

# -----プロジェクトを閉じる-------------
close_project

色々定義したTCLファイル(define.tcl)

ここを変えればある程度?ボード変えてもいい??本当か???(他のボードで試してないからわからん)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# -----変数-------------
set howManyThread   2                       ;# 実行時のスレッド数
set outputDir       "$projectPath/output"   ;# プロジェクトの出力先
set projectName     "vio_show_project"      ;# プロジェクト名
set rtl_directory   "$projectPath/rtls"     ;# RTLファイルのディレクトリ
# set constraint_file "$projectPath/consts/Arty-S7-50-Master.xdc" ;   # xdcファイルの設定/
set constraint_file "$projectPath/consts/alveo-u250-xdc.xdc"    ;   # xdcファイルの設定/
# set partName        "xc7s50csga324-1"       ;# パーツ名
set partName        "xcu250-figd2104-2L-e"  ;# パーツ名
set hw_device_name  "xc7s50_0"              ;# デバイス名
set logfile         "./output/vio.log"      ;# ログファイルの保存先
set need_clkwiz     1                       ;# Clocking Wizardが必要なら1に
VIOモジュール作成用のTCLファイル(make_vio_design.tcl)

これでできるモジュールの入出力は次の通り.

信号名 bit幅[bit] 役割
rst_n 1 (出力)リセット信号.不論理
clk_i 1 (入力)ベースとなるクロック信号(100MHz)
tx_en_i 1 (入力)ダミーのモジュールから入力されたデータが有効か
tx_i 8 (入力)ダミーのモジュールから入力されたデータ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
proc make_vio_module { { vio_module_name } { vio_ip_link } { clock_speed_hz } } {
    create_bd_design $vio_module_name
    startgroup
    create_bd_cell -type ip -vlnv $vio_ip_link vio_0
    endgroup
    set_property -dict [list \
        CONFIG.C_NUM_PROBE_IN {2} \
        CONFIG.C_PROBE_IN1_WIDTH {8} \
    ] [get_bd_cells vio_0]
    create_bd_port -dir I   -type clk   -freq_hz $clock_speed_hz    clk_i
    create_bd_port -dir O                   rst_n
    create_bd_port -dir I                   tx_en
    create_bd_port -dir I   -from 7 -to 0   tx
    connect_bd_net [get_bd_ports clk_i] [get_bd_pins vio_0/clk]
    connect_bd_net [get_bd_ports tx_en] [get_bd_pins vio_0/probe_in0]
    connect_bd_net [get_bd_ports tx]    [get_bd_pins vio_0/probe_in1]
    connect_bd_net [get_bd_ports rst_n] [get_bd_pins vio_0/probe_out0]
    save_bd_design
}
ClockingWizardモジュール作成用のTCLファイル(make_clocking_wizard_design.tcl)

これでできるモジュールの入出力は次の通り.

信号名 bit幅[bit] 役割
SYSCLK0_300_P 1 (入力)作動クロック信号のP
SYSCLK0_300_N 1 (入力)作動クロック信号のN
rst_n 1 (入力)リセット信号.不論理
CLK100MHZ 1 (出力)ベースとなるクロック信号(100MHz)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
proc make_clkwiz_module { { clkwiz_module_name } { clkwiz_ip_link }} {
    create_bd_design $clkwiz_module_name
    create_bd_cell -type ip -vlnv $clkwiz_ip_link clk_wiz_0
    set_property -dict [list CONFIG.PRIMITIVE {MMCM} CONFIG.CLK_IN1_BOARD_INTERFACE {default_300mhz_clk0} CONFIG.USE_LOCKED {false} CONFIG.USE_RESET {false} CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} CONFIG.CLKIN1_JITTER_PS {33.330000000000005} CONFIG.CLKOUT1_DRIVES {Buffer} CONFIG.CLKOUT2_DRIVES {Buffer} CONFIG.CLKOUT3_DRIVES {Buffer} CONFIG.CLKOUT4_DRIVES {Buffer} CONFIG.CLKOUT5_DRIVES {Buffer} CONFIG.CLKOUT6_DRIVES {Buffer} CONFIG.CLKOUT7_DRIVES {Buffer} CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} CONFIG.MMCM_BANDWIDTH {OPTIMIZED} CONFIG.MMCM_CLKFBOUT_MULT_F {4.000} CONFIG.MMCM_CLKIN1_PERIOD {3.333} CONFIG.MMCM_CLKIN2_PERIOD {10.0} CONFIG.MMCM_COMPENSATION {AUTO} CONFIG.MMCM_CLKOUT0_DIVIDE_F {12.000} CONFIG.CLKOUT1_JITTER {101.475} CONFIG.CLKOUT1_PHASE_ERROR {77.836}] [get_bd_cells clk_wiz_0]
    set_property -dict [list \
        CONFIG.CLKOUT1_JITTER {101.475} \
        CONFIG.CLKOUT1_PHASE_ERROR {77.836} \
        CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {100} \
        CONFIG.MMCM_CLKFBOUT_MULT_F {4.000} \
        CONFIG.MMCM_CLKOUT0_DIVIDE_F {12.000} \
        CONFIG.MMCM_DIVCLK_DIVIDE {1} \
    ] [get_bd_cells clk_wiz_0]
    # -----入力部分の接続--------------------------------
    create_bd_port -dir I SYSCLK0_300_N
    create_bd_port -dir I SYSCLK0_300_P
    connect_bd_net [get_bd_ports SYSCLK0_300_N] [get_bd_pins clk_wiz_0/clk_in1_n]
    connect_bd_net [get_bd_ports SYSCLK0_300_P] [get_bd_pins clk_wiz_0/clk_in1_p]
    # -----出力部分の接続--------------------------------
    create_bd_port -dir O CLK100MHZ
    connect_bd_net [get_bd_ports CLK100MHZ] [get_bd_pins clk_wiz_0/clk_out1]
    # -----保存--------------------------------
    save_bd_design
}

FPGA上のVIO(出力)を表示させるTCLファイル

やりたいこと

作成したbitstreamファイルをFPGAに書き込んだのち,行いたいのは以下の2つ

  • 最初にrst_nを1→0→1とリセットをかけたい
  • ターミナルやファイルにtx_dataを表示したい
実際のコードshow_vio.tcl
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
set projectPath [file normalize [file dirname [file dirname [info script]]]]
cd $projectPath

#############################################
# defineファイル追加
#############################################
source "$projectPath/tcl/define.tcl"

#############################################
# 保存先ファイルの初期化
#############################################
set     log [open $logfile w]   ;#① 保存先ファイルをopen
puts    -nonewline  $log ""     ;#② 中身を削除
close   $log                    ;#③ 保存先ファイルをclose

#############################################
# ボーレートの設定
# $delay_time[ms]ごとに計測
#############################################
set_property CORE_REFRESH_RATE_MS 100 [get_hw_vios [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]

#############################################
# リセット信号(vio_0_probe_out0)の出力
#   1→0→1 となる
#############################################
# 1を出力
set_property OUTPUT_VALUE 1 [get_hw_probes vio/vio_0_probe_out0 -of_objects [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]
commit_hw_vio [get_hw_probes {vio/vio_0_probe_out0} -of_objects [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]
after 1000
# 0を出力
set_property OUTPUT_VALUE 0 [get_hw_probes vio/vio_0_probe_out0 -of_objects [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]
commit_hw_vio [get_hw_probes {vio/vio_0_probe_out0} -of_objects [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]
after 1000
# 1を出力
set_property OUTPUT_VALUE 1 [get_hw_probes vio/vio_0_probe_out0 -of_objects [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]
commit_hw_vio [get_hw_probes {vio/vio_0_probe_out0} -of_objects [get_hw_vios -of_objects [get_hw_devices $hw_device_name] -filter {CELL_NAME=~"vio/vio_0"}]]

#############################################
# 中断するまで表示を繰り返す
#   Canselを押して中断
#############################################
while {1} {
    set tx_value_num    [get_property   INPUT_VALUE [get_hw_probes vio/tx_1] ]      ;#RTLから受け取った表示したい文字データ(数値)
    set tx_value        [format         %c          $tx_value_num]                  ;#数値を文字に変換
    set tx_en_value     [get_property   INPUT_VALUE [get_hw_probes vio/tx_en_1] ]   ;#RTLから受け取った表示したい文字データのenable
    if {$tx_en_value == 1} then {      ;# 表示したい文字があれば
        puts -nonewline $tx_value       ;# TCLコンソールに表示
        set log [open $logfile a]       ;# 保存先ファイルをopen
        puts -nonewline $log $tx_value  ;# 保存先ファイルに出力
        close $log                      ;# 保存先ファイルをclose
    }
    after 100   ;# 100[ms]停止
}

結果

〜bitstream生成

ターミナルで実行しましょ.

1
vivado -mode batch -source tcl/build.tcl

実行後lsするとoutputってディレクトリができますわよ.

vivadoを立ち上げて書き込み

Open Hardware ManagerからOpen TargetAuto Connectして,Program Deviceで書き込み.

書き込んだFPGAと通信

Vivadoのtclコンソールで実行しましょ.

1
source tcl/show_vio.tcl

その結果.Vivadoはこんな画面になる. 下の方にBDFHJLNPRTと表示されてればOK Canselを押せば停止できますわ.

output/vio.logの中身はこんな感じになる.


まとめ

AlveoU250でシリアル通信ができなかった.しかしまあVirtual I/Oを使って10Hzの速度で出力を文字列で確認できるようにした.

今後このモジュールを使わなくて済むことを祈っている.