【今週の関心記事】2018/10/13

www.links.co.jp

おお、私が今使っているLIVA Zの後継機が出た!

大きな変更は追加ドライブがM.2から2.5インチに変わったこと。
この理由としてはLIVA Zで使われていたM.2はフォームファクタ
2242という超小型タイプでして、
あまり市場で流通しなかったことが原因と思います。
M.2の定番は2280ですが約二倍くらい大きい。
2280と2.5インチを検討してみてサイズ感が大きく変わらないのが
後者だったのかなと推測されます。

まあ結局サイズとしては、一回りでかくなってるんですが。
LIVA Z 215x215x58mm
LIVA Z2 255x220x75mm

他はディスプレイ出力からmDPが無くなりました。
HDMIを2基搭載することでマルチディスプレイ環境は継続サポートされています。
これは規格競争でDPが負け始めている為、主流のHDMIに絞った為と思います。

なかなかインターフェースの世の中の流れが定点観測的に分かって、面白いですね。

【今週の関心記事】2018/9/30

qiita.com

スピルという機能がExcelに追加された。
なんか難しいと感じる割に、得られるものがちょっとすぐには思いつかない。
いざ使う場面になったら、便利なんだろうか?

jp.cointelegraph.com

DMM.comニュースリリースでASIC開発したという事例はあったけど、
世の中的には類字のことをやってる会社がたくさんあるんだな。

smhn.info

詐欺してでも勝ちたいという気概は重要。
何故ならその市場でトップを狙ってるということだから。

後発には手段を選ぶ余裕なんて無いんです。
これで返品とか損害賠償が起きればまた話は違うのだが、
傷つくのはブランドイメージだけ。
守るブランドイメージが無ければそりゃあやるでしょ。

という風に思うのは、僕がベンチマークで話題になるような
ハイエンド機を使わないからです。
ユーザーからしたら、がっかりでしょうね。

av.watch.impress.co.jp

おお、これは欲しい。
テレビ番組をスマホで見れるなんて。

僕はコンテンツの質はネットよりテレビのほうが面白い、と思ってる。
見る行為はネットのほうが楽だけど、中身は制作に金かけてる分テレビのほうが断然いい。

そこへ来てスマホでテレビを好きな時に見れる、
というソリューションはテレビユーザーにはありがたい話だ。

【今週の関心記事】2018/9/8

news.mynavi.jp

僕自身がiPhoneをやめてファーウェイに乗り換えた口なので、安くて良いものを作ると感じます。
最初はローエンドの中華スマホの代表格でしたが、すっかり規模が大きくなり、APUも自前するレベルにまで到達。
さらには世界初の先端技術の開発も出来るようになってしまったか。
日本メーカーは完全に負けた。
けど僕は廃墟の中からこそ良いモノは生まれてくると思ってますよ。

wired.jp

これも同じくファーウェイ関連。
オランダでは締め出しを食らっているそうだ。
日本もセキュリティ意識は高めるべきなんじゃなかろうか。
安心して使えないものは販売停止にすべき。
この手の「中国製、危ないんじゃない?」的な話は、中国や韓国に変な気を使って表沙汰にされないような、そんな空気を日本では感じる。

www.businessinsider.jp

僕は完全に別意見。
もっと人材は流動化すべきだと思う。
自分が最も力を発揮できる場所を探しましょう。
また、組織としても人材の入れ替わりのない組織は、空気が淀んでしまいます。
大きな会社なら人事異動という形が良いのだが、そう都合よく人事は仕事してくれませんからね。

【今週の関心記事】2018/9/1

gigazine.net

GFが7nmの先端プロセスから脱落。
半導体ロジックのファウンダリは、TSMCSamsungの2社に絞られた。
あ、一応やる気あるか微妙だが、intelもか。

GF は設立した当初から他社に勝てるところの少ないところだった。
当初のまま差別化することもなく負けていった印象。

14nmと12nmで勝負していくということだが、差別化が微細化しかない領域だったので、どういう戦い方が出来るのか疑問。
トランプの保守政策の後押しで有利な立場にはあるのに肝心の技術が追いついてない。

news.biglobe.ne.jp

