« 2020年10月 | トップページ | 2020年12月 »

2020.11.25

HDMIの読み出しが安定しないのは・・・

先日から開発しているHDMI入出力回路で1080pの入力が安定してできないのは、やはり基板かFPGAのせいでしょう。

FPGAのデザインとしては内部のクロックリソースを正しくつないだり、最新のVivadoで当該部分のWarningを出さずに論理合成できるようにしたり、CLOCK DEDICATED ROUTEが出ないようにしたので、これ以上ないくらい完璧です。

様々なHDMIソースを取り換えたり、フィルタをON/OFFして実験してみると、やはり、特定のロットでPixel Clockが148.5MHzの場合に安定しなくなります。基板の作りで変わるものなのかなぁ

 

| | コメント (0)

2020.11.24

HDMI 2入力、1出力回路

Kintex-7で、DDR3メモリを介したHDMI 2入力、HDMI 1出力+USB3.0な回路が出来ました。

やりたいことは下の図のようなシンプルなことなのですが、

Hdmi_mixer

Vivado Block Designはぐっちゃーという感じになりました。

Circuit

そもそも真ん中にあるFX3というブロックに大量の信号が出入りしているのが悪いのですが、これは、EZ-USB FX3をカプセル化したブロックで、USB 3.0で高速転送できるだけでなく、HDMIデコーダのステータスなどを読みだせるようにしています。

各種ステータスやコントロール信号が多いからこんなにぐちゃぐちゃしているのですね。綺麗にするにはInterfaceを定義するしかありません。

昨日作ったフィルタにはHとVのカウントを数える機能があるので、その数えたカウント数をUSBで読み出すと、画面の解像度もわかります。

App

ここまでは完璧に動いたので、HDMIの2個目の出力を作ることにしましょう。

| | コメント (0)

2020.11.23

HDMIの安定入力のために「フィルタ」を追加

HDMIの出力が安定してできるようになったので、今度はHDMIの入力を安定にしたいと考えました。

今の安定性の問題は、画面の上方に4ラインくらいのごみラインが出て、画面が上下に揺れることです。

dvi2rgbでHDMIの信号をデコードし、その中にある垂直同期信号的な信号(vsync)や、水平同期信号的な信号(hsync)、それとvdeを取り出して、内蔵ロジアナで見てみることにしました。

まず、VSYNCが来る際の挙動です。

Vsync

HSYNCとVSYNCが同時に立ち上がっていますね。HSYNCの立ち上がりの次でhcount=0にクリアして、HSYNCの長さを測ってみたら44クロックでした。

Hsync2

どうやら、HDMIではHSYNCやVSYNCは8b/10b変換して、c0,c1,c2,c3という符号として送られてきています。これらの符号がいつ送られてくるかはソース機器によるのかもしれません。(余談ですが、HDMIの8b/10bはPCI ExpressやSATAの8b/10bとは違うコード体系なんじゃないかなと思います)

このようにして、水平のカウント数や垂直のライン数を数えて、VDEがHになる期間を調べました。

HやVの数を図にしてみます。

Hdmi_hv_20201201174001

HDMIの1920×1080pでは、ブランキング期間を含めると2200×1125のタイミングで送られてきていました。2200×1125×60fps = 148.5MHzなので計算も合います。

 

さて、入力が安定しない機器では、VSYNCが来てから2回目のHSYNCが立ち上がるVCOUNT=1のときにvdeがバタバタ動いているのがわかります。

Vcount0

VCOUNT=2のときにも、vdeはバタバタ動いています。

 Vde_butter 

HDMIの機器によっては上記のVDEがライン1~4くらいの間にバタバタしながらやってくるので、AXI Video DMAなどのカウンタが誤動作してしまいます。それがノイズや信号の減衰によるものなのか、規格的にそうなのかはわかりません。たぶん、FPGAに到達したときのTMDS波形の質が悪いからなんじゃないかなと思います。

そこで、VCOUNTが31以下ならVDEがHになっても強制的にLにするというチート的な回路を入れてみたところ、画面の揺れはぴたりと収まりました。

Filter

    process(pixclk) begin
