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 |