ADC_DeltaSigmaADCOrder2_DecimationFilter : A decimation filter for a second-order delta-sigma ADC
A decimation filter converts a single-bit digital input stream of in
to a multi-bit digital output stream of out
via decimation and filtering. In particular, this decimation filter model converts a 1-bit stream of in
to a 21-bit stream of out
with a decimation factor of 16. The input in
and output out
are updated at each rising edge of the input clock iclk
and the output clock oclk
, respectively. The ratio between the iclk
frequency and oclk
frequency determines the decimation factor, which is 16.
This decimation filter model describes a cascaded integrator-comb (CIC) filter in Verilog, consisting of a set of 5 accumulators, a down sampler, and a set of 5 differentiators. The more details on the CIC filter can be found at this link (https://en.wikipedia.org/wiki/Cascaded_integrator%E2%80%93comb_filter).
module ADC_DeltaSigmaADCOrder2_DecimationFilter (in, iclk, out, oclk, gl_reset); input in; // 1-bit input input iclk; // input clock output [20:0] out; // 21-bit output output oclk; // output clock input gl_reset; // global reset reg [20:0] out; // output register wire oclk; // output clock wire aclk; // internal clock for accumulators wire dclk; // internal clock for differentiators reg [3:0] div; // clock divider reg in_reg; // input register wire [20:0] a1, a2, a3, a4, a5; // accumulators reg [20:0] s0, s1; // decimators wire [20:0] d1, d2, d3, d4, d5; // differentiator // internal clock assign aclk = ~iclk; // input register always @(posedge aclk, posedge gl_reset) begin if (gl_reset) in_reg <= 0; else in_reg <= in; end // accumulator stages sinc_acc acc1({{20{1'b0}}, in_reg}, a1, aclk, gl_reset); sinc_acc acc2(a1, a2, aclk, gl_reset); sinc_acc acc3(a2, a3, aclk, gl_reset); sinc_acc acc4(a3, a4, aclk, gl_reset); sinc_acc acc5(a4, a5, aclk, gl_reset); // decimator always @(posedge aclk, posedge gl_reset) begin if (gl_reset) div <= 0; else div <= div + 1; end always @(posedge aclk, posedge gl_reset) begin if (gl_reset) s0 <= 0; else if (div == {4{1'b1}}) s0 <= a5; end assign dclk = div[3]; always @(posedge dclk, posedge gl_reset) begin if (gl_reset) s1 <= 0; else s1 <= s0; end // differentiator stages sinc_diff diff1(s1, d1, dclk, gl_reset); sinc_diff diff2(d1, d2, dclk, gl_reset); sinc_diff diff3(d2, d3, dclk, gl_reset); sinc_diff diff4(d3, d4, dclk, gl_reset); sinc_diff diff5(d4, d5, dclk, gl_reset); // output register always @(posedge dclk, posedge gl_reset) begin if (gl_reset) out <= 0; else out <= d5; end // clocks used by the subsequent FIR filter assign oclk = ~dclk; // indicates the center of the data eye endmodule //////////////////////////////////////////////////////////////////////////////// // // Block Name : sinc_acc.v // Block Description : // accumulator used in sinc^k decimator // //////////////////////////////////////////////////////////////////////////////// module sinc_acc(in, out, clk, gl_reset); input [20:0] in; // 21-bit input input clk; // input clock input gl_reset; // global reset output [20:0] out; // 21-bit output wire [20:0] out; reg [20:0] acc; // accumulator always @(posedge clk, posedge gl_reset) begin if (gl_reset) acc <= 0; else acc <= out; end assign out = in + acc; endmodule //////////////////////////////////////////////////////////////////////////////// // // Block Name : sinc_diff.v // Block Description : // differentiator used in sinc^k decimator // //////////////////////////////////////////////////////////////////////////////// module sinc_diff(in, out, clk, gl_reset); input [20:0] in; // 21-bit input output [20:0] out; // 21-bit output input clk; // input clock input gl_reset; // global reset wire [20:0] out; reg [20:0] prev; always @(posedge clk, posedge gl_reset) begin if (gl_reset) prev <= 0; else prev <= in; end assign out = in - prev; endmodule
Input/Output Terminals
Name | I/O | Type | Description |
in | input | wire | 1-bit input |
iclk | input | wire | input clock |
out[20:0] | output | wire | 21-bit output |
oclk | output | wire | output clock |
gl_reset | input | wire | global reset |