It can be seen from the meaning of the title: the finite state machine has a total of 6 states, that is, the state of the sensor (s3, s2, s1), which are as follows
A2:001->000
B1:000->001
B2:011->001
C1:001->011
C2:111->011
D1:011->111
Among them, 000 means that the sensors (s3, s2, s1) below the water level s1 are all 0, 111 means that the sensors (s3, s2, s1) above the water level s3 are all set to 1, and so on.
Then analyze FR3, FR2, FR1, and dfr corresponding to 6 states, where dfr represents whether to increase the water volume, dfr=1 represents the water demand increases, and dfr=0 represents the water demand remains unchanged or decreases.
A2: Since the end of this state is 000, the water level is below s1, so (FR3,FR2,FR1)=(1,1,1). The state is 001 at the beginning and 000 at the end. Therefore, the required amount of water is changed from (FR3, FR2, FR1) = (0, 1, 1) required by 001 to (FR3, FR2, FR1) = (1, 1, 1) required by 000, so the water demand increases dfr=1;
B1: The tail state is 001 between the water level s2 and s1, so (FR3,FR2,FR1)=(0,1,1). The state is 000 at the beginning and 001 at the end. Therefore, the amount of water required for 000 (FR3, FR2, FR1) = (1, 1, 1) has changed to the amount of water required for 001 (FR3, FR2, FR1) = (0, 1, 1) and the amount of water required has decreased. so dfr=0;
D1: The tail state is 111 and the water level is above s3, so (FR3, FR2, FR1)=(0,0,0). The state is 011 at the beginning and 111 at the end. Therefore, the required amount of water is changed from (FR3,FR2,FR1)=(0,0,1) required by 011 to (FR3,FR2,FR1)=(0,0,0) required water amount of 111 is reduced by dfr =0;
Analyzing B2, C1, C2 in the same way
After the above analysis, the code can be obtained as follows
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
// set parameter
//A2:001->000,B1:000->001,B2:011->001,C1:001->011,C2:111->011,D1:011->111
parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
wire[2:0] state, next;
// state transition (combination logic)
always@(*)begin
case(state)
A2: next = s[1]? B1:A2;
B1: next = s[2]? C1:(s[1]? B1:A2);
B2: next = s[2]? C1:(s[1]? B2:A2);
C1: next = s[3]? D1:(s[2]? C1:B2);
C2: next = s[3]? D1:(s[2]? C2:B2);
D1: next = s[3]? D1:C2;
endcase
end
always@(posedge clk)begin
if(reset)
state <= A2;
else
state <= next;
end
// output control()sequential logic
always@(*)begin
case(state)
A2: {fr3,fr2,fr1,dfr} = 4'b1111;
B1: {fr3,fr2,fr1,dfr} = 4'b0110;
B2: {fr3,fr2,fr1,dfr} = 4'b0111;
C1: {fr3,fr2,fr1,dfr} = 4'b0010;
C2: {fr3,fr2,fr1,dfr} = 4'b0011;
D1: {fr3,fr2,fr1,dfr} = 4'b0000;
endcase
end
endmodule
The code should pay attention to always only need to set the rising edge trigger when synchronous reset. In the rest of the time, whenever the state changes, each output changes accordingly.
State transition analysis:
When in state A2, when s[1] is equal to 1, it means that the next state is from 000->001, which is state B2. When s[1] is equal to 0, it means that it is still in the current state 001->000
When in the B1 state, when s[2] is equal to 1, it means that the next state is from 001->011, which is the state C1. When s[2] is equal to 0 and s[1] is equal to 1, keep 000->001 B2, When s[2] is equal to 0 and s[1] is equal to 0, the state is changed from 001->000, which is A2.
and so on.