if(pixclk'event and pixclk='1') then
hsync_o <= hsync_i;
vsync_o <= vsync_i;
data_o <= data_i;
if(disable_filter_i = '1') then
vde_filter <= vde_i;
else
if(vcount >= 32) and (vcount < 1121) then
vde_filter <= vde_i;
else
vde_filter <= '0';
end if;
end if;
vde_filter_d <= vde_filter;
end if;
end process;

こんなんでいいのかという疑問はありますが、画像が劇的に安定したのでした。

| | コメント (0)

2020.11.22

AXI Video DMAで画面を切り替える

XILINXのIPコアでAXI Video DMAというのがあります。これは、DDR3 SDRAMから自動的にデータを取ってきてAXI Streamから出力するということをしてくれます。

使い方は結構複雑です。

  • AXI VDMAには、AXI Liteでレジスタ設定をする必要があるため、AXI Liteを出力できるIPが必要
  • AXI VDMAの出力は32bitなので、RGB 24bit化するためにAXI Subset Converterを使う
  • AXI StreamをAXI Video Outに入れる
  • AXI Video Outのタイミング信号生成用に別途Video Timing Controller(v_tc)を使う
  • AXI Video Outの出力はRGBなので、TMDSコンバータを別途入れる

Vdma

これで、DDR3 SDRAMの特定のアドレスから繰り返しデータを読み出して画像表示してくれます。ここまでは他社の評価ボードでもやっているので難しくはありません。

しかし、画面を切り替えたい場合はどうすればいいのでしょう。

次のようにしたらうまくいきました。

① AXI Video DMAの設定で、Frame Buffersを2以上にする

Vdma2

② MM2S_DMACRレジスタ(アドレス0)のbit1 (Circular_Park)を'0'にする。

Vdma3

③ MM2S_START_ADDRESS1、MM2S_START_ADDRESS2、MM2S_START_ADDRESS3・・・に出力したいメモリのアドレスを書いておく。

④ 表示を切り替えたいときに、PARK_PTR_REGレジスタ(アドレス28h)のRdFrmPtrRefを書き換える。

Vdma4_20201201190501

このRdFrmPtrRefに、フレームバッファのポインタを書き込むことでDMA先頭アドレスが変わるという仕組みのようです

画面の切り替えは直接アドレスを指定するのではなく、フレームバッファの番号で設定するようでした。私のやり方が悪いのかもしれませんが、動作中にMM2S_START_ADDRESSxレジスタを書き換えてみても表示は切り替わりませんでした。昔のPCのように表示アドレスの先頭を書き換えるということでの画面スクロールはできなさそうです。ちょっと残念でした。

 

| | コメント (2)

2020.11.21

ついに、Kintex-7で安定したHDMI 1080p出力に成功!

ついにKintex-7での安定したHDMIの1080p出力に成功しました。USB3.0で書き込んだ画像をHDMIで表示しています。

Hdmicosmok

「安定した」というのは、Vivadoのバージョンによらず、他の回路に影響されず、XDCファイルにCLOCK_DEDICATED_ROUTEを指定することもなく、Warningも出さずに論理合成できるようになったことを意味します。7シリーズクロックリソースの理解が鍵でした。

リソースの使用量はこんなもん。

Res1 Res2

使っているボードは、HDMIを4ポート備えたKintex-7ボード「Cosmo-K」です。

1544234522_cskdvi

 

ただ、最初、HDMI出力をしてみると、液晶モニターによっては画面が出たり出なかったりしました。

家庭用テレビでは映るのにメインで使っている液晶モニタには画像が出ない。(# ゚Д゚)

モニターによって映ったり映らなかったりする原因は、HDMIコネクタの18番端子「+5V」にありました。

Cosmo-Kの回路図では+5Vの端子と、システムの+5Vの間にはNI(未実装の抵抗のパッドのみ)となっていて、HDMIの+5V端子はオープンになっていました。

Hdmi_tx

ここに1kΩの抵抗をつないだら、最後まで映らなかったモニターでも画像が出るようになりました。

原因を見つけたきっかけは、Zynqberryの回路図です。

Zb_hdmi

この回路は非常に参考になります。5Vは、ソースの5V→シンクへ供給するということが明確に示されているからです。

他にも、DigilentのPYNQやZYBOの回路図も調べたのですが、システムの5Vと直接つながっているだけなので、どちらからどちらへ供給するものかわからなかった

+5Vってモニターからシンク機器へ電力を供給するものだと思っていましたが、ソースからシンクへ電流を供給するものだったのです。しかも流せる電流が55mAと微弱なものだそうです。[参考記事] たぶんEDID(モニタの解像度などの情報を得るROM)の電源ですね。

どうやら私がメインで使っている液晶モニタは、この5Vが来ているかどうかでソース機器の接続を判断していたようです。

あと、HDMIのMISC的な端子について。

Hdmi_misc

  • CECはオープンでよいです。オープンが嫌な場合は3.3Vにプルアップします。
  • SDA、SDLは3.3Vにプルアップしておきます。操作する必要はありません。
  • HPDは、100kΩとか200kΩとかでプルダウンします。シンク機器が接続されるとL→Hに上がるので、何かしたければします。

これらは回路上でプルアップやプルダウンをしておけばよく、必ずしもFPGAに接続して操作する必要はない信号なのです。

あと、XILINXのVideoコアにおけるAXI Stream上のRGBの配列は「RBG」になっているようです。なんでこんな変則的なんでしょうね。

Rgb

| | コメント (0)

2020.11.20

AXI Liteのコアを作り直したらビデオ出力が動いた!

もうね、激おこぷんぷん丸ですよ。

Video Out回路が動かない原因が、Vivadoが生成したステートマシンのフライングだったなんて・・。ツールが自動で生成したIPならちゃんと動くと思うでしょ!?

ここでグダグダいっても仕方がないので、正しいステートマシンの作り方を解説します。

ステートマシンってのは、中に「カウンタ」を入れるんです。ベースとなるカウンタを作って、そのカウンタがカウントアップする条件をAWREADYやBVALIDなどいろいろな信号に関連付けていくのです。

こういうとき、考え方を整理するため、AXI Liteの基本的な動かし方を図にしてみます。

Axilstate

冗長なステートもありますが、気にせずにいきましょう。

とりあえず、0~6まで数えられるカウンタを用意して、そのカウンタの値=ステートとします。カウンタの遷移はcase文で作ります。

WVALIDやAWVALIDなどの信号出力は、特定のステートでそれを出す(ステートマシン中に遷移する信号として記述する)か、ステートをデコードして出す(ステートマシンの外側で書く)ようにします。

これを実際のコードに落とし込みます。上のステートマシンをそのまま書くとあまりにも冗長なので少し縮めています

process(clk) begin
if(clk'event and clk='1') then
if(aresetn = '0') then
wstate <= 0;
windex <= 0;
awvalid <= '0';
wvalid <= '0';
bready <= '0';
else
case wstate is
when 0 =>
awvalid <= '0';
wvalid <= '0';
if(windex < 16) then
wstate <= wstate + 1;
end if;
when 1 =>
case windex is
when 0 =>
awaddr <= x"00000000";--MM2S_DMACR
wdata <= x"00000003";--MM2S_DMACR
when 1 =>
awaddr <= x"0000005c";--MM2S_START_ADDRESS1
wdata <= FRAME_ADDRESS_0;--x"00000000;--MM2S_START_ADDRESS1
when 2 =>
awaddr <= x"00000060";--MM2S_START_ADDRESS2
wdata <= FRAME_ADDRESS_1;--MM2S_START_ADDRESS2
・・・(中略)・・・
when others =>
awaddr <= x"0000FFFF";
wdata <= x"00000000";
end case;
awvalid <= '1';
wstate <= wstate + 1;
when 2 =>
if(awready = '1') then
awvalid <= '0';
wvalid <= '1';
wstate <= wstate + 1;
end if;
when 3 =>
if(wready = '1') then
wstate <= wstate + 1;
bready <= '1';
wvalid <= '0';
end if;
when 4 =>
if(bvalid = '1') then
wstate <= wstate + 1;
end if;
when 5 =>
windex <= windex + 1;
wstate <= 0;
when others =>
wstate <= 0;
end case;
end if;
end if;
end process;

シンプルでしょ?ちゃんと動きます。

Vivadoが生成した回路と違って、アドレス系のハンドシェイクとデータ系のハンドシェイクの順序ができているし、BVALIDをちゃんと待つようにもなっている。

あと、VHDLやVerilogでは、if文やcase文の中ではstate_next <= *** みたいな信号を作るだけにしておいて、別のprocess文でstate <= state_nextとする書き方もありますが、分かりにくくなるのでやめましょう。

「case文でstateを判断し、遷移条件を書いて次のstateを直接指定する」ようにしてください。2つに分けない。

 

波形を見ると、当たり前ですがハンドシェイクが効いています。AWVALID & AWREADYが来てからWVALIDを出し、WVALID & WREADYが来てBVALIDを待ってから次のデータを出すようになっています。

Viddebug9

AXI LiteでAXI Video DMAコアを設定したら、AXI MMが動き、AXI Streamが動くとう連携した動作も見えるようになりました。(ILAだと3つのILAコアが別々だから、こういうデバッグはやりにくいですよね。)

Viddebug10

Video DMAが動き出し、Streamが動き出し、無事にv_tcとaxis_vid_outもロックがかかるようになりました。

これでHDMI端子からメモリの中身の画像が出力されるようになりました。

 

| | コメント (2)

2020.11.19

AXIバスを横から覗き見るVivadoのIPを作る

昨日、ビデオまわりのAXIのバスの動きを調べてみようとILAを入れようとしていろいろハマりました。エラー解決はできたのですが、VivadoからPlatform Cable USBにつなごうとするとhw_serverがすでに立ち上がってるとか、見つからないとか、とにかく接続性が悪いし、SmartLynqはIPアドレスを入れなければならず面倒くさすぎるので、すっかりILAを使う気がなくなってしまいました。

やはりMITOUJTAGに搭載されたBlockRAM型の内蔵ロジアナ(BLOGANA)を使ってデバッグがしたいわけです。

BLOGANAを内包したIPを作ってBlockDesignに張り付けるには一つ問題がります。BlockDesignでのバスの接続は基本的に一対一なので、横から覗き見るようなことができないのです。

でも、ILAみたいにどこにでも接続できるIPを作りたい

頑張って作りました。それがこのコア↓

Viddebug_20201121005001

ビデオ関係の回路につながっているAXI Liteと、AXI StreamとAXI MMの3つのバスを中に引き込んでいます。

作り方としては以下のようにします。

① まず、ピンの設定はすべてinにします。

Viddebug2

② Interface modeの設定では、monitorにします。(mirroredMasterやmirroredSlaveって何につかうんでしょうね)

Viddebug3

このような感じで3種類のバスをmonitor設定にしました。

Viddebug4

③ これで、ポートに虫眼鏡のマークがついてバスを横から覗き見るポートが作れるようになりました。

Viddebug5

 

上のreset_oという端子は、AXI周辺回路をリセットした直後のバスの動作を見るための出力で、MITOUJTAGのロジアナのコアから信号を出せるようにしています。XILINXのVIOのようなことができます。

実際に動作させて波形を見てみると・・・なんじゃこりゃ!

Viddebug6

AXI LiteでVDMAを設定するところの波形がめちゃくちゃです。awvalidを出してawreadyが帰ってきて、wreadyが来ないのに次のawvalidを出しに行っています。それにbrespを待つこともしていない。このvdma_settingsという自作のコアがフライングして動作しているのがいけないようです。

・・いやいや、このコアは自作とはいっても、VivadoのTools→Create and Package New IPで生成したコアですよ。

Viddebug7Viddebug8

それなのに、brespはおろか、アドレスVALIDを与える→アドレスREADYを待つ→データVALIDを与える→データREADYを待つ→BRESPを待つというAXIの基本ができていません。ソースを見るとアドレス系とデータ系のステートマシンが別々に存在していて・・・とにかくわかりにくいソースなのです。

これで原因がわかってきました。

Vivado 2017.2のAXI Video DMAは素早く応答してこの滅茶苦茶なAXI Liteアクセスでもうまく動いていたのでしょう。

ところが、Vivado 2019ごろからはAXI Video DMAのリセット後初回の反応が遅くなり、AXI Liteのハンドシェイクをちゃんとしないと正しく書き込みできなくなたのでしょう。だから昔のVivadoでしか動かない回路が出来上がってしまっていたと推測されます。

VivadoのCreate and Package New IPで生成したAXI Liteのペリフェラルは要注意です。

 

| | コメント (0)

2020.11.18

ILAを使ってAXI Streamの信号をデバッグしようとしたら・・

Video Out回路が動かないので、慣れないながらもILAを使ってデバッグしてみようとしました。

手始めにここのAXI Streamを見てみます。

Video_debug1

ところが、Bitgenでエラー発生。

Video_debug2

「このようなクロック接続はできない」みたいなことが書いていて逃げ出しそうになるのですが、7シリーズのクロッキングを完全に理解した(はず)なので、エラーメッセージを読んでみました。

[DRC REQP-1975] OSERDES invalid clock topology: Unsupported clocking topology used for OSERDESE2 hdmi_repeater_i/hdmi_out_0/rgb2dvi_0/U0/ClockSerializer/SerializerMaster. This can result in corrupted data. The hdmi_repeater_i/hdmi_out_0/rgb2dvi_0/U0/ClockSerializer/SerializerMaster/CLK / hdmi_repeater_i/hdmi_out_0/rgb2dvi_0/U0/ClockSerializer/SerializerMaster/CLKDIV pins should be driven by the same source through the same buffer type or by a BUFIO / BUFR combination in order to have a proper phase relationship. Please refer to the Select I/O User Guide for supported clocking topologies of the chosen INTERFACE_TYPE mode.

ふむふむ。エラーを起こしているのはDigilentのIPであるrgb2dviだな。

SerializerMasterというOSERDESモジュールの、CLKとDVICLKが別々のクロックソースから供給されていて許されない接続だと言っているようです。確かにOSERDESのクロックはBUFRとBUFIOから供給しなきゃいけませんね。

ではではDeviceのViewを見てみましょう。

Video_debug3

なんだこりゃ?CLKDIVがPixelClk_BUFGというネットになってるぞ。こんな信号は使った覚えがない。

Video_debug4

rgb2dviのソースをDigilentのgithubからダウンロードして比べてみても変更点はない。

ネットをたどっていくと、下にあるBUFGが勝手に挿入されたようです。

Video_debug5

VivadoのプロジェクトフォルダをGREPして調べてみると、

Time (s): cpu = 00:00:17 ; elapsed = 00:00:30 . Memory (MB): peak = 2076.555 ; gain = 111.723
INFO: [Opt 31-389] Phase Sweep created 1 cells and removed 8929 cells
INFO: [Opt 31-1021] In phase Sweep, 1173 netlist objects are constrained preventing optimization. Please run opt_design with -debug_log to get more detail.  
Phase 5 BUFG optimization
INFO: [Opt 31-194] Inserted BUFG hdmi_repeater_i/hdmi_out_0/rgb2dvi_0/U0/ClockGenInternal.ClockGenX/PixelClk_BUFG_inst to drive 8 load(s) on clock net hdmi_repeater_i/hdmi_out_0/rgb2dvi_0/U0/ClockGenInternal.ClockGenX/PixelClk_BUFG
INFO: [Opt 31-193] Inserted 1 BUFG(s) on clock nets
INFO: [Opt 31-1112] Starts optimizing BUFG(s) with a common MMCM/DPLL/XPLL driver.
INFO: [Opt 31-1112] Starts optimizing BUFG(s) with a common driver.
INFO: [Opt 31-1092] Phase BUFG optimization transformed 0 BUFG(s) to MBUFG(s).
Phase 5 BUFG optimization | Checksum: 22d88c4d1

ということだそうです。何勝手に挿入してんねん😡

ちなみにrgb2dviコアの設定でシリアルクロックの生成にMMCMではなくPLLを使ったのが原因のようでした。FPGAにMMCMは8個しかないのでもったいなくてPLLにしたのがいけなかったようですね。

どうやら論理合成にBUFGの最適化というのをやってくれるようで、それが勝手にBUFGを挿入して今回のエラーになったようです。

ツールにBUFGを最適化させないためにも、正しいクロックネットを作らなければいけませんね。

| | コメント (0)

2020.11.17

Kintex-7でHDMI出力回路

Kintex-7にHDMI出力回路を入れてDDR3メモリの内容を表示しようと思っているのですが、なかなかうまくいきません。

Dviout1

回路は↑の図のようなもので、DDR3メモリから読み込んだ内容をv_tcやvid_outで表示するというシンプルなものです。Vivado 2017.2で作ったデザインではこれで動いていたはずなのですが、2019.2ではなぜか動きません。Lockがかからないのです。

一番後ろにあるrgb2dviはDigilent製のコアです。設定は以下のとおり。

Dvi2rgb

AXI to Video Outの設定は以下のとおり。

Vid_out

Video Timing Controllerの設定は以下のとおり。

 

Vtc1

Vivado 2017.2のころとは少し値が違っていたので、Customにして2017.2の設定に合わせます。

Vtc2

Vtc3

AXI Subser Converterは、4バイトのデータを3バイトに切り詰めるためのものです。DDR3メモリからの読み出しデータは32bit単位になっているのですがRGB 8:8:8にするために上位8bitを捨てています。

Axisubset

AXI Video DMAはRead Channelのみ有効にします。

Vdmaout

Dynamic Slaveにしておけばタイミングは自動的に作られる・・・はず。(この辺が一番あやしいかな)

Vdmaout2

Vdma settingsというのは、特電のアルバイトさんが作ってくれたコアで、AXI VDMAの設定をAXI Liteで出力するというものです。

Vdmasetting

どこからどうみても完璧なのに、なぜ動かないのだ。

| | コメント (0)

Kintex-7でHDMI出力回路

Kintex-7にHDMI出力回路を入れてDDR3メモリの内容を表示しようと思っているのですが、なかなかうまくいきません。

Dviout1

回路は↑の図のようなもので、DDR3メモリから読み込んだ内容をv_tcやvid_outで表示するというシンプルなものです。Vivado 2017.2で作ったデザインではこれで動いていたはずなのですが、2019.2ではなぜか動きません。Lockがかからないのです。

一番後ろにあるrgb2dviはDigilent製のコアです。設定は以下のとおり。

Dvi2rgb

AXI to Video Outの設定は以下のとおり。

Vid_out

Video Timing Controllerの設定は以下のとおり。

 

Vtc1

Vivado 2017.2のころとは少し値が違っていたので、Customにして2017.2の設定に合わせます。

Vtc2

Vtc3

AXI Subser Converterは、4バイトのデータを3バイトに切り詰めるためのものです。DDR3メモリからの読み出しデータは32bit単位になっているのですがRGB 8:8:8にするために上位8bitを捨てています。

Axisubset

AXI Video DMAはRead Channelのみ有効にします。

Vdmaout

Dynamic Slaveにしておけばタイミングは自動的に作られる・・・はず。(この辺が一番あやしいかな)

Vdmaout2

Vdma settingsというのは、特電のアルバイトさんが作ってくれたコアで、AXI VDMAの設定をAXI Liteで出力するというものです。

Vdmasetting

どこからどうみても完璧なのに、なぜ動かないのだ。

| | コメント (0)

2020.11.16

HDMI 入力+出力+MIGが入った

7シリーズのクロックの仕組みを理解してBUFMRやBUFGを置きなおしたら、CLOCK_DEDICATED_ROUTEの制約を付け加えずに、HDMI入力2ch+HDMI出力1ch+MIGが入りました。

Hdmimig

LUTの使用率は16%なので、余った領域にHLSで作った回路を追加できそうですね。

Hdmimig2

DeviceのViewを見てみると、HDMI(DVI)の入出力はほとんどSLICEを使っていないのがわかります。これならHDMIの出力回路をもう1ch付け加えても大丈夫そうですね。同じクロックで動かすのであればクロックリソースを余分には消費しないでしょうし。

Hdmimig3

 

| | コメント (0)

2020.11.15

7シリーズのクロッキングリソースについて理解する

作りたい回路は以下のような2chのHDMI入力をデコードするものです。DigilentのZYBOなどでも使われているHDMIのデコーダを2chに改造したものです。

Hdmi2ch_20201116154201

MMCMはFPGA内に全部で8個しかなく、各BankのCMTに1個あると思われますので、この回路をBank16の中だけで作ることはできません。下側のMMCMを別のBankに配置する必要があります。

ユーザガイドug472を読んで、7シリーズのクロッキングリソースについて理解を深めることにします。

  • BUFGは32個あるが上下16個ずつにわかれていて、CMTは上半分か下半分のどちらかのグループしか駆動できない
  • SRCC,MRCCのピン(bankに4つ)には、1対1で対応するBUFIOがいる
  • SRCC,MRCCのピンはBUFRを駆動できる。
  • MRCCのピンはBUFMRを駆動できる。
  • BUFMRは各bankに2つある
  • BUFRは分周もでき、BUFIOと組み合わせて使う。

BUFMRとは何ぞやということですが、自分と隣のbankのBUFRを駆動するためのもののようです。隣のBUFR/BUFIOを駆動する以外には使い道はなさそうです。

Bufmr

BUFRや、BUFMR、BUFIOが何を使って駆動できるかも調べてみましょう。

  • BUFIO・・MRCC/SRCC、同一または隣の領域のBUFMR、MMCMの0~3
  • BUFR・・MRCC/SRCC、同一または隣の領域のBUFMR、MMCMの0~3、汎用インターコネクト
  • BUFMR/BUFMRCE・・同じ領域内のMRCCまたはGTクロック

BUFRとBUFIOが各bankに何個あるかということですが、DeviceのViewを見てみるとおそらく4個ずつあります。

Bufio_bufr

BUFMRは各bankに2個あります。

Bufmr_20201116151101

BUFMRの入力はHCLK_CMT_MUXにつながっているので、実際には様々なソースが使えるのかもしれません。

こうしてみると、何となくMIGでDDR3メモリのデータバスが8個ずつのグループに分かれているのも納得できてきます。

BUFR等の数を再確認しておきます。

  • BUFIO・・bankあたり4個
  • BUFR・・bankあたり4個
  • BUFMR・・bankあたり2個

さて、Backboneとは何かということについてはユーザガイドを見てもよくわからないのですが、デバイス全体を縦に貫いているものであることがわかります。

Backbone

Backboneが何本あるのかはよくわかりませんが、

Backbone2

Global Clocking Backboneは32本、CMT Clockingも何本かありそうですね。そんなに便利そうなクロック配線なら最初から使わせてくれよと思うのですが、なんでデフォルトで使うようになっていないんでしょうね。やっぱり特性が悪いのかな。

Deviceのビューを見てBackboneに割り当てられている配線を見てみると、

Bb1

確かにBBとう名前の付く配線を通っていますね。

しかし、Bitgenでエラーが出たほうの配線を見てみると、一般の信号用の配線を通ってしまっています。

Bb2

もしかすると、BACKBONEを指定しているネットが2個あるからいけないのかもしれません。

XDCでBACKBONEを指定しているクロック配線をFALSEにして再度論理合成してみます。

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk]

これで論理合成が通ってBitgemまで徹ようになりました!

つまり、クロックの性能の良さは専用配線 >BACKBONE > 一般配線 という順序なのですが、専用配線やBACKBONEは制約が大きく使えない場合もあるので、そういう場合はCLOCK_DEDICATED_ROUTE FALSEを指定して一般配線を通しましょうということです。

 

そもそもこの回路の問題点は、1つのBankで2chのHDMIを入力するところにあります。BankにMMCMは1つしかないので、隣のBankのMMCMを借りてこなければなりませんが、その際のクロック配線が足りなくてBACKBONEを通したりして、いろいろなエラーの元になっていたようです。IBUFDSから隣にBankのMMCMまで行く配線が一般配線を使っているため距離が長くなっていたりもしていました。

そこで、解決策としては、HDMI1とHDMI2で少しクロックバッファの構成を変え、下の図のようにすればよかったようです。

Bufmr2

本来、BUFMRはMRCCピンからしか駆動できないようなのですが、なぜかMRCCからも駆動できてしまいました。不思議ですね。CLK_MUXというのがうまく配線を繋ぎ変えてくれているのでしょうか。

ug472を読むと、非推奨ながらインタコネクトからBUFMRを駆動することはできるようです。

Bufmr3

一般の配線を通ってしまった信号でもBUFMRを駆動できるようですね。

7シリーズのクロックを完全に理解した気分です。

| | コメント (0)

2020.11.14

CLOCK_DEDICATED_BACKBONEのエラー

ちょっと複雑な回路を作っていると、Vivadoがクロックが引けないとエラーを出してくることがあります。

このデザインはHDMIの2つの入力をミキシングするための回路なのですが、

Cosmok_dvi

以下のようないろいろなエラーが出ます。

Default_err

エラーメッセージの先頭を読むと、

[Place 30-575] Sub-optimal placement for a clock-capable IO pin and MMCM pair. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
< set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk] >
hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/UseIBUFDS.InputBuffer (IBUFDS.O) is locked to IOB_X0Y76
hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/DVI_ClkGenerator (MMCME2_ADV.CLKIN1) is provisionally placed by clockplacer on MMCME2_ADV_X0Y0
hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/UseIBUFDS.InputBuffer (IBUFDS.O) is locked to IOB_X0Y76
hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/DVI_ClkGenerator (MMCME2_ADV.CLKIN1) is provisionally placed by clockplacer on MMCME2_ADV_X0Y0

となっていて、xdcファイルにset_property CLOCK_DEDICATED_ROUTE BACKBONEを追加すればよさそうなヒントが書かれているので、その通りにやってみます。

すると今度は別のところでエラーが出て

< set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets hdmi_repeater_i/clk_wiz_1/inst/clkfbout_hdmi_repeater_clk_wiz_1_0] >

