FPGA SDR(12)自作CICフィルタ
2019/03/06 追記:レート固定に戻しました。
2018/07/29 追記:パラメータを変更しました。
2018/07/05 追記:段数が増えると出力レベルが下がる不具合を直しました。
IP CatalogにあるCICフィルタは評価版なのでダウンロードケーブルを接続した状態でのみ使うことができます。Verilogの文法を勉強してCICフィルタを自作してみました。for文を初めて使いましたが便利です。入出力はIP CatalogにあるCICフィルタに合わせています。
MegaWizardのCICフィルタの生成が途中で止まってしまうEP2C5T144でもこの自作フィルタなら使用できます。
`timescale 1ns/1ns module MyCIC #( parameter NUM_STAGES = 4, parameter RATE = 24, parameter RATE_WIDTH = 5, // ceil(log2(RATE)) parameter SCALE_WIDTH = 19, // ceil(log2(RATE) * NUM_STAGES) parameter DATA_WIDTH = 19 ) ( input wire clk, input wire reset_n, input wire [1:0] in_error, input wire in_valid, output wire in_ready, input wire signed [DATA_WIDTH-1:0] in_data, output reg signed [DATA_WIDTH-1:0] out_data, output wire [1:0] out_error, output reg out_valid, input wire out_ready ); localparam WIDTH = SCALE_WIDTH + DATA_WIDTH; integer i; reg signed [WIDTH-1:0] integ [0:NUM_STAGES]; reg signed [WIDTH-1:0] diff [0:NUM_STAGES]; reg signed [WIDTH-1:0] diff_d [0:NUM_STAGES]; reg [RATE_WIDTH-1:0] count; reg next_out_valid; assign in_ready = 1'b1; assign out_error = 2'b00; always @(posedge clk) begin if (~reset_n) begin for (i = 1; i <= NUM_STAGES; i = i + 1) begin integ[i] <= 0; end diff[1] <= 0; end else begin integ[1] <= in_data + integ[1]; for (i = 2; i <= NUM_STAGES; i = i + 1) begin integ[i] <= integ[i-1] + integ[i]; end diff[1] <= integ[NUM_STAGES-1] + integ[NUM_STAGES]; end end always @(posedge clk) begin if (~reset_n) begin count <= 0; next_out_valid <= 1'b1; end else begin if (count == RATE - 1) begin count <= 0; next_out_valid <= 1'b1; end else begin count <= count + 1; next_out_valid <= 1'b0; end end end always @(posedge clk) begin out_valid <= next_out_valid; if (~reset_n) begin for (i = 1; i <= NUM_STAGES; i = i + 1) begin diff_d[i] <= 0; end for (i = 2; i <= NUM_STAGES; i = i + 1) begin diff[i] <= 0; end out_data <= 0; end else begin if (next_out_valid) begin for (i = 1; i <= NUM_STAGES; i = i + 1) begin diff_d[i] <= diff[i]; end for (i = 2; i <= NUM_STAGES; i = i + 1) begin diff[i] <= diff[i-1] - diff_d[i-1]; end out_data <= (diff[NUM_STAGES] - diff_d[NUM_STAGES]) >>> SCALE_WIDTH; end end end endmodule
IP CatalogにあるCICフィルタは cic の代わりに自作CICフィルタ MyCIC を使うことができます。
cic cic_inst_i ( ... ); cic cic_inst_q ( ... );
MyCIC cic_inst_i ( ... ); MyCIC cic_inst_q ( ... );
一度評価版のIPを追加したQuartusプロジェクトは評価版のIPを削除してもダウンロード状態でしか動作しません。自作CICフィルタと自作NCOを使ってプロジェクトを作り直す必要があります。