106 lines
3.3 KiB
Verilog
106 lines
3.3 KiB
Verilog
`timescale 1ns/1ps
|
|
|
|
module sigmadelta_sampler(
|
|
input wire clk,
|
|
input wire A,
|
|
input wire B,
|
|
output wire out
|
|
);
|
|
// ===== Tunable parameters =====
|
|
// Sine source (A input / P)
|
|
parameter real F_HZ = 2.0e3; // input sine frequency (1 kHz)
|
|
parameter real AMP = 1.5; // sine amplitude (V)
|
|
parameter real VCM = 1.65; // common-mode (V), centered in 0..3.3V
|
|
|
|
// Comparator behavior
|
|
parameter real VTH = 0.0; // threshold on (vp - vn)
|
|
parameter real VHYST = 0.05; // symmetric hysteresis half-width (V)
|
|
parameter integer ADD_HYST = 0; // 1 to enable hysteresis
|
|
|
|
// 1-bit DAC rails (feedback into RC)
|
|
parameter real VLOW = 0.0; // DAC 0 (V)
|
|
parameter real VHIGH = 3.3; // DAC 1 (V)
|
|
|
|
// RC filter (B input / N)
|
|
parameter real R_OHMS = 3300.0; // 3.3k
|
|
parameter real C_FARADS = 220e-12; // 220 pF
|
|
|
|
// Integration step (ties to `timescale`)
|
|
parameter integer TSTEP_NS = 10; // sim step in ns (choose << tau)
|
|
|
|
// ===== Internal state (simulation only) =====
|
|
real vp, vn; // comparator A/B inputs
|
|
real v_rc; // RC node voltage (== vn)
|
|
real v_dac; // DAC output voltage from O
|
|
real t_s; // time in seconds
|
|
real dt_s; // step in seconds
|
|
real tau_s; // R*C time constant in seconds
|
|
real two_pi;
|
|
reg q; // comparator latched output (pre-delay)
|
|
reg O;
|
|
reg sampler;
|
|
|
|
initial sampler <= 1'b0;
|
|
always @(posedge clk) begin
|
|
sampler <= O;
|
|
end
|
|
assign out = sampler;
|
|
|
|
|
|
// Helper task: update comparator with optional hysteresis
|
|
task automatic comp_update;
|
|
real diff;
|
|
begin
|
|
diff = (vp - vn);
|
|
|
|
if (ADD_HYST != 0) begin
|
|
// simple symmetric hysteresis around VTH
|
|
if (q && (diff < (VTH - VHYST))) q = 1'b0;
|
|
else if (!q && (diff > (VTH + VHYST))) q = 1'b1;
|
|
// else hold
|
|
end else begin
|
|
q = (diff > VTH) ? 1'b1 : 1'b0;
|
|
end
|
|
end
|
|
endtask
|
|
|
|
initial begin
|
|
// Init constants
|
|
two_pi = 6.283185307179586;
|
|
tau_s = R_OHMS * C_FARADS; // ~7.26e-7 s
|
|
dt_s = TSTEP_NS * 1.0e-9;
|
|
|
|
// Init states
|
|
t_s = 0.0;
|
|
q = 1'b0; // start low
|
|
O = 1'b0;
|
|
v_dac= VLOW;
|
|
v_rc = (VHIGH + VLOW)/2.0; // start mid-rail to reduce start-up transient
|
|
vn = v_rc;
|
|
vp = VCM;
|
|
|
|
// Main sim loop
|
|
forever begin
|
|
#(TSTEP_NS); // advance discrete time step
|
|
t_s = t_s + dt_s;
|
|
|
|
// 1) Update DAC from previous comparator state
|
|
v_dac = sampler ? VHIGH : VLOW;
|
|
|
|
// 2) RC low-pass driven by DAC: Euler step
|
|
// dv = (v_dac - v_rc) * dt/tau
|
|
v_rc = v_rc + (v_dac - v_rc) * (dt_s / tau_s);
|
|
vn = v_rc;
|
|
|
|
// 3) Input sine on A
|
|
vp = VCM + AMP * $sin(two_pi * F_HZ * t_s);
|
|
|
|
// 4) Comparator decision (with optional hysteresis)
|
|
comp_update();
|
|
|
|
// 5) Output with propagation delay
|
|
O = q;
|
|
end
|
|
end
|
|
|
|
endmodule |