Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

ADPLL using Verilog? Not working!

Guys I am trying to implement ADPLL in verilog using Quartus-II so I can synthesis my model to an FPGA.

on the internet (http://www-unix.ecs.umass.edu/%7edjasinsk/adpll.html) I have found this code that implements an ADPLL designed by R.E.Best on 1999. I tried to simulate this code to test it but it is not working. Compliation OK but no simulation results. Only CK toogles but all other signals are at zero state.

Please help me figure this out. If this code doesnt work out I think I wont try to write my own code for a different ADPLL!

Thank you.

module pll (u1, u2, fc, reset);
parameter M  = 5;			//5 3
parameter N  = 4;			//4 2
parameter NF = 0;			//0 1
input  u1, fc, reset;
output u2;
wire FF1_in, FF3_in, MF_in, Start, CK, reset, Reset;
wire  Modulus_Control;
reg u1_star, Ud, Load;
wire u2, div_out;
reg u2_prime;
reg  N_Uf;
reg  feedback_divider;
//*****PULSE FORMING CIRCUIT******//
inverter nt3(FF1_in, u1);
always @(negedge u1 or negedge reset)
begin
 if(!reset) u1_star <= 0;
 else u1_star <= !u1_star;
end
assign CK = u1 && u1_star; 
assign MF_in = !u1_star; 
mf mf1(.out (Start), .in (MF_in) );
//*****END PULSE FORMING CIRCUIT****//
jk jk1(.Q (FF3_in), .J (Start), .K (u2_prime), .reset (reset), .fc (fc) );
//jk jk1(.Q (FF3_in), .J (Start), .K (u2) );
always@(u2)
u2_prime <= u2;
/*
always@(posedge u2 or negedge reset)
begin
 if(!reset) 
  begin
  u2_prime <= 0;
  feedback_divider <= 0;
  end
 else 
   begin
   feedback_divider <= feedback_divider + 1;
   if(&feedback_divider) u2_prime <= !u2_prime;
   else u2_prime <= u2_prime;
   end
end
*/
//*****DIGITALLY CONTROLLED OSCILLATOR****//
mcounter# (M) mc1(.u2 (u2), .div_out (div_out), .Reset (Reset), .reset (reset) );
ndivider# (N) nd1(.div_out (div_out), .Load (Load), .fc (fc), .Modulus_Control (Modulus_Control), .reset (reset) );
always @(posedge fc)
Load = div_out || Start;
assign Reset = Start;
//*****END DCO*****//
//***PHASE DETECTOR*****//
always@(posedge u1_star or negedge reset)
begin
	if(!reset) 	Ud <= 0;
        else 		Ud <= FF3_in;
end
//***END PHASE DETECTOR***//
//***LOOP FILTER***//
always@(posedge CK or negedge reset)
begin
 if(!reset) 	 N_Uf <= 6'b010000;
 else if(Ud==0)  N_Uf <= N_Uf+1;
 else 		 N_Uf <= N_Uf-1;
end
assign Modulus_Control = N_Uf;
//***END LOOP FILTER***//
endmodule
///////////////////////
module mcounter(u2, div_out, Reset, reset);
parameter M = 2;
input div_out, Reset, reset;
output u2;
reg  value;
reg u2;
always@(posedge Reset or posedge div_out or negedge reset)
begin
 if(!reset) 
  begin
  value <= 0;
  u2 <= 0;
  end
 else if(Reset)
  begin
  value <= 0;
  u2 <= 0;
  end
 else 
   begin
   value <= value + 1;
   //if (value==5'b11111) u2 <= !u2;
   if (&value==1) u2 <= !u2;
   else u2 <= u2;
   end
end
endmodule
module ndivider(div_out, Load, fc, Modulus_Control, reset);
parameter N = 2;
input Load, fc, reset;
input  Modulus_Control;
reg  value;
reg div_out_pre;
output div_out;
//always@(posedge Load or posedge fc or negedge reset)
always@(posedge fc or negedge reset)
begin
if(!reset) 
  begin
  value <= 0;
  div_out_pre <= 0;
  end
else if(Load) 
  begin 
  value <= Modulus_Control;
  div_out_pre <= 0;
  end
else if(value != 0) 
  begin
  value <= value - 1; 
  div_out_pre <= 0;
  end
else div_out_pre <= 1;
end
assign div_out = div_out_pre;
endmodule
module jk (Q, J, K, reset, fc);
input J, K, reset, fc;
output Q;
reg Q;
reg Q1, Q2;
always@(posedge J or negedge reset)
begin
	if (!reset)	Q1 <= 0;
	else if(K==1)	Q1 <= !Q;
	else		Q1 <= 1;
end
always@(posedge K or negedge reset)
begin
	if (!reset)	Q2 <= 0;
	else if(J==1)	Q2 <= !Q;
	else		Q2 <= 0;
end
always@(Q1 or Q2)
begin
Q <= Q1 || Q2;
end
/*
always@(posedge J or posedge K)
begin
	if((J==0)&&(K==0)) 		Q <=  Q;
	else if((J==0)&&(K==1))		Q <=  0;
	else if((J==1)&&(K==0))		Q <=  1;
	else 				Q <= !Q;
end
*/	
endmodule
module mf (out, in);
input in;
output out;
wire flag, flag2;
reg out;
inverter nt4 (flag, in);
inverter nt5 (flag2, flag);
always@(in or flag2)
begin
  if(!in) out <= 0;
  else out <= in ^ flag2;
end
endmodule
module inverter (out, in);	// inverter
output out;
input in;
reg out;
always @(in)
begin# 1 out <= !in;
//out <= !in;
end
endmodule

10 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Before looking though the code I thought I'd check the simple stuff first :)

    What are you using for stimulus? Have you written a testbench? What drives the clock and reset inputs? (Looks like an active low reset)

    Are you simulating on Quartus or modelsim?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I see some dubious constructs, e. g. CK is a gated clock that probably has glitches and must cause timing violations. The code has to be reworked to get a proper synchronous design. Other issues may exist, too.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Before looking though the code I thought I'd check the simple stuff first :)

    What are you using for stimulus? Have you written a testbench? What drives the clock and reset inputs? (Looks like an active low reset)

    Are you simulating on Quartus or modelsim?

    --- Quote End ---

    Im using QuartusII.

    If u check the link in the first post wer I got the code from, it has figures for the block diagram and the supposed simulation results.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I see some dubious constructs, e. g. CK is a gated clock that probably has glitches and must cause timing violations. The code has to be reworked to get a proper synchronous design. Other issues may exist, too.

    --- Quote End ---

    Can u elaborate more please?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Why are you using Verilog and not the PLL Megafunction of QuartusII?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This a classical example of a gated clock, it's used in the design to clock other modules

    --- Quote Start ---

    always @(negedge u1 or negedge reset)

    begin

    if(!reset) u1_star <= 0;

    else u1_star <= !u1_star;

    end

    assign CK = u1 && u1_star;

    --- Quote End ---

    Please consult Quartus handbook or FPGA/HDL text books why it's a possible issue. I guess, you can see in timing simulation, if you look sharp.

    Generally, I see that there are possible reasons to use a DPLL (digital PLL) respectively ADPLL (all digital PLL) in a design. Apart from practical purpose in some design, it may be used for educational purposes, e.g. to better understand the stuff presented in Best's book.

    Please consider, that I didn't yet try to use the code. I didn't say, that the gated clock issue is a reason, why the design doesn't work. There may be a much more basic problem with the points, vernmid mentioned. But it would be a problem, when using the code in a real design.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Why are you using Verilog and not the PLL Megafunction of QuartusII?

    --- Quote End ---

    I need to synthesis my code on FPGA to test, then synthesized it an actual chip using CAD tools.. thats why..
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    This a classical example of a gated clock, it's used in the design to clock other modules

    Please consult Quartus handbook or FPGA/HDL text books why it's a possible issue. I guess, you can see in timing simulation, if you look sharp.

    Generally, I see that there are possible reasons to use a DPLL (digital PLL) respectively ADPLL (all digital PLL) in a design. Apart from practical purpose in some design, it may be used for educational purposes, e.g. to better understand the stuff presented in Best's book.

    Please consider, that I didn't yet try to use the code. I didn't say, that the gated clock issue is a reason, why the design doesn't work. There may be a much more basic problem with the points, vernmid mentioned. But it would be a problem, when using the code in a real design.

    --- Quote End ---

    Thanx for the input.

    Any idea of other methods for clock data recovery other than ADPLL? (verilog applicable methods)..?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    DPLL are used e. g. in USB controller cores, they clearly have an application field. On the other hand, cause a DPLL has a jitter of one input clock period, it isn't usable for a lot of applications and can't replace an analog PLL so far.

    Cause I don't know your application, I can't rate if a DPLL is a feasible solution.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The feasibility of an alternative method depends on the maximum sampling frequency that you can apply to the input data. The more you oversample the input, the more you will be accurate in clock and data recovery. But certainly, as FvM says, it is difficult to suggest you an appropriate solution without knowing well your application.