IP CatalogのCICフィルタも自作CICフィルタも入力rateの値で間引き率を動的に変更できます。ただし平均の分母が常に最高間引き率固定なので、最高間引き率より小さい間引き率のときは出力データが小さくなってしまいます。段数が多いとべき乗で小さくなってしまいます。
AM/FMラジオの間引き率は、AM 1/1024、FM 1/64にしているので、1段のフィルタでもFMのときのCICフィルタの出力はAMのときの1/16になります。2段、3段にすると小さくなりすぎて復調できません。
そこで、間引き率で出力レベルが変化しないCICフィルタを作ってみました。
`timescale 1ns/1ns module MyCIC #( parameter NUM_STAGES = 3, parameter MAX_RATE_WIDTH = 12, parameter IN_WIDTH = 19, parameter OUT_WIDTH = 19 ) ( input wire clk, input wire reset_n, input wire [MAX_RATE_WIDTH:0] rate, input wire signed [IN_WIDTH-1:0] in_data, output wire in_ready, input wire in_valid, input wire [1:0] in_error, output reg signed [OUT_WIDTH-1:0] out_data, input wire out_ready, output reg out_valid, output wire [1:0] out_error ); localparam WIDTH = MAX_RATE_WIDTH * NUM_STAGES + IN_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 [MAX_RATE_WIDTH:0] count; reg [3:0] rate_width; 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 = 16384) rate_width = 8192) rate_width = 4096) rate_width = 2048) rate_width = 1024) rate_width = 512) rate_width = 256) rate_width = 128) rate_width = 64) rate_width = 32) rate_width = 16) rate_width = 8) rate_width = 4) rate_width = 2) rate_width = 1) rate_width >> (rate_width * NUM_STAGES + IN_WIDTH - OUT_WIDTH); end end end endmodule