ルネサスがまたアメリカの半導体会社を買収。
IDTというあんまり有名でもない会社。
特許で稀に名前を見たことがある程度。

額が6000億円というから驚き。
IDTの2017の売り上げは800億円弱、営業利益は200億円弱。
2016からの売り上げからは微減。
営業利益率は高いが、6000億の価値はあるのかな。

主力は高速デジタルインターフェース関連製品。
SerdesもDRAMもさらに光通信まで、手広くやっており、製品のラインナップを見る限り、先端までキャッチアップされており、培ってきたものはかなりのレベル。
ルネサスに使いこなせるのか?

【今週の関心記事】2018/8/25

akiba-pc.watch.impress.co.jp

Phison製コントローラICを使用したM.2ドライブ。
PCIeカードとしても使用可能なところが特徴的。

ICはデータの圧縮機能までコントローラで担っている。
しかもICベンダの独自仕様。
単なるバッファや規格変換だけでなく、そういうところに付加価値をつけてるんですね。

ascii.jp

M.2ドライブをUSB外付けドライブに変換するケース。
USB3.1 Gen2の10Gbpsを活用して書き込み読み込みともに非常に高速。

ICはJMicron製のPCIe Gen3 x2-USB3.1 Gen2変換ICを使用。
この手のブリッジICは規格が立ち上がる度に登場するが、付加価値があんまりない。
しかも、高速IFはRevision更新が2-3年単位とめちゃくちゃ早いので、陳腐化も早い。
このICもこの用途しか使い道がないのではないかと思うと、短命で終わりそうですね。

【Serdes】Dual Dirac MethodをPythonで実装

Dual Dirac MethodをPythonで実装してみた。

Dual Dirac Methodの技術参考資料 (Keysight)
https://www.keysight.com/upload/cmc_upload/All/dualdirac1.pdf

1. Jitter Dataの準備

解析するモチーフをまず定義する。
Data Rate: 10Gbps (1UI=100psec)
Rj: 1ps RMS
Dj: 14ps PP (±7ps)のSj
Sample Size: 1MUI

Jitter Dataのデータは、各行に各UI毎のJitter値として、text file dataを作成。
RjとDjそれぞれのデータを作成してから、それらの和を取ることでTjのデータを作成することにした。

1.1 Rjの生成プログラム

乱数でRjデータを発生させ、rj.csvに保存。

import numpy as np
import csv

#Sample size
intSize = 1000000

#Jitter RMS = 1ps
fltJitterRms = 1e-12

#Generate random pattern
arrData = np.random.normal(0, fltJitterRms, intSize)

#Output Data
arrWriteData = []
for i,d in enumerate(arrData):
        arrWriteData.append([])
        arrWriteData[i].append(d)

with open('rj.csv', 'w') as f:
        wr = csv.writer(f)
        wr.writerows(arrWriteData)

1.2 Dj(Sj)の生成プログラム

14ps-pp, 周波数100MHzの正弦波でSjを発生し、sj.csvに保存。

import numpy as np
import csv

#Sample size 
intSize = 1000000
#Time step : 1UI = 100ps
fltStepTime = 100e-12

#Noise frequency = 101MHz
fltNoiseFreq = 101e6
#Noise Amp = 14ps-pp
fltNoiseAmp = 14e-12 / 2

#Generate sin pattern
arrTime = np.arange(0, intSize*fltStepTime, fltStepTime)
arrData = []
for t in arrTime:
	d = fltNoiseAmp*np.sin(2*np.pi*fltNoiseFreq*t)
	arrData.append(d)

#Output Data
arrWriteData = []
for i,d in enumerate(arrData):
	arrWriteData.append([])
	arrWriteData[i].append(d)

with open('sj.csv', 'w') as f:
	wr = csv.writer(f)
	wr.writerows(arrWriteData)

1.3 RjとDjの合成

rj.csv, sj.csvをコマンド因数で受け取り、2つのジッタの和を取り、rjsj.csvに保存。

import numpy as np
import csv 
import sys

args = sys.argv
path = []
path.append(args[1])
path.append(args[2])

arrData = []

#Read path[0] data
with open(path[0], 'r') as f:
	rr = csv.reader(f)
	for rd in rr:
		arrData.append(float(rd[0]))

