ΔΣーADC実験編 その28 CIC filter ->
fir filter 詳細 1.やっと、補償フィルタが、できました。 /// DCM ////////////////////////////////// wire signed[6:0]douta; cic_filter cic(CLK0_OUT,q_inter,data_out_signed,devided_clk);//1/64
decimation my_fir my_fir(CLK0_OUT,data_out_signed,fir_result_signed); assign fir_result_unsigned=fir_result_signed+24'h7f_ffff; always @(posedge CLK0_OUT) begin endmodule
1/64 decimation後に、fir LPFを通したsimulation 結果
ROM,
Single Port RAMを使った fir filter
FIR Compilerを使った DAfilter
LUTの消費量を抑える事ができて、ホッとしています (^_^;;
私みたいに、物忘れの激しい人間は、メモして置くのが一番ですね。
で、 以降に、製作過程を記述しておきます。
2.戦略
CICフィルタにより、1/64 decimationを行ったのですから
decimatedクロック(devided_clk)は、元クロック(CLK0_OUT 50MHz)に対して、64倍の長さの周期を持っています。
devided_clk 1周期の間に、fir
ilterの計算を行えば、OKなわけです。
で、
このdevided_clkの1周期の間に、CLK0_OUTは64回振動しますから、これを利用して
ROMの読み込み及び、Single
port RAMへの書き込みと読み出しを、行います。
3.ROMの読み出しタイミング
まず、ROMを作ります。
ROMに書き込む、fir filterの係数は、64個と、1つ増やして置き、その値は ゼロ。
テストプログラムは
タイミングは
negedge clkで設定しておくと
すぐ次のposedgeで、そのアドレスのデータを、吐き出してくれます。
4.Sigle Port RAMへの書き込み及び読み出し
Single
Port RAMを作ります。
HDL記述は
擬似inputデータも作っています。
ROMの場合と同じく、negedgeで設定すると
すぐ次のposedgeで、書き込んだデータが出力されます。(write
first mode)
5.Single port
RAMへの書き込みの工夫
最新のデータを、fir
filterの最初のROMデータ、即ちcoef(0)=-3と掛け合わせなければなりませんから
新たに、count(カウンター)、wr_addr(write_address),addra(read_address)の変数を設定して、
Single
Port RAMのデータ出力が、そういう並びになるように、HDL記述を書き換えます。
擬似のinputデータ(input_data_array)は、見やすいように、addraに 10 をプラスしたものに設定しています。
そうすっと、
6.ROMデータとSingle Port
RAM出力のすり合わせ
次に、以下のHDL記述にて、テストベンチi風のHDL記述を行います。
今回は、posedgeで、データを拾い出します。
このテストベンチは、ISE付属のISim simulatorでは、普通のmoduleとして記述します、便利。
次に、擬似データをテストベンチmoduleに記述して、Single Port
RAM moduleの擬似データを消します。
そして、擬似データと fir filterの係数の積を蓄積する accumlatorである、accum
を設定します。
fir_result出力に、convolution結果を書き込むタイミングは、countが63の時に、なります。
よさげですね。
最後は、擬似データを消して、本来のHDL記述に組み込みます。
//////////////////////////////////////////////////////////////////////////////////
//
Company:
// Engineer:
//
// Create Date:
15:11:40 11/06/2010
// Design Name:
// Module
Name: myADC
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
//
Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module
myADC (clk,D,neg_q,q);
input clk;
input
D;
output neg_q;
output q;
reg Qinner = 0;
wire q_inter;
wire
RST_IN;
wire CLKFX_OUT;
wire
CLKIN_IBUFG_OUT;
wire CLK0_OUT;
wire
LOCKED_OUT;
//// fir
//////////////////////////////////////
wire signed[23:0]fir_result_signed;
wire [23:0]fir_result_unsigned;
////
CIC////////
wire signed[6:0]data_out_signed;
wire [6:0]data_out_unsigned;
wire devided_clk;
myDCM instance_name (
.CLKIN_IN(clk),
.RST_IN(RST_IN),
.CLKFX_OUT(CLKFX_OUT),
.CLKIN_IBUFG_OUT(CLKIN_IBUFG_OUT),
.CLK0_OUT(CLK0_OUT),
.LOCKED_OUT(LOCKED_OUT)
);
//need
for 1bit ADC
assign neg_q = ~Qinner;
// This is not a
correct way to multiply 1bit signals,but works good.
assign q_inter = CLKFX_OUT ~^ Qinner; //multiply 1bit
singnals : CLKFX_OUT=6.818MHz 1bit sgnal ,D=7MHz 1bit
signal
accum #(24)
accum2(CLK0_OUT,fir_result_unsigned,q);
Qinner =
D;
end
それらしい.... 拡大
なんとか、思い出せました (^_^;;
H.23.02.03