Skip to content

Commit 3707c9c

Browse files
committed
Added documentation and out of how much a dynamic phase shift occurs for all clocks per pulse.
1 parent 541e398 commit 3707c9c

File tree

1 file changed

+74
-4
lines changed

1 file changed

+74
-4
lines changed

libtrellis/tools/ecppll.cpp

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct secondary_params{
5454

5555
float freq;
5656
float phase;
57+
float phase_vco_step;
58+
float phase_div_step;
5759
};
5860

5961
struct pll_params{
@@ -62,6 +64,10 @@ struct pll_params{
6264
int feedback_div;
6365
int output_div;
6466
int primary_cphase;
67+
int primary_fphase;
68+
float primary_phase_vco_step;
69+
float primary_phase_div_step;
70+
6571
string clkin_name;
6672
string clkout0_name;
6773
int dynamic;
@@ -85,6 +91,8 @@ struct pll_params{
8591
}
8692
};
8793

94+
float calc_vco_phase_step(int fphase, int div);
95+
float calc_div_phase_step(int cphase, int div);
8896
void calc_pll_params(pll_params &params, float input, float output);
8997
void calc_pll_params_highres(pll_params &params, float input, float output);
9098
void generate_secondary_output(pll_params &params, int channel, string name, float frequency, float phase);
@@ -245,22 +253,38 @@ int main(int argc, char** argv){
245253
cout << "Feedback divisor: " << params.feedback_div << endl;
246254
cout << "clkout0 divisor: " << params.output_div << "" << endl;
247255
cout << "clkout0 frequency: " << params.fout << " MHz" << endl;
256+
if(params.dynamic){
257+
cout << "clkout0 vco step: " << params.primary_phase_vco_step << " degrees" << endl;
258+
cout << "clkout0 div step: " << params.primary_phase_div_step << " degrees" << endl;
259+
}
248260
if(params.secondary[0].enabled){
249261
cout << "clkout1 divisor: " << params.secondary[0].div << endl;
250262
cout << "clkout1 frequency: " << params.secondary[0].freq << " MHz" << endl;
251263
cout << "clkout1 phase shift: " << params.secondary[0].phase << " degrees" << endl;
264+
if(params.dynamic){
265+
cout << "clkout1 vco step: " << params.secondary[0].phase_vco_step << " degrees" << endl;
266+
cout << "clkout1 div step: " << params.secondary[0].phase_div_step << " degrees" << endl;
267+
}
252268
}
253269
if(params.secondary[1].enabled){
254270
cout << "clkout2 divisor: " << params.secondary[1].div << endl;
255271
cout << "clkout2 frequency: " << params.secondary[1].freq << " MHz" << endl;
256272
cout << "clkout2 phase shift: " << params.secondary[1].phase << " degrees" << endl;
273+
if(params.dynamic){
274+
cout << "clkout2 vco step: " << params.secondary[1].phase_vco_step << " degrees" << endl;
275+
cout << "clkout2 div step: " << params.secondary[1].phase_div_step << " degrees" << endl;
276+
}
257277
}
258278
if(params.secondary[2].enabled){
259279
cout << "clkout3 divisor: " << params.secondary[2].div << endl;
260280
cout << "clkout3 frequency: " << params.secondary[2].freq << " MHz" << endl;
261281
cout << "clkout3 phase shift: " << params.secondary[2].phase << " degrees" << endl;
282+
if(params.dynamic){
283+
cout << "clkout3 vco step: " << params.secondary[2].phase_vco_step << " degrees" << endl;
284+
cout << "clkout3 div step: " << params.secondary[2].phase_div_step << " degrees" << endl;
285+
}
262286
}
263-
cout << "VCO frequency: " << params.fvco << endl;
287+
cout << "VCO frequency: " << params.fvco << " Mhz" << endl;
264288
if(vm.count("file")){
265289
ofstream f;
266290
f.open(vm["file"].as<string>().c_str());
@@ -269,6 +293,14 @@ int main(int argc, char** argv){
269293
}
270294
}
271295

296+
float calc_vco_phase_step(int fphase, int div){
297+
return (360.f * (float)fphase) / (8.f * (float)div);
298+
}
299+
300+
float calc_div_phase_step(int cphase, int div){
301+
return (360.f * ((float)cphase - (float)div)) / (1.f + (float)div);
302+
}
303+
272304
void calc_pll_params(pll_params &params, float input, float output){
273305
float error = std::numeric_limits<float>::max();
274306
for(int input_div=1;input_div <= 128; input_div++){
@@ -294,7 +326,12 @@ void calc_pll_params(pll_params &params, float input, float output){
294326
params.fvco = fvco;
295327
// shift the primary by 180 degrees. Lattice seems to do this
296328
float ns_phase = 1/(fout * 1e6) * 0.5;
297-
params.primary_cphase = ns_phase * (fvco * 1e6);
329+
float phase_count = ns_phase * (fvco * 1e6);
330+
params.primary_cphase = phase_count;
331+
int cphase = (int) phase_count;
332+
params.primary_fphase = (int) ((phase_count - cphase) * 8);
333+
params.primary_phase_vco_step = calc_vco_phase_step(params.primary_fphase, params.output_div);
334+
params.primary_phase_div_step = calc_div_phase_step(params.primary_cphase, params.output_div);
298335
}
299336
}
300337
}
@@ -331,6 +368,15 @@ void calc_pll_params_highres(pll_params &params, float input, float output){
331368
params.secondary[0].freq = fout;
332369
params.fout = fout;
333370
params.fvco = fvco;
371+
372+
// Is this correct for highres mode?
373+
float ns_phase = 1/(fout * 1e6) * 0.5;
374+
float phase_count = ns_phase * (fvco * 1e6);
375+
params.primary_cphase = phase_count;
376+
int cphase = (int) phase_count;
377+
params.primary_fphase = (int) ((phase_count - cphase) * 8);
378+
params.primary_phase_vco_step = calc_vco_phase_step(params.primary_fphase, params.output_div);
379+
params.primary_phase_div_step = calc_div_phase_step(params.primary_cphase, params.output_div);
334380
}
335381
}
336382
}
@@ -359,6 +405,8 @@ void generate_secondary_output(pll_params &params, int channel, string name, flo
359405
params.secondary[channel].cphase = cphase + params.primary_cphase;
360406
params.secondary[channel].fphase = fphase;
361407
params.secondary[channel].name = name;
408+
params.secondary[channel].phase_vco_step = calc_vco_phase_step(fphase, div);
409+
params.secondary[channel].phase_div_step = calc_div_phase_step(params.secondary[channel].cphase, div);
362410
}
363411

