Forum Discussion
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
Honored 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
Honored 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
Honored 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