読者です 読者をやめる 読者になる 読者になる

仮想I/O (VIO) IPコアを使ったFPGAのデバッグ

今回は、LogiCORE IP Virtual Input/Output (VIO) コアを用いてFPGAの内部信号をPCからコントロールしてみます。

どんなことができるのか

VIOを使うと、Vivadoの画面上でピンや信号線の状態を監視したり、操作したりすることができます。

ILAと同じくデバッグ用のIPコアです。
波形を見たいときはILAを使い、信号線をPCから操作したいときはVIOを使うといった感じでデバッグをしていきます。

下の画像は、LEDが接続されたピンを操作して、ZYBO上のLEDをコントロールしている様子です。

今回はVIOの使い方について書いていこうと思います。

続きを読む

ESP32で複数のシリアルポートを開く

ESP32の中に入っている3つのUARTを使ってみようと思います。

やり方

Arduinoのサンプルに「MultiSerial」と言うものがあります。
これを少し編集してシリアルポート0以外のポートを開くことができました。

// ---------- ここを追加
HardwareSerial Serial1(2); // UART2を使う
// ----------

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(115200);
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial1.write(inByte);
  }
}

ESP32のIO16とIO17(UART2のTX,RX)を直接接続することでループバックテストをすることができました。

問題点

今回はUART0と2を使用しました。
UART1は下記のサイトに書いてあるように、デフォルトでSPI Flashに設定されているようです。
ESP32 devkit esp-idf UART1 examle not working - ESP32 Forum

UART1の使い方については分かり次第ブログに書こうと思います。

Arduino TIANの概要

Arduino TIANというボードを使う機会があったので、このボードについていろいろと紹介して行こうと思います。

Arduino TIANとは

Linuxが動いて、Wi-FiBluetoothEthernetがついてるボード…らしです。
ボード価格は1個1万円程度とArduinoとしてはかなり高価なボードです。

下記ページにて詳しい説明があります。
www.arduino.org

このArduinoボードは普通のArduinoボードとは少し違っていて、Linuxが動くマイクロプロセッサと、ArduinoIDEで開発できるマイクロコントローラが載っていて、それらのチップはシリアルで通信をしているようです。
この仕様についてブロック図で見ていきましょう。

Arduino TIANの回路図(ブロック図)

Arduino TIANのホームページにあるarduino-tian-schematic.pdfを見てみると、1ページ目にこのボードのブロック図が示されています。
f:id:taltalp:20170502164755p:plain
この図を見ると2つのCPUがあるのがわかります。

MIPS 74K CPU
Linuxが動くCPUでAtheros AR9342というMIPSプロセッサです。

・SAMD21G18
ArduinoIDEで開発できるCPUで、アーキテクチャはARM Cortex-M0+です。

この2つのCPUはシリアル通信で相互に通信ができるようです。

続いて各モジュールについて詳しく見ていきましょう。

Wi-Fiモジュール
MIPS 74K CPUに接続されています。
Linux側から使うようです。
ArduinoIDEに入っているWi-Fiサンプルプロジェクトは使うことができなさそうです。

・CP2105(USB-UART)
USB-UART変換チップです。
こちらはMIPS 74K CPUとSAMD21G18Aのどちらにも繋がっています。
実際にPCにUSB接続するとCOMポートが2つ認識されます。
SAMD21G18Aとの接続ではArduino UNOのように、プログラムの書き込み、シリアル通信のコンソールとして動作します。
MIPS 74K CPUとの接続ではLinuxのコンソール画面が出てきました。こちらからOSを操作することができそうです。

・AU6350(USB2.0 HUB)
USBハブチップです。ホストはMIPS 74K CPUとなっています。
USBデバイスとして
・SAMD21G18A
Bluetoothドングル
・基板上のUSBコネクタ
・ピンヘッダのD+、D-ピン
が接続されています。
USB関連(Bluetoothも含め)はLinux側から制御するようです。
ArduinoIDE側ではUSBデバイスの開発が可能なようです。

・ピンヘッダ
Arduino互換のデザインとなっているピンヘッダはSAMD21G18Aに接続されています。
ArduinoIDEから通常の開発と同様に操作することができます。

pythonで印刷するメモ(mac・linux編)

今回はpythonから何かをプリンターで印刷したい時にどうすればいいかについてです。
自分用のメモ書きなので適当な説明です。

テキストを印刷してみる

import subprocess

# ただのテキスト
text = 'print out message'
# ファイルから印刷する場合
text = open('text.txt', 'r').read()

p = subprocess.Popen('lpr', stdin=subprocess.PIPE)
p.communicate(text)
p.stdin.close()

lprコマンドにパイプしてデータを渡すだけで印刷ができました。とても簡単です。

画像を印刷してみる

今回やりたかったのは、画像を生成してそれをファイルとして書き出さずにそのまま印刷する方法です。PILで適当な画像を生成して印刷してみます。