を追加しろと言ってきます。

そのような感じで言われるがままに制約を追加していって、最終的に

set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets hdmi_repeater_i/clk_wiz_1/inst/clk_in1_hdmi_repeater_clk_wiz_1_0]
set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets hdmi_repeater_i/clk_wiz_1/inst/clkfbout_hdmi_repeater_clk_wiz_1_0]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets hdmi_repeater_i/clk_wiz_1/inst/clk_200m_hdmi_repeater_clk_wiz_1_0]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets hdmi_repeater_i/clk_wiz_1/inst/clk_100m_hdmi_repeater_clk_wiz_1_0]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_OUT_5x_hdmi_clk]

ついにRouteは通るようになったのですが、Bitgenでエラーが出るようになってしまいました。

[DRC RTRES-1] Backbone resources: 1 net(s) have CLOCK_DEDICATED_ROUTE set to BACKBONE but do not use backbone resources. The problem net(s) are hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk.

このエラーは、CLOCK_DEDICATED_ROUTEにBACKBONEが指定されたけれども、実際に使用されなかったというエラーです。

XILINXのアンサーAR# 60480で似たようなケースが出ています。このアンサーでは、いったん配線を全部消して、問題となっている配線だけをルーティングし、IS_ROUTE_FIXEDを設定して配線を固定し、再度全配線を行って、get_property route でどの配線を通っているかを調べて、それをXDCに書き出して配線を固定するという超荒業でした。

