M系列で White Noise の生成
[31,28]g の M-Sequence でホワイトノイズを生成してみました。 2^31-1 の PRBS (Pseudo-Random Binary Sequence) になります。
かなり性質の良いノイズができました。
電線で回路を作っていると時間がかかるので、8051 のチップを使って簡単なプログラムを書いて動作させました。

全体が 31bit のシフトレジスタをシミュレートし、タップを 28 に取った M 系列シフトレジスタです。 M-系列のタップ位置については[以前の記事]を参考にしてください。
適当にプログラムして、まずアイパターンを出してみます。 右の図です。 これはわざと立ち上がりをなまらせて、縦の線がよく見えるようにしています。
まあすなおに出ました。 MPU のハードウェアクロックは 25MHz なのですが、シミュレートしたシフトレジスタのクロックはプログラムステップの分だけ遅くなりますので 763kHz 程度になっています。 (ですので、出力波形の 1 や 0 の最少区間は 1.3us です) またこの原信号の振幅は 3.2V です。
スペクトルを見てみます。 クロックの 1/4 程度がよく見えるようにスパンを
250kHz に取っています。 縦軸は、中央が -30dBV で、一目盛り 10dB です。 窓は
Hanning にしています。フラットで、きれいなホワイトノイズになっています。
ちょっと聞いてみてください。
これです ==>
高い方はどうなっているでしょうか。 スパンを 2.5MHz に広げてみます。760kHz のところで落ち込んでおり、ここより 1/4 程度のところまで使えることが分かります。
低い方はどうなっているでしょうか。 31 ビットですから、 760kHz の 2^31
分の 1 である 0.00035Hz 位まで伸びているはずです。 スパンを 100Hz にした右の図ではもちろん見えませんね。オーディオ帯では問題なく使えます。 ただし、オーディオではホワイトは、 Δf/f を同じにすると高い周波数で Δf が大きくなっていきますから耳には高い周波数が大きく聞こえます。 高い方を 1/√f で (-3dB/Oct. で) 落としこんだピンクノイズを使うときもあります。
え? どうしてももっと低いところまで見たい?右の図はスパンが 1Hz です。 1目盛り 0.1Hz ですね。 これを取るのはとても時間がかかるんですよ。
31 ビットでは高級すぎるときはもっとビット数を落としてもいいでしょう。
試しに 7 ビットにしてみましょうか。 [7,6]g で作ってみました。

右の図はスパン 50kHz で見ていますが、なんか変ですね。 明らかに特定の周波数成分が見えます。
聞いてみましょうか ==>
ぜんぜんダメです。 シミュレーションのクロックは 1.53MHz ですので、2^7-1 の 127 で割ると 12kHz になります。 私の耳には聞こえません。
こうして考えると、下限の周波数で 1/10 Hz 程度をねらえばいいことが分かります。 キャリアが 700kHz とすると、23 ビットほどで十分です。
------
下のコードが今回実験で使ったものです。 P3.3 から出力を取っています。 P3.2 はオシロを同期させるための信号です。 JC のインストラクションはジャンプしないときは 2 サイクルしかとらないので NOP を入れています。
今回使ったチップは Silicon Lab の C8051F310 というもので、安価に入手できます。 開発キットも容易に手に入ります。 チップのスペックはこちらです==> C8051F31x
実際に使用するのならば出力に 20kHz 以上を通さないフィルタを入れる必要があります。
===== 8051 Code for [31,28]g and [7,6]g =====
(前略)
mov r0,#2 ;set seed
mov r1,#0
mov r2,#80h
mov r3,#0
mov r7,#82h ;bits 1 and 7 for [7,6]g
mov r6,#0
mov r5,#20h ;bit 29 for [31,28]g
mov r4,#1 ;bit 1
mov a,#2
clr c
;jmp lp1 ;activate this line for [7,6]g
;31 bit M Seq
lp: setb p3.2 ;sync
clr p3.2
;shift all 31 bits
mov a,r0
rlc a
anl a,#0ffh-1 ;length=31
mov r0,a
mov a,r1
rlc a
mov r1,a
mov a,r2
rlc a
mov r2,a
mov a,r3
rlc a
mov r3,a
jc setbit
;no carry case
nop ;1 clock compensation
mov a,r3
xrl a,r6 ;nop
mov r3,a
mov a,r0
xrl a,r6 ;nop
mov r0,a
setb p3.3 ;set output
jmp lp
;carry case
setbit: mov a,r3
xrl a,r5 ;flip bit 29 for carry
mov r3,a
mov a,r0
xrl a,r4 ;set bit 1 for carry
mov r0,a
clr p3.3 ;clear output
jmp lp
;7 bit M Seq
lp1: setb p3.2
clr p3.2
rlc a
anl a,#0ffh-1
jc setbit1
nop
xrl a,r6
setb p3.3
jmp lp1
setbit1:
xrl a,r7
clr p3.3
jmp lp1
================== code end ===================
[余談]
この 2^31-1 のときに極端に低い周波数まで伸びているというのは、伝送回路を考えるときは問題になります。 近いうちにこれについて考えてみます。
[余談2]
M-系列で Carry bit を使いましたが、これの性質をちょっと調べておきましょう。 ホワイトノイズで大切なのは周波数に関する情報です。
先人の知恵をお借りします。 Cal Tech の Titsworth という方の計算によると、クロックを ωc、シフトレジスタの段数を n としたとき、最低要素周波数はωc/(2^n-1) になって、そこから上に ωc/(2^n-1) の間隔でコンポーネントが連なっており、それぞれのコンポーネント(周波数ω)の相対振幅は
Sin^2(πω/ωc) / (πω/ωc)^2
で表されるとのことです。 ちょっとグラフにしてみますとこんな風です。 0.1Hz までは要素をプロットし、それ以上は連続線で表しました。

実験結果と合っていますね。
私見ですが、直流分もあるはずです。 31 ビットの 1 の連続は一巡の間に 1 回だけ出てきますが、0 の 31 回連続は出てきません。 30 ビットの 1 の連続は出てきませんが、0 なら 1 回出てきます。 (29 ビット以後はどちらも 1、2、4、8... と同数出てきます。) ですから + の方が一巡の長さの 1/(2^31-1) だけ多くなります。 上の図の 0dB に当たる量です。
-----------------
[M-系列、関連記事]
- NRZ 信号と PRBS とカップリング
- M-系列のタップ位置の表とプログラム
- M系列のレジスタを0で始める、ガロアとフィボナッチを入れ替える