import subprocess
from PIL import Image
from StringIO import StringIO

buf = StringIO()

# create an image
screen = (500, 500)
bgcolor = (0x00, 0x00, 0x00)
img = Image.new('RGB', screen, bgcolor) 

# save this image to memory as a png image
img.save(buf, 'PNG')

# print out
p = subprocess.Popen('lpr', stdin=subprocess.PIPE)
p.communicate(buf.getvalue())

p.stdin.close()
buf.close()

StringIOを使ってメモリ上に画像ファイルを作って、それをlprコマンドに渡してあげることで印刷することができました。

Linuxデバイスドライバを書いてみる(2)

前回は最小構成のカーネルモジュールを作ってみました。
taltalp.hatenablog.jp

今回はデバイスを/devに登録して,ユーザー空間からデバイスドライバに触れてみたいと思います。

続きを読む

Linuxデバイスドライバを書いてみる(1)

この間、O'ReillyのLinux Device Driversを読んでみました。
忘れないうちにメモを取っておこうと思います。

最終的にはZYNQ上で動くドライバを書くことが目的ですが、今回はとりあえず仮想環境上で動くCentOS用のドライバを書いて基本的な開発方法を勉強していこうと思います。

続きを読む

FPGAの差動入力でAD変換

はじめに

XilinxのXcell Journal 94号に掲載されている「1つのザイリンクス FPGA で数百の信号をデジタル化する方法」がとてもおもしろそうだったので実際に実装してみました。
Xcell Journal 日本語版
差動入力1つと抵抗,コンデンサがそれぞれ1つだけでΔ変調器型のADCを作ることができるため1つのFPGAにたくさん搭載することができます。
今回はVivado2015.4で開発してZyboで動かしました。

仕組み

回路図は下のようになります。差動アンプの+側にアナログ信号を入力し,-側にはRCローパスフィルタの出力を接続しています。+側と-側の電位を比較してアンプから0または1の信号が出力され,そのパルスがローパスフィルタを通してフィードバックされます。そうすると+側と-側の電位差がほぼ0となるところで安定します。このとき,デジタル出力から出るパルスはディジタルローパスフィルタを通すことでAD変換をすることができます。
f:id:taltalp:20160619043945p:plain

ソースコード

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity adc is
    Port ( clk_240m: in STD_LOGIC;
	   sigin_p : in STD_LOGIC;
           sigin_n : in STD_LOGIC;
           sigout : out STD_LOGIC;
           LED : out STD_LOGIC);
end adc;

architecture Behavioral of adc is
    signal sig : std_logic;
begin

    -- 差動入力
    ibufds_1_i : IBUFDS
        generic map(
            DIFF_TERM => FALSE,
            IBUF_LOW_PWR => FALSE,
            IOSTANDARD => "DEFAULT"
        )
        port map(
            O => sig,
            I => sigin_p,
            IB => sigin_n
        );
    
    process (clk_240m) begin
        if (clk_240m'event and clk_240m='1') then
            sigout <= sig;
        end if;
    end process;

    LED <= sig;
end Behavioral;

I/O Planning

ピンアサイン時にいくつか注意点があるため各ピンについて説明をしていきます。
clk_240m : 240MHzのクロックを入れます。zyboの場合PS側からPL側に供給される100MHzまたはPL側に直接供給される125MHzの信号からClocking Wizard等を用いて240MHzを生成します。
sigin_p, sigin_n : 差動入力に対応したピンに割り当てる必要があります。またI/O StdはTMDS_33に設定しました。
sigout : ここから出た信号はRCローパスフィルタに繋がります。LVCMOS33に設定し,Drive Strengthを16に設定しました。 Xcellの内容には24に設定したと書かれていますが,zynq-7010では16が最大なようです。これをオーバーしないように外付けの抵抗の値を決める必要があります。また,Slew TypeはFastにOff-Chip TerminationはNONEに設定しました。
LED : どこでもいいのですが,今回はとりあえずLEDにデジタル信号を入れてみました。

回路

上に示す回路図のRとCは下記のように設定しました。
R = 10kΩ
C = 33pF
3.3Vの電圧をRCに入力するときに16mAの電流値を超えないように設定しています。周波数特性は特に気にせず適当に決めています。

実験

アナログ入力に可変抵抗器で0~3.3Vまでの信号を入力してLEDの光り方をみてみました。
電圧が低いと暗くなり,電圧が高くなると明るくなります。原理はPWM調光と同じような感じです。(PDM信号)

まとめ

FPGAを使ってADCがとても簡単に、しかも大量に実装することができます。デジタルローパスフィルタを入れて数値に変換すればマルチチャンネルな簡易オシロスコープなんかも作ることができそうです。プリミティブを使ってアナログフロントエンドを作るというのはとてもおもしろいですね。