#Add path[1] data
with open(path[1], 'r') as f:
	rr = csv.reader(f)
	for i,rd in enumerate(rr):
		arrData[i] += float(rd[0])

#Output data
arrWriteData = []
for i,d in enumerate(arrData):
	arrWriteData.append([])
	arrWriteData[i].append(d)

with open('rjsj.csv', 'w') as f:
	wr = csv.writer(f)
	wr.writerows(arrWriteData)

1.4 生成したジッタデータの確認

結果確認用にヒストグラムプロットのプログラムも作った。

import numpy as np
import csv
import sys
import matplotlib.pyplot as plt

args = sys.argv
path = args[1]
arrData = []

#Read data file
with open(path, 'r') as f:
        rr = csv.reader(f)
        for rd in rr:
                arrData.append(float(rd[0]))

#Plot Histgram
plt.figure()
plt.hist(arrData, bins=100, normed=True)
plt.show()

1.1で作ったrj.csvヒストグラム。ちゃんと正規分布が得られている。

f:id:kent_s:20180817140053p:plain
rj.csv

1.2で作ったsj.csvヒストグラム。正弦波による特徴的なジッタ分布が得られてる。

f:id:kent_s:20180817140241p:plain
sj.csv

1.3で作ったrjsj.csvの分布。正弦波に正規分布が重畳されているのが分かる。

f:id:kent_s:20180817140407p:plain
rjsj.csv

2. Dual Dirac Methodの実装

2.1 BERプロットの作成

1.3で作ったrjsj.csvを使ってBERプロットを作成。
1UIを1000等分にスライスし、ジッタがx番目の各スライスに含まれる確率をJ(x)と定義。
次にJ(x)の積分により、BER(x)を求めています。
出力はber.csvへのファイル出力です。

import numpy as np
import csv 
import sys
import matplotlib.pyplot as plt

fltUi = 100e-12
intRange = 1000

args = sys.argv
path = args[1]
arrJx = np.zeros(intRange, dtype='float')
intSize = sum(1 for line in open(path))

# Read Jitter Data
with open(path, 'r') as f:
	rr = csv.reader(f)
	for rd in rr:
		d = float(rd[0])/fltUi*intRange
		idx = int(round(d))
		arrJx[idx] += 1/float(intSize)

# Cal BER
arrBer = np.zeros(intRange, dtype='float')

for i in range(intRange/2, 0, -1):
	arrBer[i] = arrBer[i+1] + arrJx[i]

for i in range(-intRange/2, 0, 1):
	arrBer[i] = arrBer[i-1] + arrJx[i]

arrBer[0] = (arrBer[-1]+arrBer[1])/2 + arrJx[0]

#Generate Time axis
arrT = np.arange(0, fltUi, fltUi/intRange)

#Plot BER
plt.figure()
plt.plot(arrT, arrBer)
plt.yscale('log')
plt.show()

#Write BER
arrWriteData = []
for i,d in enumerate(arrBer):
	arrWriteData.append([])
	arrWriteData[i].append(d)

with open('ber.csv', 'w') as f:
	wr = csv.writer(f)
	wr.writerows(arrWriteData)

BER(x)の出力です。1MUI(=1e6UI)のデータなのでy軸は1e-6で切れています。

f:id:kent_s:20180817172225p:plain

左側のバスタブを拡大。
f:id:kent_s:20180817172340p:plain

BER=1e-5の後半あたりから曲線が荒い。
これもサンプル数が1MUIの為、BER=5e-5付近で精度が落ちている為。
x=7psec(赤で示したあたり)がDjが無くなるポイントだが非常に滑らか。
つまり、このプロットからRjを予測するのは困難。

2.2 Qプロットの作成

2.1で作ったber.csvからQプロットを作成。
信号遷移率ρTは1とした。
今回のデータは毎サイクルにジッタが発生しているので、信号遷移率は100%となる。

import numpy as np
import csv 
import sys
import matplotlib.pyplot as plt
from scipy import special

fltUi = 100e-12
intRange = 1000
fltRho = 1

args = sys.argv
path = args[1]