Tclコンソールで以下を実行します。

open_run impl_1
get_property route [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk]
route_design -unroute
route_design -nets [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk]
set_property IS_ROUTE_FIXED 1 [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk]
route_design
get_property route [get_nets hdmi_repeater_i/clk_wiz_1/inst/clk_in1_hdmi_repeater_clk_wiz_1_0]
{ IOB_IBUF0 LIOI_I0 LIOI_ILOGIC0_D IOI_ILOGIC0_O LIOI_I2GCLK_TOP0 HCLK_CMT_MUX_OUT_FREQ_REF0 HCLK_CMT_FREQ_REF_NS0 MMCM_CLK_FREQ_BB_REBUF0_NS PLL_CLK_FREQ_BB0_NS MMCM_CLK_FREQ_BB_REBUF0_NS PLL_CLK_FREQ_BB0_NS CMT_R_LOWER_B_CLK_FREQ_BB3 CMT_LR_LOWER_B_MMCM_CLKIN1 }

で、この結果から作られたTclの行が

set_property route [get_nets hdmi_repeater_i/hdmi_in_1/dvi2rgb_0/U0/TMDS_ClockingX/CLK_IN_hdmi_clk] { IOB_IBUF0 LIOI_I0 LIOI_ILOGIC0_D IOI_ILOGIC0_O LIOI_I2GCLK_TOP0 HCLK_CMT_MUX_OUT_FREQ_REF0 HCLK_CMT_FREQ_REF_NS0 PLL_CLK_FREQ_BB_BUFOUT_NS0 MMCM_CLK_FREQ_BB_NS0 CMT_R_LOWER_B_CLK_FREQ_BB3 CMT_LR_LOWER_B_MMCM_CLKIN1 }

