PYNQ > PL > Verilog-HDL: スイッチ > UartLite : Slide SWをONにした時はループバックにし、OFFの場合はUartLiteを使う

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

### 関連

- [PYNQ > PL > IP: concat > 一つの入力(Slide SW)を一つの出力(RGBLED_R)につなげる](https://qiita.com/7of9/items/147a8092b5b61f8ba31f)
- [PYNQ > Verilog-HDL > UART > loopbackの実装 (rx -> tx)](https://qiita.com/7of9/items/39ebee23c2a37577b2a8)


### 概要

- SlideSWにてUartの動作を切り替える
    - A. UART Lite使用
    - B. ループバック

### Block Design

![コメント 2020-08-15 162825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/7a5e43c8-600f-2596-850c-aafdcb967e3a.png)

二つのRTLを用いてTX,RXのスイッチを行う。

### UartSwTX_V1_0 (Verilog-HDL)

assign一行でTXとRX2, RX1の切り替えを行う。

```verilog
`timescale 1ns / 1ps

module UartSwTX(
    input SW,
    input RX1,
    input RX2,
    output TX
    );
       
    assign TX = (SW==1'b1) ? RX2: RX1;
endmodule

```


### UartSwRX2_V1_0 (Verilog-HDL)

```verilog
`timescale 1ns / 1ps

module UartSwRX2(
    input SW,
    input clk,
    output TX1,
    output TX2,
    input RX
    );

    reg tx1buf;
    reg tx2buf;
    
    always @(posedge clk) begin
        if (SW == 1'b1) 
            tx1buf <= RX;
        else
            tx2buf <= RX;
    end

    assign TX1 = tx1buf;
    assign TX2 = tx2buf;

//    assign TX1 = (SW==1'b1) ? RX: 0;
//    assign TX2 = (SW==1'b1) ? 0: RX;
endmodule
```

assign一行では実装できていない。

```
assign RX = (SW==1'b1) ? TX1 : TX2;
```

上記のように実装したところ、Open Synthesized Designで下記エラーが出たため。

`
[Common 17-70] Application Exception: Failed to stitch checkpoint 'c:/pynq_proj_2020-05-23/2020-08-15_1401_SW_UartLoopback/2020-08-15_1401_SW_UartLoopback.srcs/sources_1/bd/design_1/ip/design_1_UartSwRX_0_0/design_1_UartSwRX_0_0.dcp' at cell 'design_1_i/UartSwRX_0'.
`

### 制約ファイル

```
set_property PACKAGE_PIN M20 [get_ports {SlideSW[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {SlideSW[0]}]
set_property PACKAGE_PIN Y18 [get_ports RX_0]
set_property IOSTANDARD LVCMOS18 [get_ports RX_0]
set_property PACKAGE_PIN Y19 [get_ports TX_0]
set_property IOSTANDARD LVCMOS18 [get_ports TX_0]
```

### 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本で接続した。



### Python

作成した.bitファイルと.tclファイルをZYNQ-Z1に転送した後に下記を実行する。

```py
from pynq import Overlay

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

### 結果

TeraTermにて接続。
SlideSW(SW0)をオンにしたとき、baudrateは9600bpsでも115200bpsでも無関係に入力をloopbackすることができる。
SlideSWをオフにすると応答はない (UART Liteに接続している)。

一次的なループバック機能として使えるだろうか。


### UartSWRX2_V1_0 (Verilog-HDL) > v0.2

UartSWRX2_V1_0 の実装を以下に変更してみた。
これでも動作するようだ。


```verilog
`timescale 1ns / 1ps

module UartSwRX2(
    input SW,
    input clk,
    output TX1,
    output TX2,
    input RX
    );

    assign TX1 = (SW==1'b1) ? RX: 0;
    assign TX2 = (SW==1'b1) ? 0: RX;
endmodule
```