Sum: The part with the state machine named "WaitS2" is only incrementing the "count" once.
I am trying to control ultrasound sensors HC-SR04 in systemverilog. As I saw in the datasheet, this sensor creates a signal "trigger" which creates the sound and after generating the sound sensor creates logic "echo", I need to count the time, so that I create the state machine you can see in the code, but the problem is count++ is not working as well as expected it is only incrementing count variable once, no matter how long the echo signal is
I used another module called 32-bit adder from internet, which did not changed anything.
I changed all of the statements to non-block statements it did not work.
I even tried changed count++
to count = count + 1
did not work
module sensorFSM(
input logic echo , clk ,reset,
output logic trig,
output logic[31:0] distance,
output logic[1:0] presentState
);
/*typedef enum logic[1:0] {BeginS , WaitS , ReturnS } states;
states presentState , nextState;
*/
logic[31:0] count , count1;
logic[1:0] BeginS , WaitS, WaitS2 , ReturnS , nextState;
assign BeginS = 2'b00;
assign WaitS = 2'b01;
assign WaitS2 = 2'b10;
assign ReturnS = 2'b11;
// clk and state change
always_ff @( posedge clk )
begin
if ( reset == 1'b1 )
presentState <= BeginS;
else
presentState <= nextState;
end
// real state changes
always_comb
begin
case(presentState)
BeginS:
begin
trig = 1'b1;
count = 32'b0;
nextState = WaitS;
end
WaitS:
begin
trig = 1'b0;
distance = 32'b0;
//#5000;
nextState = WaitS2;
end
WaitS2:
begin
if( echo == 1 )
begin
if ( count < 24'b101100111000000100100000 )
begin
// here is the problem count is only incrementing
//once
count++;
nextState = WaitS2;
end
else
begin
distance = count;
nextState = BeginS;
end
end
else // echo == 0
begin
nextState = ReturnS;
end
end
ReturnS:
begin
//count = count / 1470;
distance = count;
nextState = BeginS;
end
default:
nextState = BeginS;
endcase
end
endmodule
I expect the simulation will count like around 1 miliion but it always outputs 1, but I can see that the state named "WaitS2" is present for a long amount of time when echo is active also
You created an asynchronous feedback loop with count++;
inside always_comb
. You need to make count
a register.
Also trig
and distance
are currently inferred level-sensitive latches. distance
needs to be a flop. trig
could be written as pure combinational logic, but since it is an output I highly recommend to make it a flop remove the rise of output glitches.
always_ff @( posedge clk )
begin
if ( reset == 1'b1 ) begin
presentState <= BeginS;
trig <= 0; // <-- reset
distance <= 0; // <-- reset
count <= 0; // <-- reset
end else begin
presentState <= nextState;
trig <= next_trig; // <-- flop trig
distance <= next_distance; // <-- flop distance
count <= next_count; // <-- flop count
end
end
// real state changes
always_comb
begin
next_trig = trig; // <-- default value is flopped value
next_distance = distance; // <-- default value is flopped value
next_count = count; // <-- default value is flopped value
case(presentState)
BeginS:
begin
//trig = 1'b1; // <-- is now a flop assigned in always_ff
//count = 32'b0; // <-- is now a flop assigned in always_ff
next_trig = 1'b1; // <-- update value
next_count = 32'b0; // <-- update value
nextState = WaitS;
end
WaitS:
// ... replace trig/distance with next_trig/next_distance in here ...
WaitS2:
begin
// ...
//count++; // <-- NOPE would be asynchronous feedback
next_count = count + 1; // <-- synchronous increment
// ...
end
ReturnS:
// ... replace distance with next_distance in here ...
default:
nextState = BeginS;
endcase
end