このところビット列、バイト列の生成、復元などを練習しており、前回は巡回冗長検査(CRC)でした。今回はHDLC(High-Level Data Link Control)などで使われるゼロビット・インサーションとリムーバルを練習してみたいと思います。「原理」実装は動いた、けれども分量が多いとダメだなこれは。どうする?
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※Windows11上で、Scilab6.1.1およびScilab上のツールボックス Scilab Communication Toolbox 0.3.1(以下comm_tbx)を使用させていただいとります。
ゼロビット挿入
0と1のビット列が長くなってくると、連続して1や0のシーケンスが出現する確率も当然上がってきます。通信の元祖か御本家か?HDLCでは、ヘッダ(1が7個連続したもの)とそうでないデータを識別するために、データ部分では1が5個連続したらば次に0を挿入して5個以上続かないようにする「仕組み」が求められています。当然「ゼロビット挿入」されたビット列から元のデータ列を復元する場合には、上の逆で1が5個連続した後の0は挿入された0なので取り除く操作が必要です。
ゼロビット挿入の自前Scilab関数
0と1のビット列(行ベクトル)のために作成した自前関数(効率悪いので「原理実装」じゃといいわけ)が以下に。第一引数に01の行ベクトル、第2引数に検出する1の連続数を与えるもの(HDLCの場合は5を与える。)
// zero-bit insertion (by J.Halfmoon Nov. 30, 2023) // blis: bit data list // cone: number of consecutive 1s to detect // b: bit data list(zero-bit inserted) function b=zeroBitIns(blis, cone) b = [] counter = 0 for bi = blis do if bi == 0 then counter = 0 b = [b 0] else counter = counter + 1 if counter == cone then counter = 0 b = [b 1 0] else b = [b 1] end end end endfunction
ゼロビット削除の自前Scilab関数
上記で生成したゼロビット挿入されたビット列(行ベクトル)から挿入されたゼロビットを削除して元に戻す自前関数(これまた効率悪いので「原理実装」じゃといいわけ)が以下に。
// zero-bit Removal (by J.Halfmoon Nov. 30, 2023) // blis: bit data list(zero-bit inserted) // cone: number of consecutive 1s to detect // b: bit data list(zero-bit removed) // err: error flag function [b, err]=zeroBitRem(blis, cone) err = %f b = [] counter = 0 for bi = blis do if counter == cone then if bi==1 then err = %t counter = 1 b = [b 1] else counter = 0 end else if bi == 0 then b = [b 0] counter = 0 else b = [b 1] counter = counter + 1 end end end endfunction
動作検証と問題点
上記の挿入、削除関数と、過去回で作成したビット列の比較関数を使って短いパターンで動作検証してみるコードが以下に。
a = [1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0] b = zeroBitIns(a, 5) [c, err] = zeroBitRem(b, 5) [nerr, ber, flag] = calcBER(a, c)
ちゃんと0挿入され、そして元に戻っておるようです。
今度は少し長いランダムシーケンスに対して処理する場合。なお、ランダムビット列生成に使っているcomm_tbxのprbs()関数は列ベクトルを返すので「転置」してます。
d=prbs(1000); e=zeroBitIns(d', 5); length(e) [f, err] = zeroBitRem(e, 5); length(f) [nerr, ber, flag] = calcBER(d', f)
挿入して削除して元に戻ったようです。
1000個くらいのビットであれば全然問題なく動いているように見える。けど調子に乗って100万ビット食わせてみたら全然戻ってこないです。double型のデータ100万個、たかだか8Mバイトっす。でも「ズボラなリスト処理」をしているせいで、リストの挿入やら削除やらの手間がとっても大きいのだと思います。まあ、実際にHDLCするならScilabでやらんか。。。どうする?