PYNQ > Verilog-HDL > UART > loopbackの実装 (rx -> tx)

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
PYNQ v2.5 Image
Vivado v2019.1 (64-bit)
Akafugu FTDIアダプター
NonSoft様 RS232Cテストツール
```

### 概要

- Verilog-HDLにてrx受信したものをtx送信する実装
- Akafugu FTDIアダプタでPCと接続
- RS232Cテストツールにてエコーバックを確認した

### Block Design

![コメント 2020-08-14 110246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/988038a2-1ccc-d640-fffc-0d7818db788e.png)

UARTのrxに対して、Make Externalしたrx_0を接続。
同時に、自作のUartLoopBack_v1_0のrxに接続した。

### Address Editor

UartLiteのアドレスはデフォルトのまま。

![コメント 2020-08-14 112142.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/c325601b-9720-e479-602b-a0bda9ca32f1.png)

### UartLoopBack_v1_0 (Verilog-HDL)

UartLoopBack_v1_0はrxしたものをtxするだけの実装。

```verilog:UartLoopBack_v1_0.v
`timescale 1ns / 1ps

module UartLoopBack(
    input rx,
    output tx,
    input clk
    );
    
    reg buffer;  // rxをtxに渡すためのバッファ
    always @(posedge clk)
    begin
        buffer <= rx;
    end
    
    assign tx = buffer;
endmodule
```

### 制約ファイル

```txt:XDC 
set_property PACKAGE_PIN Y18 [get_ports rx_0]
set_property IOSTANDARD LVCMOS33 [get_ports rx_0]
set_property IOSTANDARD LVCMOS33 [get_ports tx_1]
set_property PACKAGE_PIN Y19 [get_ports tx_1]

set_property IOSTANDARD LVCMOS33 [get_ports reset_rtl]
set_property PACKAGE_PIN W6 [get_ports reset_rtl]
```

reset_rtlの設定はしっかりとは考えてない。


### FTDIアダプタ (3.3V使用)

https://www.akafugu.jp/ja/posts/products/ftdi-adapter/

今回は3.3Vとして使用。
上記の制約ファイルでもLVCMOS33を設定している。

COM3としてパソコンでは認識した。

### 接続

PMOD
https://pynq.readthedocs.io/en/v2.4/pynq_libraries/pmod.html

![pmod_pins.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/6fcc3a9d-d18f-ff82-789e-f58b64ee82a9.png)


- PYNQ <-> FTDIアダプター
    - PMODA 0ピン(RX) <-> FTDI (TX)
    - PMODA 1ピン(TX) <-> FTDI (RX)
    - PMODA (GND) <-> FTDI (GND)

ブレッドボード用のケーブル3本で接続した。

### Vivado生成ファイル

下記のファイルをPYNQの「`\\pynq\xilinx\jupyter_notebooks\base`」に配置する。
(Explorerでコピーした）。

- UARTloopback_200814.bit
- UARTloopback_200814.tcl

### Pythonスクリプト

```py
from pynq import Overlay

ol = Overlay("/home/xilinx/jupyter_notebooks/base/UARTloopback_200814.bit")
```

### 動作確認

NonSoft様の以下を使用させていただきました。
ソフト提供ありがとうございます。

- [RS232Cデバッグツール（RS232C接続を行い電文の送受信を行うテストツール） ](http://nonsoft.la.coocan.jp/Download/Rs232cTool/index.html)


下記が実行した結果。

![コメント 2020-08-14 111812.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/321eb836-7889-bf3b-8ff8-e2e8007b5e51.png)

loopbackのVerilog HDL実装が有効となり、送信した文字列がそのまま受信できている。


### 9600 bpsでない動作 :thinking:

19200bpsでも試してみた。
文字化けはない。

:thinking: 

![コメント 2020-08-14 112049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/f77bca83-cbde-13bf-884a-4f66c0fdf6c6.png)

そもそもUartLiteの初期化もしてない。

このあたりは将来もう少し理解を深めて使うことになるかな。

rxで受けたものをtxへループバックしながら、rxのコマンドをPSで解析、みたいなこと。それをするための今回のBlock Design (未検証）。

### はまった点

UartLiteのtxを別のIPに接続しようとしたが、Make Externalするとそれはできないようだ。
シリアル通信モニターのようなことをするには工夫が必要になるだろう。


### XSDK > Loopback機能

<font color=red>下記は広告などがある。見たくない人は開かないこと</font>

- [Learn Zynq(25) UART poll (poll) mode example](https://www.programmersought.com/article/9813831088/)

```c 
XUartPs_SetOperMode(Uart_Ps, XUARTPS_OPER_MODE_LOCAL_LOOP); //Local loopback mode
```

XUARTPS_OPER_MODE_LOCAL_LOOPで指定する（ローカル）ループバック機能があるとのこと。
PYNQのシステムでXSDKを使わない場合、この機能を使うLibraryが見つからなかった。


### その他、参考情報

この作業をする過程で見つけたいくつかのWebページ。

- [verilog～UART通信受信機(RX)編～](https://keymale.xyz/2019/06/05/post-381/#comment-717)
- [verilog～UART通信送信機(TX)編～](https://keymale.xyz/2019/05/20/post-324/)
    - これらを使おうとしたけれど、AXIとの接続でうまい方法を見つけられなかった
- [PYNQ で遊ぶ : 2. Verilog HDL を使ってみる](https://qiita.com/nishimuraatsushi/items/e05b7185de463c0b006a)
    - Verilog-HDLの実装をBlock Designに追加する「Add Module to Block Design」はよい情報でした
    - その他の部分もわかりやすかったです
    - 情報感謝です
- [デザイン向け（論理合成可能）SystemVerilog記述](https://qiita.com/vega77/items/398a343ae616bd618f22)
    - Vivadoでは[System VerilogがBlock Design用には使いにくい](https://qiita.com/7of9/items/ac2070227e058033b8f4)のですが、今後それを工夫してSystem Verilogを使うかもしれない
    - 上記のページはうまくまとめられています
    - 情報感謝です
- [Vivado IP Integratorでよく使う便利なIPコア16選](https://qiita.com/s_nkg/items/f2928fb727238d14f23f)
    - concat含めて、いろいろ便利そうなIPの紹介
    - 情報感謝です
- [AXI UART 16550 standalone driver](https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842080/AXI+UART+16550+standalone+driver)
    - UART Liteとは別のIP
    - Test casesにXSDKの実装例がある
- [Vivado 合成 - サポートされない SystemVerilog 構文](https://japan.xilinx.com/support/answers/55135.html)
- [uart cycle project based on Xilinx zynq-7020 Z-turn board](https://www.youtube.com/watch?v=3Rkhg3IzNGU)
    - 二つのUART LiteのIPのtx,rxを相互接続
    - これで何をするかまでは追えていない