#Read BER data
arrBer = []
with open(path, 'r') as f:
	rr = csv.reader(f)
	for rd in rr:
		arrBer.append(float(rd[0]))

#Calc Q plot
arrQ = []
for ber in arrBer:
	q = np.sqrt(2) * special.erfinv(1 - 1/fltRho*ber)
	arrQ.append(q)

#Generate Time axis
arrT = np.arange(0, fltUi, fltUi/intRange)

#Plot Q
plt.figure()
#plt.scatter(np.arange(intRange), arrQ)
plt.plot(arrT, arrQ)
plt.ylim(8, 0)
plt.show()

#Output Data
arrWriteData = []
for i,d in enumerate(arrQ):
	arrWriteData.append([])
	arrWriteData[i].append(d)

with open('q.csv', 'w') as f:
	wr = csv.writer(f)
	wr.writerows(arrWriteData)

Q(x)の出力。
f:id:kent_s:20180817172742p:plain

左のバスタブの拡大。
f:id:kent_s:20180817172849p:plain

バスタブカーブが線形に近いことが確認できる。この線形性を利用してσを計算できる。
x=7psecのSjが無くなるポイントだが、変曲点よりも外側に来ている。
これは参考資料にある通り、Djのpp点Dj(pp)よりも、正規分布中心Dj(δδ)の方が内側に来ることが理由。

2.3 σの計算

最後にσの計算を行う。
BERのバスタブ底は精度が無いので、BER=2e-5のところで近似することにした。
BER=2e-5 ⇒ Q=4.265 (信号遷移率=1の時)なので、Q=4.265のところでfittingを取る。

import numpy as np
import csv 
import sys
import matplotlib.pyplot as plt
from scipy import special

fltUi = 100e-12
intRange = 1000
fltRho = 1

args = sys.argv
path = args[1]

#Read Q data
arrQ = []
with open(path, 'r') as f:
	rr = csv.reader(f)
	for rd in rr:
		arrQ.append(float(rd[0]))

#Search Q 
fltQs = 4.265

def getNearestIndex(list, val):
	return (abs(np.asarray(list) - val)).argmin()

intIlt = getNearestIndex(arrQ[:intRange/2], fltQs)
intIrt = getNearestIndex(arrQ[intRange/2:], fltQs) + intRange/2

#Generate Time axis
arrT = np.arange(0, fltUi, fltUi/intRange)

#Fitting
FitLt = np.polyfit(arrT[intIlt-2:intIlt+2], arrQ[intIlt-2:intIlt+2], 1)
FitRt = np.polyfit(arrT[intIrt-2:intIrt+2], arrQ[intIrt-2:intIrt+2], 1)

print FitLt
print FitRt

#Plot Q
plt.figure()
plt.scatter(arrT, arrQ, c='red')
plt.plot(arrT, np.poly1d(FitLt)(arrT))
plt.plot(arrT, np.poly1d(FitRt)(arrT))
plt.ylim(8, 0)
plt.xlim(0, fltUi)
plt.show()

QプロットとQ=4.265での線形近似直線。
f:id:kent_s:20180818054121p:plain

線形近似の係数はax+bとすると、バスタブ左側はa=9.19e11, b=-5.35. 右側はa=-1.04e12, b=97.0となった。

1/aがRjのσとなるが、計算すると、σ@左=1.1ps, σ@右=1.0psと計算できた。
これは1.1でRjを生成した時の1ps RMSと一致しており、Dual Dirac Methodで正しく見積もれていることが確認できた。

Dj(δδ)=-b/aなので、Dj(δδ)@左=5.8ps, Dj(δδ)@右=-6.3psとなる。
ここからBER=1e-12として、Tj=Dj(δδ)+7*σで見積もると、それぞれ13ps, -13psで、トータル26psとなる。
Dj(pp)=7psだったので、Tj=Dj(pp)+7σで見積もった場合は±14psとなるが、それよりも1psずつ悲観性を無くすことができている。

【Serdes】RjとJTFの関係

PCI Expressなどの高速SerdesのSystemの中で、TXのPLLとRXのCDRはジッタを抑制するフィルタの役割を果たす。これは、ジッタトランスファファンクション(Jitter Transfer Function: JTF)として数学的なモデル化が出来る。

