gndless_sample_rate_conversion
Synchronous and asynchronous sample-rate converters for Veryl.
| Version | 0.4.0 |
|---|---|
| Repository | https://github.com/AkiyukiOkayasu/gndless-sample-rate-conversion-veryl |
| License | MIT OR Apache-2.0 |
Modules
| BurstFifo | 2 sampleまでを吸収するdepth-2のvalid/ready FIFO。 |
|---|---|
| HalfbandUpsampler::<COEFFICIENT_SET> | 複数channelのframe vectorを1個のMACでTDM処理する2x halfband upsampler。 |
| LinearAsrc::<FORMAT> | format付きvalue interfaceを使う線形ASRC |
| PhaseIncrementEstimator | サンプル到着周期からASRC用の位相増分を生成する推定器 |
| SampleRateTracker | 入力サンプルの到着周期測定と低域通過周期推定値の出力 |
Packages
| Halfband103Q1_17 | 103 tap halfband用のQ1.17係数set。 |
|---|---|
| Halfband39Q1_17 | 39 tap halfband用のQ1.17係数set。 |
Modules
| BurstFifo | 2 sampleまでを吸収するdepth-2のvalid/ready FIFO。 |
|---|---|
| HalfbandUpsampler::<COEFFICIENT_SET> | 複数channelのframe vectorを1個のMACでTDM処理する2x halfband upsampler。 |
| LinearAsrc::<FORMAT> | format付きvalue interfaceを使う線形ASRC |
| PhaseIncrementEstimator | サンプル到着周期からASRC用の位相増分を生成する推定器 |
| SampleRateTracker | 入力サンプルの到着周期測定と低域通過周期推定値の出力 |
BurstFifo
2 sampleまでを吸収するdepth-2のvalid/ready FIFO。
書き込み側は2クロック連続のburst書き込みを吸収でき、input_readyは空きがある間Highになる。
読み出し側はoutput_valid && output_readyでpopする。書き込みから読み出しまでのレイテンシーは
1クロックで、burst書き込みとpopが同時に起きても失われない。
主にHalfbandUpsamplerの2クロックburst出力を、入力readyが間欠的な次段へ引き渡すために使う。
Parameters
| CHANNELS | u8 | 1 wordあたりのchannel数 |
|---|
Ports
| clk | input | clock | system clock |
|---|---|---|---|
| rst | input | reset | reset |
| input_valid | input | bbool | write valid |
| input_ready | output | bbool | write ready (空きがある) |
| input_samples | modport | gndless_fixedpoint __FixedPointValue__gndless_fixedpoint_Q4_23 input_port [CHANNELS] | Q4.23 write word |
| output_valid | output | bbool | read valid (データあり) |
| output_ready | input | bbool | read ready |
| output_samples | modport | gndless_fixedpoint __FixedPointValue__gndless_fixedpoint_Q4_23 output_port [CHANNELS] | Q4.23 read word |
HalfbandUpsampler::<COEFFICIENT_SET>
複数channelのframe vectorを1個のMACでTDM処理する2x halfband upsampler。
sampleはQ4.23、係数はQ1.17。module境界はQ4.23で統一し、±1.0の信号を±8.0の範囲で扱う。
出力もQ4.23のまま。補間によって+/-1.0を超える場合もある。
入力はQ4.23上で+/-1.0以内(Q1.23相当)であることを前提とする。even phaseの係数の絶対値和は約1.346なので、
出力は最大+/-1.35程度、pair_sum(対称tapの和)は最大+/-2.7程度になり、どちらもQ4.23(±8)の範囲に収まる。
この前提を外れる入力(Q4.23上で±4.0を超える両端)ではpair_sumが27bitでwrapし、乗算前に破損するため、
producer側で入力が+/-1.0以内に収まることを保証すること。
入力frameはinput_valid && input_readyで受理し、処理中はinput_readyをLowにする。
出力はeven phase、odd phaseの順にchannel vectorを1回ずつ出力する。
output_validとoutput_samplesは1クロックの出力レジスタを経由する。各出力は対応する状態に入ってから
1クロック後に現れ、ちょうど1クロックの間保持される。2x upsamplerのため入力frame 1つにつき
even/oddの2出力frameを2クロック連続のburstとして出力するので、output_validは2クロック連続でHighになる。
historyはSRAM推論のためresetで初期化しない。起動直後の内容は不定であり、最初のHISTORY_LENGTH frame分の出力には不定値が含まれる。ストリームが進めば即座に実データへ置き換わるため、 消費側は起動過渡の値を要求しないこと。 historyは循環アドレス方式(書き込み位置のみが前進し、タップkは書き込み位置からk前の位置にある)で、 left/rightの2タップを同時に読むため同じ内容を2コピー持つ。書き込みは入力受理後に1 channelずつ行う。 MACはSRAMの同期読み出し(登録アドレス、1clkレイテンシ)をprefetchパイプラインで吸収し、 1 pair/cycleを維持する。SRAMの書き込みと読み出しは別状態で行うためread-during-writeは発生しない。
係数はfull tap列ではなく、halfbandの対称pair係数を実装した
HalfbandCoefficientSet packageから受け取る。MAC自体はchannelと係数pairの
両方向へ時分割共有する。
COEFFICIENT_SETは係数set prototypeHalfbandCoefficientSetを実装したpackageで、デフォルトはHalfband103Q1_17。
Tap数が少ないHalfband39Q1_17も用意している。tap数が少ないと周波数特性は悪化するが、MACの処理時間は短くなる。
Generic Parameters
| COEFFICIENT_SET | HalfbandCoefficientSet |
|---|
Parameters
| CHANNELS | u8 | channel数。1つのMACでTDM処理する。ステレオを想定して2をデフォルトとする。 |
|---|
Ports
| clk | input | clock | system clock |
|---|---|---|---|
| rst | input | reset | reset |
| input_valid | input | bbool | input frame vector valid |
| input_ready | output | bbool | input frame vector ready |
| input_samples | modport | gndless_fixedpoint __FixedPointValue__gndless_fixedpoint_Q4_23 input_port [CHANNELS] | Q4.23 input frame vector |
| output_valid | output | bbool | output vector valid |
| output_samples | modport | gndless_fixedpoint __FixedPointValue__gndless_fixedpoint_Q4_23 output_port [CHANNELS] | Q4.23 output frame vector |
LinearAsrc::<FORMAT>
format付きvalue interfaceを使う線形ASRC
既定のQ4.23はmodule境界の統一formatで、±1.0の信号を±8.0の範囲で扱う
Generic Parameters
| FORMAT | gndless_fixedpoint SignedFixedPointFormat |
|---|
Parameters
| PHASE_WIDTH | u32 | 位相入力のbit幅 |
|---|---|---|
| INPUT_DEPTH | u32 | 入力FIFOの深さ |
| STARTUP_LEVEL | u32 | 出力開始に必要な未消費FIFO word数 |
Ports
| clk | input | clock | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| rst | input | reset | |||||||||||||||||
| input_valid | input | bbool | |||||||||||||||||
| input_ready | output | bbool | |||||||||||||||||
| input_sample | modport | gndless_fixedpoint FixedPointValue input_port | |||||||||||||||||
| input_level | output | logic<$clog2(INPUT_DEPTH+1)> | |||||||||||||||||
| phase | input | logic|
| advance |
input |
bbool |
| output_active |
output |
bbool |
| output_sample |
modport |
gndless_fixedpoint FixedPointValue output_port |
| underflow |
output |
bbool |
| |
PhaseIncrementEstimator
サンプル到着周期からASRC用の位相増分を生成する推定器
SampleRateTrackerで平滑化した入力サンプル周期から、システムクロックあたりの入力位相進行量を求める。
phase_incrementはQ0.PHASE_WIDTHで、値が1.0未満となるサンプルレート比で使用する。
RATE_MULTIPLIER_SHIFTを2にすると、4倍オーバーサンプリング経路用の位相増分を生成できる。
除算は逐次演算で行い、入力サンプル周期より短いDIVIDEND_WIDTHクロックで完了する必要がある。
除算中に新しい周期を観測した場合は最新の周期を保持し、現在の除算完了後に再計算する。
TIMEOUT_PERIODを有効にすると、入力停止時は古い位相増分を無効化して新しい到着列を再測定する。
Parameters
| PERIOD_WIDTH | u32 | サンプル周期の整数部ビット幅 |
|---|---|---|
| PERIOD_FRACTION | u32 | 平滑化周期の小数部ビット幅 |
| PHASE_WIDTH | u32 | 位相増分の小数部ビット幅 |
| FILTER_SHIFT | u32 | 周期平滑化IIRの右シフト量 |
| LOCK_COUNT | u32 | 位相増分の計算を始める測定回数 |
| RATE_MULTIPLIER_SHIFT | u32 | 位相増分に掛ける2のべき乗倍率のシフト量 |
| STEP_THRESHOLD_SHIFT | u32 | 即時追従する周期差の比率を表す右シフト量、0で無効 |
| TIMEOUT_PERIOD | u32 | 入力停止とみなすクロック数、0で無効 |
Ports
| clk | input | clock | システムクロック | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| rst | input | reset | 同期リセット | ||||||||
| sample_valid | input | bbool | 入力サンプル到着パルス | ||||||||
| phase_increment | output | logic| ASRC用Q0位相増分
|
locked |
output |
bbool |
位相増分が有効
|
range_error |
output |
bbool |
位相増分が1.0以上となる設定または入力を検出
|
|
SampleRateTracker
入力サンプルの到着周期測定と低域通過周期推定値の出力
このモジュールはASRC全体ではない。sample_validの時刻列から、生の周期と平滑化した周期を作るだけに責務を限定する。
位相累積、補間、FIFOレベル制御は後段のモジュールで行う。
FILTER_SHIFTが大きいほど追従は遅くなるが、valid時刻の量子化やサンプル間ジッターを位相増分へ伝えにくくなる。
STEP_THRESHOLD_SHIFTを有効にすると、平滑化周期との差がその2のべき乗分の1以上となった周期変更は即時に取り込む。
TIMEOUT_PERIODを有効にすると、入力停止時にlockを解除して次の入力から測定をやり直す。
filtered_periodはPERIOD_WIDTH.FRACTION_WIDTHの固定小数点値である。
最初のsample_validは基準時刻を記録するだけで、次の到着からmeasured_periodを更新してperiod_validを1クロックだけHighにする。
有効な測定がLOCK_COUNT回に達するとlockedを保持する。
Parameters
| PERIOD_WIDTH | u32 | 整数周期のビット幅 |
|---|---|---|
| FRACTION_WIDTH | u32 | 平滑化周期の小数部ビット幅 |
| FILTER_SHIFT | u32 | 周期平滑化の右シフト量 |
| LOCK_COUNT | u32 | lock判定に必要な有効測定回数 |
| STEP_THRESHOLD_SHIFT | u32 | 即時追従する周期差の比率を表す右シフト量、0で無効 |
| TIMEOUT_PERIOD | u32 | 入力停止とみなすクロック数、0で無効 |
Ports
| clk | input | clock | システムクロック | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| rst | input | reset | リセット | ||||||||||||||||
| sample_valid | input | bbool | 入力サンプル到着パルス | ||||||||||||||||
| measured_period | output | logic| 測定した整数周期
|
period_valid |
output |
bbool |
周期更新パルス
|
filtered_period |
output |
logic | 平滑化した固定小数点周期
|
locked |
output |
bbool |
lock状態
|
timed_out |
output |
bbool |
入力停止によるlock解除パルス
|
|
Module Prototypes
Interfaces
Packages
| Halfband103Q1_17 | 103 tap halfband用のQ1.17係数set。 |
|---|---|
| Halfband39Q1_17 | 39 tap halfband用のQ1.17係数set。 |
Halfband103Q1_17
103 tap halfband用のQ1.17係数set。
係数はtools/design_halfband_coefficients.pyで設計・量子化する。
全係数の絶対値は1.0未満 (最大の最内側pairで約0.636) なので、Q1.17 (範囲[-1.0, +1.0)) に収まる。
Q2.16より小数部が1bit多く、係数量子化誤差が半分になる。
Halfband39Q1_17
39 tap halfband用のQ1.17係数set。
係数はtools/design_halfband_coefficients.pyで設計・量子化する。
全係数の絶対値は1.0未満 (最大の最内側pairで約0.630) なので、Q1.17 (範囲[-1.0, +1.0)) に収まる。