364412
void write_pll_config(const pll_params & params, const string &name, ofstream& file)
@@ -376,8 +424,30 @@ void write_pll_config(const pll_params & params, const string &name, ofstream& f
376424
{
377425
file << " input [1:0] phasesel, // clkout[] index affected by dynamic phase shift (except clkfb), 5 ns min before apply\n";
378426
file << " input phasedir, // 0:delayed (lagging), 1:advence (leading), 5 ns min before apply\n";
379-
file << " input phasestep, // 45 deg step, high for 5 ns min, falling edge = apply\n";
380-
file << " input phaseloadreg, // high for 10 ns min, falling edge = apply\n";
427+
file << " // high for 5 ns min, falling edge = apply\n";
428+
file << " // " << params.primary_phase_vco_step << " deg step for " << params.clkout0_name << "\n";
429+
if(params.secondary[0].enabled){
430+
file << " // " << params.secondary[0].phase_vco_step << " deg step for " << params.secondary[0].name << "\n";
431+
}
432+
if(params.secondary[1].enabled){
433+
file << " // " << params.secondary[1].phase_vco_step << " deg step for " << params.secondary[1].name << "\n";
434+
}
435+
if(params.secondary[2].enabled){
436+
file << " // " << params.secondary[2].phase_vco_step << " deg step for " << params.secondary[2].name << "\n";
437+
}
438+
file << " input phasestep,\n";
439+
file << " // high for 10 ns min, falling edge = apply\n";
440+
file << " // " << params.primary_phase_div_step << " deg step for " << params.clkout0_name << "\n";
441+
if(params.secondary[0].enabled){
442+
file << " // " << params.secondary[0].phase_div_step << " deg step for " << params.secondary[0].name << "\n";
443+
}
444+
if(params.secondary[1].enabled){
445+
file << " // " << params.secondary[1].phase_div_step << " deg step for " << params.secondary[1].name << "\n";
446+
}
447+
if(params.secondary[2].enabled){
448+
file << " // " << params.secondary[2].phase_div_step << " deg step for " << params.secondary[2].name << "\n";
449+
}
450+
file << " input phaseloadreg,\n";
381451
}
382452
file << " input " << params.clkin_name << ", // " << params.clkin_frequency << " MHz, 0 deg\n";
383453
file << " output " << params.clkout0_name << ", // " << params.fout << " MHz, 0 deg\n";

0 commit comments

Comments
 (0)