エフェクタのA/Dサンプリング周波数は、CDと同じく44.1kHzとします。
手持ちの水晶は4MHzなのでFPGAで分周してタイミングを生成します。
残念ながら44.1kHzが4MHzの整数倍ではなく、等間隔にはできません。
しょうがないので10msで441回サンプルに帳尻あわせするようにします。
4MHz(250ns)で90サイクルを131回と91サイクルを310回、
それでちょうど10msにする作戦です。
回路はVerilogで記述します。
こんな感じ。
// =====================================================
// A/Dサンプリングタイミングトリガを生成するモジュール
// ベースクロックは4MHz
// サンプルタイミングは44.1kHz(=22.675736・・・us)
// 10msあたり441発のトリガを出力する。
// 90サイクルカウントを131発と91サイクルカウントで310発
// =====================================================
`timescale 1ns/1ns
module m_SAMPL_TRG
(i_clk
,i_rst_n
,o_trg_p
);
input i_clk ;// クロック(4MHz)
input i_rst_n ;// リセット
output o_trg_p ;// サンプルトリガ(44.1kHz)
reg [6:0] count_div;//
reg [8:0] count_trg;// 出力トリガの回数をカウント
reg o_trg_p ;//
wire [6:0]max_count = (count_trg >10'd130 ) ? 7'd90 : 7'd89;
wire cler_div_p = (count_div == max_count) ? 1'b1 : 1'b0 ;
wire cler_trg_p = (count_trg == 10'd441 ) ? 1'b1 : 1'b0 ;
//トリガ生成用カウンタ
always@(posedge i_clk or i_rst_n)
begin
if(~i_rst_n) count_div <= 7'd0;
else if(cler_div_p) count_div <= 7'd0;
else count_div <= count_div + 7'd1;
end
//トリガ出力回数カウンタ
always@(posedge i_clk or i_rst_n)
begin
if(~i_rst_n) count_trg <= 9'd0;
else if(cler_trg_p) count_trg <= 9'd0;
else if(cler_div_p) count_trg <= count_trg + 9'd1;
else count_trg <= count_trg;
end
always@(posedge i_clk or i_rst_n)
begin
if(~i_rst_n) o_trg_p <= 1'd0;
else o_trg_p <= cler_div_p;
end
endmodule
//テストベンチ
module m_SAMPL_TRG_tb();
reg i_clk =0;
reg i_rst_n =0;
wire o_trg_p;
m_SAMPL_TRG m_SAMPL_TRG
(.i_clk (i_clk )
,.i_rst_n (i_rst_n )
,.o_trg_p (o_trg_p )
);
//クロック4MHz
always#125 i_clk = ~i_clk;
integer cnt=0;
//10ms毎のトリガで時刻とカウント数を表示
always@(posedge m_SAMPL_TRG.cler_trg_p)
begin
$display("10ms Triger = %t[ns] cnt = %d",$time,cnt);
end
//44.1kHzトリガの回数をカウント
always@(posedge o_trg_p)
begin
cnt = cnt +1;
end
//トリガ間隔のチェック
integer chk_time1;
integer chk_time2;
integer chk_time;
always@(posedge o_trg_p)
begin
chk_time1 <= $time ;
chk_time2 <= chk_time1 ;
if(cnt > 1)
begin
chk_time <= chk_time1 - chk_time2;
if( (chk_time > 22750) || (chk_time < 22500) )
begin
$display("Triger Error");
end
end
end
//
initial
begin
#50;
i_rst_n=1;
#100000050; //1秒で終了
$stop;
end
endmodule
***********************************************************
シミュレーションの結果は以下のとおり。
これで44.1kHzのサンプリングタイミングが作れました。
# 10ms Triger = 9999625[ns] cnt = 441
# 10ms Triger = 19999625[ns] cnt = 882
# 10ms Triger = 29999625[ns] cnt = 1323
# 10ms Triger = 39999625[ns] cnt = 1764
# 10ms Triger = 49999625[ns] cnt = 2205
# 10ms Triger = 59999625[ns] cnt = 2646
# 10ms Triger = 69999625[ns] cnt = 3087
# 10ms Triger = 79999625[ns] cnt = 3528
# 10ms Triger = 89999625[ns] cnt = 3969
# 10ms Triger = 99999625[ns] cnt = 4410



