49 lines
1.8 KiB
Verilog
49 lines
1.8 KiB
Verilog
`timescale 1ns/1ps
|
|
|
|
// =============================================================================
|
|
// RC model to convert sigma delta samples to Q1.15
|
|
// Models the RC circuit on the outside of the FPGA
|
|
// Uses: Yn+1 = Yn + (sd - Yn)*(1-exp(-T/RC))
|
|
// parameters:
|
|
// -- alpha_q15 : the 1-exp(-T/RC), defaults to R=3k3, C=220p and T=1/15MHz
|
|
// rounded to only use two bits (0b3b -> 0b00), the less
|
|
// bits the better
|
|
// inout:
|
|
// -- clk : input clock
|
|
// -- resetn : reset signal
|
|
// -- sd_sample : 1 bit sample output from sd sampler
|
|
// -- sample_q15 : output samples in q.15
|
|
// =============================================================================
|
|
module sigmadelta_rcmodel_q15 #(
|
|
parameter integer alpha_q15 = 16'sh0b00
|
|
)(
|
|
input wire clk,
|
|
input wire resetn,
|
|
input wire sd_sample,
|
|
output wire [15:0] sample_q15
|
|
);
|
|
reg signed [15:0] y_q15;
|
|
wire signed [15:0] sd_q15 = sd_sample ? 16'sh7fff : 16'sh0000;
|
|
wire signed [15:0] e_q15 = sd_q15 - y_q15;
|
|
// wire signed [31:0] prod_q30 = $signed(e_q15) * $signed(alpha_q15);
|
|
wire signed [31:0] prod_q30;
|
|
// Use shift-add algorithm for multiplication
|
|
mul_const_shiftadd #(.C($signed(alpha_q15))) alpha_times_e ($signed(e_q15), prod_q30);
|
|
wire signed [15:0] y_next_q15 = y_q15 + (prod_q30>>>15);
|
|
|
|
// clamp to [0, 0x7FFF] (keeps signal view tidy)
|
|
function signed [15:0] clamp01_q15(input signed [15:0] v);
|
|
if (v < 16'sd0000) clamp01_q15 = 16'sd0000;
|
|
else if (v > 16'sh7FFF) clamp01_q15 = 16'sh7FFF;
|
|
else clamp01_q15 = v;
|
|
endfunction
|
|
|
|
always @(posedge clk or negedge resetn) begin
|
|
if (!resetn) y_q15 <= 16'sd0000;
|
|
else y_q15 <= clamp01_q15(y_next_q15);
|
|
end
|
|
|
|
assign sample_q15 = y_q15;
|
|
|
|
endmodule
|