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

FPGAの差動入力でAD変換

FPGA zynq

はじめに

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