下図の青線がUSB3.1 Gen2のリファレンスとして記載されているRX CDRのJTFである。一方、TX PLL側は同図の赤線のようになる。

RX側のHigh Pass FilterとTX側のLow Pass Filterの組み合わせにより、全帯域のJitterは抑制される。ただし、10MHz付近に関してはスイートスポットとなり、この帯域のジッタは排除することが出来ない。

f:id:kent_s:20180729094817p:plain

JTFはDetermistic Jitter(Dj)を抑える上で効果があることは容易に理解できる。Djは周波数分布が限定されており、その分布がJTFの不感帯に入っていなければ、抑制できると分かるからだ。

では、Random Jitterに対して、これらのフィルタは効くのだろうか?このことをPythonを使ったSimulationで検討した。

検証方法

検証モチーフはUSB3.1 Gen2である。手順をいかに示す。

  1. 乱数を使用し、1ps RMSの時系列データを作成
  2. 1をフーリエ変換
  3. 2にCDRのJTFを乗算
  4. 3を逆フーリエ変換し時系列波形を再生
  5. 4の標準偏差を計算

Simulationに使ったPythonのプログラムを本記事の末尾に記載する。

検証結果

結果は下記の通り、JTFによってほとんどジッタは減っていないことが分かった。

  • JTF通過前ジッタ: 1.00006781201 ps RMS
  • JTF通過後ジッタ: 0.996609674857 ps RMS

周波数スペクトルで見ると、下図の通り、JTFによって低周波数成分は明確に減衰していることは分かる。
ランダムジッタは非常に広い帯域で分布しており、かつ、広域側の強度が強い。したがって、低域側だけの減衰では効果が少ないことが原因と思われる。
にしても、RMSでここまで変化量が少ないというのはとても興味深い。

JTF通過前
f:id:kent_s:20180729105559p:plain

JTF通過後
f:id:kent_s:20180729105632p:plain

ソースコード

import numpy as np
import matplotlib.pyplot as plt

#Sample size
intSize = 1000000
#Time step : 1UI = 100ps
fltStepTime = 100e-12
#Freqency step : 10kHz
fltStepFreq = 1/(intSize*fltStepTime)

#Jitter RMS = 1ps
fltJitterRms = 1e-12

#Generate random pattern
arrData = np.random.normal(0, fltJitterRms, intSize)
arrTime = np.arange(0, intSize*fltStepTime, fltStepTime)

#Generate fft pattern
arrFftData = np.fft.fft(arrData)
arrFftFreq = np.fft.fftfreq(intSize,fltStepTime)

#Calc jitter suppressed spectrum
ks = 0.707
w3dB = 2 * np.pi * 1.5 * 10**7
wn = w3dB / (1 + 2 * ks**2 + ((1 + 2 * ks**2)**2 + 1)**0.5)**(-0.5)
arrFltFftData = np.zeros(intSize, complex)
for i in range(intSize):
        s = 2 * np.pi * arrFftFreq[i] * 1j
        arrFltFftData[i] = (s**2 / (s**2 + 2*ks*wn*s + wn**2)) * arrFftData[i]

#Calc jitter suppressed time domain data
arrFltData = np.fft.ifft(arrFltFftData)

#Output jitter RMS value
print np.std(arrData.real)
print np.std(arrFltData.real)

#Plot Raw Jitter @ Time Domain
#plt.figure()
#plt.plot(arrTime, arrData)

#Plot Raw Jitter @ Histgram
#plt.figure()
#plt.hist(arrData)

#Plot Raw Jitter @ Freq Domain
plt.figure()
plt.plot(arrFftFreq, abs(arrFftData))
plt.axis([1e6,max(arrFftFreq),0,max(abs(arrFftData))])
plt.xscale("log")

#Plot Filtered Jitter @ Time Domain
#plt.figure()
#plt.plot(arrTime, arrFltData.real)

#Plot Filtered Jitter @ Freq Domain
plt.figure()
plt.plot(arrFftFreq, abs(arrFltFftData))
plt.axis([1e6,max(arrFftFreq),0,max(abs(arrFftData))])
plt.xscale("log")

plt.show()