Forum Discussion

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

Looping problem faced since loops are not synthesizable. Any other way?

Hi can anyone please help me with this code i wrote for hc-sr04 (ultrasonic sensor)? I need to loop the process after 1 sec. Since i cannot use while or for loops because they are not synthesizable. Can someone tell me how i can loop this?


module usensor3 (trig, echo, distance_o,reset);
output trig, distance_o;
input clk, echo, reset;
reg  dist_counter=0;
reg  counter=0;
reg trig;
always @ (posedge clk)
	begin
			if (reset)
					begin
					counter<=0;
					dist_counter<=0;
					end
			else
				begin
					counter <= counter + 1;
					if (counter <= 500)              //10usec to initialize sensor
					trig<=1;                         // trig is set high
			
					if (echo)                        // sensing 5v at echo pin so echo pin is high
					begin
						dist_counter <= counter;      // counter value will be recorded in distance
						trig <=0;
					end
			
					if (counter<= 1900000)	  // maximum time of sensing any object is 38ms
					trig<=0;
			
				
					if (counter<= 5000000)      // wait 1 sec to begin again
					begin
					counter<=0;
					distance_o <=0;
					end
			
				   // How to start the whole cycle again
				
			end
	end	
			
assign distance_o = (dist_counter * 340) << 1; //The velocity of the ultrasonic burst is 340m/sec in air
endmodule

3 Replies

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

    Your code is complete. Always blocks will run continuously, so once you reset counter, it will just continue incrementing in the 'counter <= counter + 1' statement.

    Your if statements make no sense, however. The symbol '<=' is a non blocking assignment, but in logic (if statement) it means less than or equal to. Your if statements should be changed to == or >= otherwise they will all trigger at once... Please review your code.

    You also want to put 'or posedge reset' in the sensitivity list. Next, since 'echo' is an asynchronous input, you should probably have some synchronizer chains to bring in the data into the FPGA's clock domain, or at least put some debounce logic.... not sure how clean your 'echo' signal's edge will be when it pops high.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes you are right about the if statements. I don't know why i didn't see that. Thank you. I've made changes in my code according to your suggestions. And i understand now i do not need a loop anymore.

    However, i am not clear about what you meant by the following:

    "Next, since 'echo' is an asynchronous input, you should probably have some synchronizer chains to bring in the data into the FPGA's clock domain, or at least put some debounce logic.... not sure how clean your 'echo' signal's edge will be when it pops high."

    Could you please break it down for me if possible. I'm still sort of in the learning phase. Thanks.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    So echo is coming in from the outside world. When the signal arrives on the FPGA pin, it will probably not be lined up with the FPGA clock's edge. Therefore you may miss some data because it arrives too early or too late. Because of this your capture register may have an undetermined value (not 0 or 1) when the clock edge triggers in the always block. This is called metastability: https://www.altera.com/content/dam/altera-www/global/en_us/pdfs/literature/wp/wp-01082-quartus-ii-metastability.pdf

    To solve the asynchronous problem you can write code that will implement a synchronizer chain. Here is a great example of the implementation with the code: https://daffy1108.wordpress.com/2014/06/08/synchronizers-for-asynchronous-signals/ . As you can see you just need to include 1 more always block.

    ----------------------------------

    assign distance_o = (dist_counter * 340) << 1 you are bitshifting in the wrong direction..... if you want to divide by 2, it would be a bitshift to the right >>

    why not multiply by 170...... instead of 340/2