です。これを追加したら確かに問題の配線はBACKBONEを通るようになったのですが、もうひとつのBACKBONEを指定しているclk_in1_hdmi_repeater_clk_wiz_1_0のほうがBACKBONEを通っていないというエラーが出るようになってしまいました。

やみくもにXDCを追加していってもダメなので、そもそもBACKBONEってなんだ?ってところから調べる必要があるでしょう。

(続く)

| | コメント (0)

2020.11.12

GHz時代のDDR3メモリの配線長は等長配線にする必要があるか?

XILINX FPGAとDDR3メモリを使った1GHzを超えるデータレートの基板を設計するとき、DDR3メモリの配線はどこまで等長配線にする必要があるのでしょうか?

次のうち、正しいものを選んでみてください。

① アドレス線とデータ線の配線長の差は10mm以内にしなければならない

② すべてのデータ線は誤差1mm以下になるよう等長配線する

③ クロックが一番最後に到着するように、一番長くする

④ FPGAのBGAの端子から、メモリの端子まで等長配線する

答えは全部です。

等長配線にはミアンダ配線という「ナスカの地上絵みたいなやつ」を描きますが、その分面積を使ってしまうし配線がまがりくねるのでインピーダンスも乱れて品質は下がります。一方、FPGAからDDR3メモリの端子まで最短で引けば、消費する面積は少なくて済み、波形の品質も最高になりますが、到着時間に差が生じてしまいます。

