Added decimator
This commit is contained in:
@@ -5,13 +5,14 @@ module sampling(
|
|||||||
input wire adc_B,
|
input wire adc_B,
|
||||||
output wire adc_O,
|
output wire adc_O,
|
||||||
|
|
||||||
input wire clk,
|
input wire clk_15,
|
||||||
|
input wire clk_120,
|
||||||
input wire reset_n
|
input wire reset_n
|
||||||
);
|
);
|
||||||
wire sigmadelta_sample;
|
wire sigmadelta_sample;
|
||||||
|
|
||||||
sigmadelta_sampler m_sdsampler(
|
sigmadelta_sampler m_sdsampler(
|
||||||
.clk(clk),
|
.clk(clk_15),
|
||||||
.A(adc_A),
|
.A(adc_A),
|
||||||
.B(adc_B),
|
.B(adc_B),
|
||||||
.out(sigmadelta_sample)
|
.out(sigmadelta_sample)
|
||||||
@@ -34,10 +35,99 @@ module sampling(
|
|||||||
else clamp01_q15 = v;
|
else clamp01_q15 = v;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
always @(posedge clk or negedge reset_n) begin
|
always @(posedge clk_15 or negedge reset_n) begin
|
||||||
if (!reset_n) y_q15 <= 16'sd0000;
|
if (!reset_n) y_q15 <= 16'sd0000;
|
||||||
else y_q15 <= clamp01_q15(y_next_q15);
|
else y_q15 <= clamp01_q15(y_next_q15);
|
||||||
end
|
end
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
|
wire signed [15:0] lpfed_q15;
|
||||||
|
lpf_iir_q15 #(.K(7)) m_lpf (
|
||||||
|
.clk(clk_15),
|
||||||
|
.rst_n(reset_n),
|
||||||
|
.x_q15(y_next_q15),
|
||||||
|
.y_q15(lpfed_q15)
|
||||||
|
);
|
||||||
|
|
||||||
|
wire signed [15:0] decimated_q15;
|
||||||
|
decimate_by_r #(.R(375)) m_decimator (
|
||||||
|
.clk(clk_15),
|
||||||
|
.rst_n(reset_n),
|
||||||
|
.in_valid(1'b1),
|
||||||
|
.in_q15(lpfed_q15),
|
||||||
|
.out_valid(),
|
||||||
|
.out_q15(decimated_q15)
|
||||||
|
);
|
||||||
|
|
||||||
|
// decimated_q15 + out_valid @ 40KHz
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Simple 1-pole IIR LPF, Q1.15 in/out, multiplier-less (alpha = 1/2^K)
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
module lpf_iir_q15 #(
|
||||||
|
parameter integer K = 10 // try 8..12; bigger = more smoothing
|
||||||
|
)(
|
||||||
|
input wire clk,
|
||||||
|
input wire rst_n,
|
||||||
|
input wire signed [15:0] x_q15, // Q1.15 input (e.g., 0..0x7FFF)
|
||||||
|
output reg signed [15:0] y_q15 // Q1.15 output
|
||||||
|
);
|
||||||
|
wire signed [15:0] e_q15 = x_q15 - y_q15;
|
||||||
|
wire signed [15:0] delta_q15 = e_q15 >>> K; // arithmetic shift
|
||||||
|
wire signed [15:0] y_next = y_q15 + delta_q15;
|
||||||
|
|
||||||
|
// clamp to [0, 0x7FFF] (handy if your signal is non-negative)
|
||||||
|
function signed [15:0] clamp01;
|
||||||
|
input signed [15:0] v;
|
||||||
|
begin
|
||||||
|
if (v < 16'sd0) clamp01 = 16'sd0;
|
||||||
|
else if (v > 16'sh7FFF) clamp01 = 16'sh7FFF;
|
||||||
|
else clamp01 = v;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always @(posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) y_q15 <= 16'sd0;
|
||||||
|
else y_q15 <= clamp01(y_next);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
// Decimate-by-R: passes through one sample every R input clocks
|
||||||
|
// No $clog2 used; set CNT_W wide enough for your R.
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
module decimate_by_r #(
|
||||||
|
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
|
endmodule
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
module sampling_tb;
|
module sampling_tb;
|
||||||
reg clk;
|
reg clk_15;
|
||||||
|
reg clk_120;
|
||||||
reg reset_n;
|
reg reset_n;
|
||||||
|
|
||||||
sampling m_sampling(
|
sampling m_sampling(
|
||||||
.clk(clk),
|
.clk_15(clk_15),
|
||||||
|
.clk_120(clk_120),
|
||||||
.reset_n(reset_n)
|
.reset_n(reset_n)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -13,15 +15,16 @@ module sampling_tb;
|
|||||||
$dumpfile("sampling_tb.vcd");
|
$dumpfile("sampling_tb.vcd");
|
||||||
$dumpvars (0, sampling_tb);
|
$dumpvars (0, sampling_tb);
|
||||||
|
|
||||||
clk <= 1'b0;
|
clk_15 <= 1'b0;
|
||||||
|
clk_120 <= 1'b0;
|
||||||
reset_n <= 1'b0;
|
reset_n <= 1'b0;
|
||||||
#50 reset_n <= 1'b1;
|
#50 reset_n <= 1'b1;
|
||||||
|
|
||||||
#1000000
|
#2000000
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
//15 MHz clock
|
always #(500/15) clk_15 = ~clk_15;
|
||||||
always #33.33 clk = ~clk;
|
always #(500/120) clk_120 = ~clk_120;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@@ -8,7 +8,7 @@ module sigmadelta_sampler(
|
|||||||
);
|
);
|
||||||
// ===== Tunable parameters =====
|
// ===== Tunable parameters =====
|
||||||
// Sine source (A input / P)
|
// Sine source (A input / P)
|
||||||
parameter real F_HZ = 2.0e3; // input sine frequency (1 kHz)
|
parameter real F_HZ = 1.5e3; // input sine frequency (1 kHz)
|
||||||
parameter real AMP = 1.5; // sine amplitude (V)
|
parameter real AMP = 1.5; // sine amplitude (V)
|
||||||
parameter real VCM = 1.65; // common-mode (V), centered in 0..3.3V
|
parameter real VCM = 1.65; // common-mode (V), centered in 0..3.3V
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user