feat: add FPGA raw jitter capture design with SPI register interface
This commit is contained in:
parent
3ee8a5c3db
commit
0332d8eb33
13 changed files with 936 additions and 2 deletions
43
fpga/rtl/ring_osc.v
Normal file
43
fpga/rtl/ring_osc.v
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Free-running ring oscillator built from LCELL buffers so synthesis keeps every stage.
|
||||
// Three evenly spaced taps are XORed into an "enhanced" output at three times the ring
|
||||
// frequency, which triples the chance that a sample lands on a jittery edge.
|
||||
module ring_osc #(
|
||||
parameter LENGTH = 12 // stages in the ring; exactly one of them inverts
|
||||
) (
|
||||
input wire enable, // low stops the ring (all stages settle high)
|
||||
output wire first_tap,
|
||||
output wire enhanced
|
||||
);
|
||||
|
||||
`ifdef SIM
|
||||
// Behavioural stand-in: independent taps toggling at random intervals, enough to
|
||||
// exercise the synchronous logic downstream. It has no physical meaning.
|
||||
reg [2:0] taps = 3'b000;
|
||||
always begin
|
||||
#(1 + {$random} % 7);
|
||||
if (enable) taps[{$random} % 3] = ~taps[{$random} % 3];
|
||||
else taps = 3'b111;
|
||||
end
|
||||
assign first_tap = taps[0];
|
||||
assign enhanced = ^taps;
|
||||
`else
|
||||
// No keep attribute here: each lcell is already one logic cell, and keep on these
|
||||
// nets makes Quartus insert a second cell per stage.
|
||||
wire [LENGTH-1:0] stage;
|
||||
|
||||
lcell inverting_stage (.in(~(stage[LENGTH-1] & enable)), .out(stage[0]));
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 1; i < LENGTH; i = i + 1) begin : delay_stage
|
||||
lcell buffer (.in(stage[i-1]), .out(stage[i]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
(* keep *) wire tap_xor = stage[0] ^ stage[LENGTH/3] ^ stage[(2*LENGTH)/3];
|
||||
|
||||
assign first_tap = stage[0];
|
||||
assign enhanced = tap_xor;
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
Loading…
Add table
Add a link
Reference in a new issue