Added decimation

This commit is contained in:
Joppe Blondel
2025-10-19 17:19:08 +02:00
parent 771fa58769
commit 165faefa59
3 changed files with 85 additions and 2 deletions

View File

@@ -0,0 +1,74 @@
`timescale 1ns/1ps
// =============================================================================
// Decimator by R
// Reduces the effective sample rate by an integer factor R by selecting every
// R-th input sample. Generates a one-cycle 'out_valid' pulse each time a new
// decimated sample is produced.
//
// Implements:
// For each valid input sample:
// if (count == R-1):
// count <= 0
// out_q15 <= in_q15
// out_valid <= 1
// else:
// count <= count + 1
//
// parameters:
// -- R : integer decimation factor (e.g., 400)
// output sample rate = input rate / R
// -- CNT_W : counter bit width, must satisfy 2^CNT_W > R
//
// inout:
// -- clk : input clock (same rate as 'in_valid')
// -- rst_n : active-low synchronous reset
// -- in_valid : input data strobe; assert 1'b1 if input is always valid
// -- in_q15 : signed 16-bit Q1.15 input sample (full-rate)
// -- out_valid : single-cycle pulse every R samples (decimated rate strobe)
// -- out_q15 : signed 16-bit Q1.15 output sample (decimated stream)
//
// Notes:
// - This module performs *pure downsampling* (sample selection only).
// It does not include any anti-alias filtering; high-frequency content
// above the new Nyquist limit (Fs_out / 2) will alias into the baseband.
// - For most applications, an anti-alias low-pass filter such as
// lpf_iir_q15 or a FIR stage should precede this decimator.
// - The output sample rate is given by:
// Fs_out = Fs_in / R
// - Typical usage: interface between high-rate sigma-delta or oversampled
// data streams and lower-rate processing stages.
// =============================================================================
module decimate_by_r_q15 #(
parameter integer R = 400, // decimation factor
parameter integer CNT_W = 10 // width so that 2^CNT_W > R (e.g., 10 for 750)
)(
input wire clk,
input wire rst_n,
input wire in_valid, // assert 1'b1 if always valid
input wire signed [15:0] in_q15, // Q1.15 sample at full rate
output reg out_valid, // 1-cycle pulse every R samples
output reg signed [15:0] out_q15 // Q1.15 sample at decimated rate
);
reg [CNT_W-1:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= {CNT_W{1'b0}};
out_valid <= 1'b0;
out_q15 <= 16'sd0;
end else begin
out_valid <= 1'b0;
if (in_valid) begin
if (cnt == R-1) begin
cnt <= {CNT_W{1'b0}};
out_q15 <= in_q15;
out_valid <= 1'b1;
end else begin
cnt <= cnt + 1'b1;
end
end
end
end
endmodule