信号の品質を考えれば、等長配線なんてしないほうがいいのです。

そういえば、XILINXのMIGはIDELAYを使ってキャリブレーションをしてくれるので、メモリからリードするときの信号の到達時間に差があっても吸収してくれるはず・・・それならライト時もやってくれるのかな?🤔

残念ながらODELAYはありません。FPGAとDDR3メモリ間の配線長の差がライト時の性能に影響してしまうとは思いますが、どの程度まで配線長に差が許されるのでしょうか。どの程度まで等長配線を頑張ればよいかというのが今回のブログのテーマです。

 

次の図は、特電Artix-7ボードのDDR3メモリの配線です。

Ddr3_1Ddr3_3Ddr3_2

このようにくねくねとした配線が行われていますが、この配線長を調べてみると次の表のようになりました。

Ddr3_delay

光は1nsで30cm進みますが、プリント基板上の電気信号はだいたい半分ですから1nsで15cm。電気信号が1mm進むのに要する時間は6ps~7psくらいです。(インピーダンスによって少し変わる)

さて、この特電Artix-7ボードではアドレス・コントロール信号の到達時間の差がクロックを基準にして-27ps~+47psであり、データの到達時間がDQSを基準にして-13ps~+33psであることがわかります。アドレス・コントロール信号は終端抵抗まで含めた信号の時間なのであまり意味がありませんが、データレート半分なので十分に遅いので考えなくてもいいでしょう。

DDR3メモリのデータラインは、DQSに対してセットアップやホールドタイムが規定されています。データバスが2バイト以上の場合は個々のバイトのグループに対してDQSがそれぞれ用意されています。それはDQSはキャリブレーション時にWrite levelingという仕組みで調整されるからです。

 

データレート1GHzの場合、FPGAが出す信号の安定している時間が800ps、遷移している時間が200psと仮定します。本当はオシロで見ればいいのですが、高速オシロで測ったときの画像ファイルがどこかへ行ってしまったので、記憶を頼りに仮定の話でいきます。

Transition_20201113022901

FPGAが出力する信号はデータ(DQ)の遷移の中央でDQSが遷移するように位相が90°ずれているので、メモリで受信したときにもDQSがこの安定の800psの中心にいれば、セットアップ400ps、ホールド400psが得られるので最大の安定性が得られます。

しかし、配線長に差があるため、実際にはDQSはデータの遷移の中心からずれてしまうでしょう。

Transition2

DQが遅いビットもあれば早いビットもあるので、全てのビットが揃って安定している時間は400ps+Tmin~400ps+Tmaxまでとなります。

一方、DDR3メモリのデータに対するセットアップとホールドは、必要とするスピードやスレッショルドの深さにもよりますが、1GHz動作時には110psくらいです。800MHz動作時の最大でも165psです。

Setup_hold

表の見方が難しいのですが、1066MHz動作時にはDQSが遷移する前後115psの間、すべてのDQが動かずに安定していればOKということがわかります。そうすると、配線長による到達時間の差は±285psまで許されることになり、DQSに対して±約40mmまでの配線長の差は許されることになります。

さすがに40mmもずれたら気持ち悪いし、反射でバタつくので常識的には±4mm程度にとどめるべきだと思います。

もちろんこの計算はクロック速度や、立ち上がり時間・立下り時間によっても変わってくるので一概には言えませんが、意外とマージンが広いことがわかります。それはDQとDQSの位相が半分ずれているため、デフォルトで500psものマージンがあるからなのです。

「配線長の差は1mm以内にしなきゃいけない」とか「アドレス線と全部合わせなきゃいけない」というのは嘘です。

大事なことですが、セットアップタイムもホールドタイムも必要です。TTLとは違ってホールドタイムも必要ですからクロックが最後に到着すればよいというものではありません。そのために90°ずらしているのですからね。

そうそう、FPGAのダイからBGAのピンまでの配線長は各ピンでバラバラです。Kintex-7の場合で調べたら60ps~200psくらいでバラついていました。基板の配線長の差よりもFPGAのパッケージの中の配線長の差のほうが大きいかもしれませんね。その調べ方はまた別の機会にしましょう。

