10
10
// 8/11 for SSRF
11
11
// 9/13 for Argonne RIA
12
12
//
13
- // The phase generation algorithm
14
- // 0. The phase increments for dds are generated using a technique described
15
- // in these 2 places:
16
- // Section: PROGRAMMABLE MODULUS MODE in:
17
- // https://www.analog.com/media/en/technical-documentation/data-sheets/ad9915.pdf
18
- // (AND) https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
19
- // Basically, increment the phase step at a coarse resolution, accumulate the
20
- // error on the side, and when that error accumulates to the lowest bit of
21
- // the coarse counter, add an extra 1 to the following phase step.
22
- // 1. phase_step_h is the coarse (20 bit) integer truncated phase increment for
23
- // the cordic. There is a 1-bit increment of phase that comes from
24
- // accumulating residue phase.
25
- // 2. This residue phase is accumulating in steps of phase_step_l, in a 12-bit
26
- // counter.
27
- // 3. However, there will be an extra residue even for this 12-bit counter,
28
- // which is the modulus, and this added as an offset when the counter crosses 0
29
-
30
- // 12-bit modulo supports largest known periodicity in a suggested LLRF system,
31
- // 1427 for JLab. For more normal periodicities, use a multiple to get finer
32
- // granularity.
33
- // Note that the downloaded modulo control is the 2's complement of the
34
- // mathematical modulus.
35
- // e.g., SSRF IF/F_s ratio 8/11, use
36
- // modulo = 4096 - 372*11 = 4
37
- // phase_step_h = 2^20*8/11 = 762600
38
- // phase_step_l = (2^20*8%11)*372 = 2976
39
- // e.g., Argonne RIA test IF/F_s ratio 9/13, use
40
- // modulo = 4096 - 315*13 = 1
41
- // phase_step_h = 2^20*9/13 = 725937
42
- // phase_step_l = (2^20*9%13)*315 = 945
43
-
44
- // TODO:
45
- // Potentially, isolate phase generation into a separate module.
46
- // Haha, turns out there is ph_acc.v (We should USE it).
47
13
// Synthesizes to ??? slices at ??? MHz in XC3Sxxx-4 using XST-??
48
14
//
49
15
@@ -65,19 +31,18 @@ parameter lo_amp = 18'd79590;
65
31
// Sometimes we cheat and use slightly smaller values than above,
66
32
// to make other computations fit better.
67
33
34
+ wire [18 :0 ] phase_acc;
35
+ ph_acc ph_acc_i (
36
+ .clk(clk), .reset(reset), .en(1'b1 ), // input
37
+ .phase_acc(phase_acc), // output [18:0]
38
+ .phase_step_h(phase_step_h), // input [19:0]
39
+ .phase_step_l(phase_step_l), // input [11:0]
40
+ .modulo(modulo) // input [11:0]
41
+ );
68
42
// See rot_dds_config
69
43
70
- reg carry= 0 , reset_d= 0 ;
71
- reg [19 :0 ] phase_h= 0 , phase_step_hp= 0 ;
72
- reg [11 :0 ] phase_l= 0 ;
73
- always @(posedge clk) begin
74
- {carry, phase_l} <= reset ? 13'b0 : ((carry ? modulo : 12'b0 ) + phase_l + phase_step_l);
75
- phase_step_hp <= phase_step_h;
76
- reset_d <= reset;
77
- phase_h <= reset_d ? 20'b0 : (phase_h + phase_step_hp + carry);
78
- end
79
44
cordicg_b22 #(.nstg(20 ), .width(18 ), .def_op(0 )) trig (.clk(clk), .opin(2'b00 ),
80
- .xin(lo_amp), .yin(18'd0 ), .phasein(phase_h[ 19 : 1 ] ),
45
+ .xin(lo_amp), .yin(18'd0 ), .phasein(phase_acc ),
81
46
// 2^17/1.64676 = 79594, use a smaller value to keep CORDIC round-off
82
47
// from overflowing the output
83
48
.xout(cosa), .yout(sina));
0 commit comments