Forum Discussion

VROGE2's avatar
VROGE2
Icon for Occasional Contributor rankOccasional Contributor
6 years ago

Duty cycle of a square wave changing with tunable delay

I am using a function I colleague of mine created to take an incoming square wave and delay it by 20ns every time I push a button on my Dev Board. However, when I do this the square wave does get delayed but the duty cycle of the square wave increase slightly each time I press the button to the point that once the wave has been delayed by a full period (520ns, 26 50MHz clock cycles) the square wave is high for 300ns (15 clock cycles) and low for only 220ns (11 clock cycles) rather than high for 260ns and low for 260ns. I have been going through the logic to try and figure this out but I have been unable to do so so far.

Furthermore, it seems that the numbers I gave are not constant. For instance at 1/2 period the wave is high for 280ns and low for 240ns and at 1.5 period the wave is high for 320ns and low for 260ns so it appears that the further the wave is delayed the more the duty cycle will change.

Thank you in advance

module tunable_delay(delay_in,delay_out,switch_up,sign_reg);  //delay_in = swin, delay_out = sw[0]
input delay_in, switch_up, sign_reg;
output delay_out;
 
parameter n=100; // number of Delay Units: 100*0.2 ns = 20 ns, for simplicity - try to use integer multiple of 16 or power of 2
wire [n-1:0] delay     /* synthesis keep */ ;
wire [n-1:0] dand    /* synthesis keep */ ;
reg [n-1:0] delay_reg;
genvar i;
 
reg pin;
 
initial begin
	 delay_reg[n-1]=0;//2^30
	 delay_reg[n-2]=1;//2^30
	 delay_reg[n-3:0]=0;
end
 
generate
	for (i=0;i<n;i=i+1)
	begin : generate_ands1
		assign dand[i]= delay_in & delay_reg[i];
	end
endgenerate
 
generate
	for (i=0;i<n-1;i=i+1)
	begin : generate_ands2
		assign delay[i+1] = delay[i] | dand[i];
	end
endgenerate
 
always @(posedge switch_up) begin
 
	if (sign_reg==0) begin
		// Fine Adjustment Down:
		if(~delay_reg[n-2]) begin
			delay_reg <= (delay_reg << 20);
		end
	end
	if(sign_reg==1) begin
		// Fine Adjustment Up:
		if(~delay_reg[1]) begin
			delay_reg <= (delay_reg >> 20);
		end
	end
	
 
end
 
assign delay_out = delay[n-1];
 
////////////////////////////////////////
endmodule

3 Replies

  • KennyT_altera's avatar
    KennyT_altera
    Icon for Super Contributor rankSuper Contributor

    From your design, there are no clock associated with it. I would suggest you have a reference clock tied to it so that your delay can be be reference to a clock.

    1) make sure you run your modelsim simulation to verify your behavior after adding the clock in.

    2) make sure you written your sdc

    3) make sure your timing closed.

  • VROGE2's avatar
    VROGE2
    Icon for Occasional Contributor rankOccasional Contributor

    This is a submodule. There is a clock associated with it however it happens earlier in the code so it just isn't shown. I was able to speak with my colleague yesterday and this is a problem he has run into before. What is happening is that the square wave coming in is not perfectly square meaning that there is a rise time and a fall time for each wave. furthermore the rise time and fall time are not the same so what happens is that as the waves are delayed an error builds up with each instance of the delay. He does know how to fix it, it would just take more time than what we have to do so.