ΔΣ-ADC 実験編 その17 CICフィルタ詳細 1.Lattice
Diamondの BKM checkとは? input clk; ////////////////////////////////////// //use myPLL
instance assign neg_q=~Qinner; always@(posedge clkop)
begin endmodule reg [5:0]count=0; end /* module accum(clk,VDA,cy_out); parameter DATA_WIDTH2=18; ///// internal variables
//////// assign cy_out= cy; always @(posedge clk) begin endmodule
1/128 decimation
using 1st order CIC filter
素晴らしい機能です。
たとえば
CICフィルタの積分器のビット数を、適当に、仮に 41bitに設定したとします。(入力は、signed 18bit)
BKM checkすると
適当に設定した bit数が、
「22bitまで、削れる」と、指示してくれるのです、 凄いで。
2.BKM checkをするには
HDL言語による記述が、出来上がったら
1. Synthesize Design を行います。
2. Generate
Hierachy
3. run BKM check
4. view Warning
このBKM checkは、最終の JEDEC fileを生成する前にも、必ず行いましょう。
余分なbit数を調べるために、そして、最終的に出力される波形が正しいかどうかをcheckするには
Functional
simulationも行ったほうが、いいです。
3.Functional
simulationを行うには
先ず、HDL記述の何処かに
///////////////////////////////////////////////////
PUR PUR_INST
(.PUR (RST_PULSE));
GSR GSR_INST (.GSR
(GSRNET));
///////////////////////////////////////////////////
を、挿入します。
次に、menuから Tools ->Simulation
Wizard
後は、全部 return keyを押します。
4.CIC filter 1段で調べてみます。
先ほど、ynを 41bitに設定しました。
これを観察すると
確かに、bit数が、余っているようです。
どうやら、24bit目が、符号bitの様子です。
そんなんで、bit数を調整して
やれやれと、安心していると
いっ! BKM checckは、「まだ 削れる」と、言っています。
で、お教えに従いまして
うーむ、最終出力は、正しい。
BKMは、非常に強力な武器で、あります、御礼。
結局
[22:0]を主体に、最終決定しました。
CIC filter 1段では
勿論、 Holdでも、正常に終了します。
で、JEDEC fileを生成し、
CIC filter1段で、1/32
decimationを、行いました。
この結果は、あくまでも
1bit delta sigma
bandpass ADCの 1bit出力が、入力だという、条件です。
以下は、CIC filter
1段の verilog記述全文です。
module myADC( clk,D,neg_q,q );
input D;
output
neg_q;
output q;
wire
clkop;
wire lock;
reg
Qinner=0;
reg [9:0]theta=0;
wire signed[17:0]sine;
wire
signed[17:0]mixed_sin;
wire signed[22:0]result_wire;
wire [22:0]result_wire_unsigned;
/*
////////////////////////////////////////////////////
PUR PUR_INST
(.PUR (RST_PULSE));
GSR GSR_INST (.GSR
(GSRNET));
///////////////////////////////////////////////////
*/
myPLL myPLL(.CLK(clk),.CLKOP(clkop),.LOCK(lock));
sin sin(.Clock(clk),
.ClkEn(1'b1), .Reset(1'b0), .Theta(theta),
.Sine(sine));
cic_filter cic(clkop,mixed_sin,result_wire);
assign mixed_sin=(Qinner ?
sine : -sine);
assign
result_wire_unsigned={~result_wire[22],result_wire[22-1:0]};
accum #(23) accum(clkop,result_wire_unsigned,q);
Qinner =D;
end
always@(posedge clk)
begin
theta=theta+64;
end
module
cic_filter(clk,data_input,data_out);
input clk;
input signed[17:0]data_input;
output signed[22:0]data_out;
reg signed[22:0]z[1:0];
reg signed[22:0]yn=0;
reg signed[22:0]yn_1=0;
reg signed[22:0]result=0;
assign
data_out=result;
always@(posedge clk)
begin
//scaling factor :
MOVING_AVEは、省略する。
//integrator
yn=yn_1+data_input;
yn_1=yn;
count=count+1;
if(count==32)
begin //decimation
ratio=1/32
z[1]=z[0];
z[0]=yn;
count=0;
//differentiator
result=z[0]-z[1];
end
initial
begin
z[0]<=0;
end
*/
endmodule
input
clk;
input
[DATA_WIDTH2-1:0] VDA;
output cy_out;
reg [DATA_WIDTH2-1:0] R=0;
reg cy=0;
{cy,R} <=R+
VDA;
end
H.22.9.2