😀

そういえば、Virtex-4で頑張っていたころはもっと等長配線が厳しかった気がしますが、最近はあまり苦労している気がしないなあ。こんな事情があるのかもしれませんね。

 

| | コメント (0)

2020.11.11

PROTEL99SEでベタパターンの回り込みを防ぐ方法

プリント基板を作るときに、部品面や半田面にベタパターンを施すことがよくあります。理由としては、GNDのベタを配置することで電源のインピーダンスを下げたり、ノイズの放射を抑制したり、残銅率を上げることで基板のソリを減らすということが挙げられます。

私はPROTEL99SEという20年前の基板CADをいまだに使っているのですが、いままでベタパターンの回り込みを防ぐ方法がわからず、単純にベタを配置して下の図のような基板になっていました。

Beta

コイルやコンデンサのようにパッド間が広い部品では部品の下にベタが回りこむし、狭いところにはヒゲができたり、広い隙間には半島ができたりします。

ポリゴンを細かく貼っていくのも面倒だし、ベタの幅や間隔を大きくするとベタが荒くなります。KEEPOUTレイヤーにオブジェクトを配置すると全部の層に影響してしまうし・・と悩んでいたのですが、なんと、PROTEL99SEにもこのベタの回り込みを防ぐ方法があったのです。

その名も、Layer Specific Keepout

まず、回り込みを防ぎたい層で、直線(Track)か、円弧(Arc)か長方形(Fill)を置きます。

P-Lの直線がおすすめです。

Track

そうしたら、ダブルクリックしてプロパティを開き、Keepoutと書かれたチェックをONにします。

Keepout

これで、Trackの周囲が紫で縁取りされた怪しげなTrackに変わります。

Track2  

これを回り込みを防ぎたい場所に配置します。ポリゴン(ベタ)と干渉するのでOnline DRCがエラーを出しますが無視します。

Keepout2

そして、ポリゴンを再生成すると、この線の部分にかからないようにベタがよけてくれます。

Keepout3

こんな変な線があっては困るのですが、Keepout指定した線はPrintPreviewやガーバには出てきません。

Keepout4

これで、望みの形のベタパターンが作れるようになるわけです。

 

もう少し複雑な例でやってみると、下のスイッチング電源のパターンを見てください。コイルやダイオードの下にベタパターンが回りこんでいます。

Before_20201113043301

こうやってたくさんのLayer Specific Keepoutを配置することで、ベタパターンの回り込みを防ぎ、

After_20201113043301

出力するときにはKeepoutオブジェクトも消えているというわけです。

Preview

この機能を使う上でひとつだけ注意しなければならないことがあります。それは、Layer Specific Keeooutオブジェクトにネット名を付けてはいけないことです。No Netなオブジェクトとして配置したTrack/Arc/Fillは何か別のネットに移動して触れると名前が自動で設定されてしまいます。名前が付くと、Keepoutとして動作しなくなります。名前をNo Netに戻してもKeepoutにならないので、これはバグなのでしょう。

そのため、配置したら移動させずにすぐにKeepout属性を設定してください。ダイアログをいちいち開くのは面倒なので、一つ作ってコピペするといいかもしれないですね。

ここまでPROTEL99SEでのやり方を示しましたが、おそらくAltium Designerでも変わっていないはずです。

😂

こんな便利な機能があったなんて。PROTELからAltiumへアップグレードする理由がまた一つなくなりました。

 

| | コメント (1)

2020.11.10

Artix-7のPCI Express基板の設計を少しすすめる

Artix-7のPCI Express基板を作るぞーと思いながら6か月ほど放置していたプロジェクトがあります。

A7pcie_20201113044601

ここまで配線したのですが、飽きちゃったのか放置していました。受託開発の仕事がひと段落したので気分転換に配線を進めることにしました・・が、なぜこういう設計なのかが、もはや理由がわからない。半年前に何を考えていたのだろう。🤔

おそらく、Arduinoコネクタの右下にあるところはArtix-7の内蔵ADコンバータが使える端子に配線するのだろうな・・とか、PMODとフラットケーブルは同時には使わなくていいんだろうな、とか。

 

ただ、コンセプトは

FPGAボードをどこまで安く作れるかを試してみたい

だったと思います。

私が設計する評価ボードはどうしてもあれもこれも載せたいと欲張ってしまい、コストが高くなる傾向にあります。必要最小限のシンプルなものを安く作ったら売れやすいのかどうかを試してみたかったんだと思います。これであまり売れ行きがよくなければ、販売数とコストの相関関係はあまりないという認知バイアスが強化されるというわけです。そういう実験のために作ります。

ただ、回路としての設計目標を決めていなかったので、たくさんあるコネクタをどこから配線つなごうかなとか悩んでしまい、あまり設計は進みませんでした。

A7pcie2_20201113045201

また半年くらい経ったら続きを作ることにしましょう。

 

| | コメント (0)

2020.11.09

リニアレギュレータの逆電圧保護回路

リニアレギュレータには、ダイオードを並列に入れることがあります。

Ldo_with_diode

これはどういう理由かというと、出力電圧 >入力電圧になったときに、いろいろな理由によりレギュレータがダメージを受けるのから保護しようという目的です。

どういう条件でこのようなことが起こるかというと、

  • 電源をOFFした際
  • 出力にインダクタ的なものがあって逆起電力が発生する場合
  • 電源入力をショートした場合

入力ショートというのは試作・デバッグ段階では起こりそうですね。

回路を実際に動かしはじめてからよくあるのは、電源OFFの際に繰り返しダメージを受けてレギュレータが損傷していくパターンです。電源がOFFになるとVinは比較的早く減衰しますが、Voutに大きなコンデンサが入っていると、出力側の電圧がなかなか下がらず、VinとVoutの電圧の逆転が起きてしまいます。

Inverted

 

リニアレギュレータが7805のような古いバイポーラ型である場合、レギュレータ内部の出力トランジスタのベースエミッタ間に逆電圧がかかってしまってダメージを受けます。(2SC1815のVBE逆電圧の最大定格が5Vですから意外と低いものです。)

Bireg

リニアレギュレータがLDOである場合、だいたいはMOSFETが使われています。MOSFETでは寄生(ボディ)ダイオードが導通するので負荷側の電圧は無事に放電されますが、ボディダイオードに積極的に電流を流す使い方は推奨されません

Mosfet_reg

私がよく使っているデバイスではどうかというと、

  • TPS736xx・・・VINより先にENピンをLowにすることでReverse Current Protectionが働く
  • TPS78618・・・PMOSですが、PMOSに内蔵されたダイオードが逆方向電流を流す。この電流はリミットされないので必要であれば外部に追加するべき
  • ZLDO1117・・・外部にダイオードを付けることを推奨
  • LP38798SD・・・記載なし

とのことでした。

最新のLDOを見ても、EN端子をLにすることで出力コンデンサをアクティブに放電させるようなものがありますが、やはりコンデンサが大きいと放電しきれないとのことです。それにENをLにするなんて面倒なことしていられません。いくつかの最新LDOのデータシートを見てみましたが、ボディダイオードに電流を流すことは基本的には推奨されないか、明確にNGとされています。

7805タイプのバイポーラ・レギュレータの場合はベースエミッタ間に逆電圧が加わることでダメージを受けますが、LDOの場合はボディダイオードに大電流が流れることでダメージを受けます。この逆電流を阻止すれば壊れないので、レギュレータ自体や電源回路にさまざまな工夫がとられています。大きく分けて「逆電流をバイパスする」方法と「回路を遮断」する方法があります。

  • 電源入力にダイオードを入れる・・・最も簡単だけど電圧降下で損失大
  • ダイオードの代わりにMOSFETのバックツーバック接続にする・・・電圧降下は減るけどコスト高
  • 本題のようにショットキダイオードでバイパス・・・ショットキの逆電流が漏れが大きい
  • 普通のダイオードでバイパス・・・導通するまでの電圧が高いから保護にならない
  • 出力MOSFETのサブストレートをGNDに接続する・・・あまり一般的ではないけど寄生ダイオードが生じない???

Mosfet_substrate

逆電流保護の問題は現時点の最新デバイスにおいても完璧には解決はされていないようで、外部にショットキバリアダイオードを接続するのがいまだに基本のようです。

 

| | コメント (0)

2020.11.08

半導体のジャンクション温度とパッケージ

電源回路やOPアンプなど発熱する回路の設計をしていると、電源ICの許容電流だけではなく最大損失に気を付けなければなりません。ICが電力を使用すると発熱しますが、その発熱がICのチップ自体を温めるので、許容された最大の温度を超えないように注意しなければなりません。

ICのチップ自体の温度をジャンクション温度といい、動作時の最大温度が決められています。

ジャンクション温度はICのパッケージの中にあるので直接測定することはできません。そこで、ICのチップ(ジャンクション)の温度がケースを伝わって来るときの熱抵抗を使ってチップの温度を推定するということが行われます。

下の図のように、ICのチップからケースを伝わって表面に熱が伝わってきます。このケース表面の温度をTc1とし、ジャンクションからケース表面までの熱抵抗をψjt(プサイジェーティー)といいます。ケース表面から周囲の環境への放熱の熱抵抗をθcaといいます。θca+ψjtを合わせてθjaといいます。

Tj_20201110095801

実際のIC(TPS736xxというドロッパ型電源IC)の熱的特性を見てみると、下の図のようになっています。この数字が大きいほど熱抵抗が大きい=放熱が悪い、ということになって、数字が小さいほうが放熱が良いということになります。

Tps736xx_thermal

最大許容損失の計算にはθjaがよく使われます。いろいろな経路で熱は放熱されますが、すべてを総合した値がθjaです。θjaと発熱による損失[W]をかけた値から、

Tj=θja×Pd+Ta・・・ジャンクション温度(℃)=熱抵抗(℃/W)×発熱(W)+周囲温度(℃)

と推定されます。

このICでは動作時のジャンクション温度は-40℃~125℃とされているので、この式にあてはめていくと、周囲が25℃のときにSOT23ピンのデバイスに許される電力損失は、

125>221.9×Pd+25

Pd < 0.45Wとなります。この電源ICを5V→2.5Vへの降圧で使うならば、最大電流は180mAまでに制限されます。

このように、発熱が見込まれるICでは、最大ジャンクション温度にも気を付けて設計(部品選定)しなければなりません。

さて、このICには3種類のパッケージが用意されていますが、その熱抵抗の大きさは下の図のとおりです。裏面に放熱パッドがあるVSON(QFNのように足が出ていないタイプ)が最もよく、次に大きなフィンが出ているパッケージとなって、一番悪いのはSOT23の使いやすいパッケージとなっています。

Thermal_res_20201110102101

実装がしやすく(手はんだでも容易)、物理的なサイズも小さいSOT23が最も悪いのですね。STO223はパッケージが分厚いのでパッケージからの放熱は悪いのですが大きなフィンから放熱できるので、θjaは小さくなっています。これはなんとなく納得できるかと思います。

θjaの値はだいたいどのくらいなのかというと、いろいろなメーカーのICでいろいろな種類のものを見て総合した結果ですが、

  • QFN/CSP・・20~50
  • BGA・・20~30
  • SOIC+PowerPAD・・40~50...100
  • QFP(50~100ピン程度)・・50
  • SOIC・・125
  • SON(電源IC)・・50
  • MSOP/SON(OPアンプなど)・・130~150
  • TSSOP/VSSOP・・180~210
  • SOT-23・・170~250

くらいです。

ざっくり言うと、パッケージが小さくなると放熱が悪くなります。

1.27mmピッチのSOICよりも、0.5mmピッチのTSSOPやVSSOPのほうが放熱が悪いので熱くなります。それを劇的に改善するのがパッケージ裏面のサーマルパッドです。QFNのICはほとんどどれも裏面にサーマルパッドが出ているので、放熱はとても良くなります。

そのかわり基板がすごく熱くなりますね。もし、サーマルパッドで基板に放熱しないことがどんなに悪いことが起きるか想像がつくと思います。

BGAはそれほど放熱はよくありません。やはりボールだから密着が悪いんでしょうかね。でもピン数が増えてくると放熱はよくなります。

 

それから、熱特性のinformationに、ψjtやψjbという項目があるかと思います。これは半導体表面温度とジャンクション温度との差を示すパラメータで、

Tj=ψjt×pd+Tc

のようにして使います。θjaと何が違うのかというと、ψjtはパッケージ表面温度を放射温度計で測ってそこからジャンクション温度を推定するのに使います。設計のときにはθjaを使って最大許容損失を求め、実際に測定するときにはψjtを使うとよいようです。

Texas InstrumentsのICはψjtはとても小さい(一桁~20くらい)なので、パッケージ表面の温度とチップの温度の差は5℃とか10℃とかそのくらいと推定されます。

だから触ってアチッとならなければ大丈夫なのです。

 

| | コメント (0)

« 2020年10月 | トップページ | 2020年12月 »