1, Principle of state machine
State machine (FSM), also known as finite state machine
One stage state machine
The one-stage state machine seems to solve all logic (including input, output and state) in one always. This writing method seems very concise, but it is often not conducive to maintenance. This writing method is not recommended, but it can still be used in some simple state machines.
Two stage state machine
Two stage state machine is a common writing method. It divides sequential logic and combinatorial logic. The current logic and the next logic are switched in sequential logic, and each input and output and state judgment are realized in combinatorial logic. This writing method is relatively easy to maintain, but the combinatorial logic output is prone to common problems such as burrs.
Three stage state machine
The writing method of three-stage state machine is a recommended writing method. The code is easy to maintain. The output of sequential logic solves the burr problem of combinatorial logic in the two-stage writing method. However, in terms of resource consumption, three-stage consumes more resources. In addition, three-stage input will delay one clock cycle from input to output than one-stage. The three-stage state machine separates sequential logic from combinational logic, and separates state from output, which is clear and easy to understand.
My recommendation is to write a three-stage state machine
2, Design ideas
Key debounce is a relatively simple module with four states
1. Idle (initial state)
2.K_ D (key pressed state)
3.H_ D (press and hold the key to stabilize the value)
4.K_ U (state of key Pop-Up) (this is optional)
Status diagram:
State transition diagram:
Then think about the jump conditions of these States, which is nothing more than the 20ms delay of edge detection and key shaking elimination
assign idle2down = (state_c == IDLE) && nedge;//Falling edge detected assign down2idle = (state_c == DOWN) && (pedge&& end_cnt_20ms);//When the timing is less than 20ms and the rising edge appears, it indicates that the key jitters unexpectedly and returns to the initial state assign down2hold = (state_c == DOWN) && (~pedge && end_cnt_20ms);//When the timing reaches 20ms, there is no rising edge sign, and it remains stable after pressing the key assign hold2up = (state_c == HOLD) && (pedge);//Jump from rising edge to rising state detected assign up2idle = (state_c == UP) && end_cnt_20ms;//The counter counts to 20ms and jumps to the initial state
The rest of the logic is the same as the usual key shaking. You can see the code of my previous blog
[FPGA] key shake elimination in actual combat
3, Code part
The code here is based on the code of my classmates. It's too messy when my code is written. Anyway, this key anti shake module directly copies the code when it needs to be used. The instantiation is finished. Use the key inside_ Just the out signal.
module fsm_key_debounce # (parameter KEY_W = 3,TIME_20MS = 1_000_000)( input clk , input rst_n , input [KEY_W - 1:0] key_in , output [KEY_W - 1:0] key_out ); //Parameter definition localparam IDLE = 4'b0001;//Initial state localparam DOWN = 4'b0010;//Key press jitter localparam HOLD = 4'b0100;//Stable after pressing the key localparam UP = 4'b1000;//Key up jitter //Signal definition reg [3:0] state_c;//Present state reg [3:0] state_n;//Secondary state //State transition condition definition wire idle2down; wire down2idle; wire down2hold; wire hold2up ; wire up2idle ; reg [KEY_W - 1:0] key_r0;//synchronization reg [KEY_W - 1:0] key_r1;//Beat wire [KEY_W - 1:0] nedge;//Falling edge wire [KEY_W - 1:0] pedge;//Rising edge //20ms counter reg [19:0] cnt_20ms; wire add_cnt_20ms; wire end_cnt_20ms; reg [KEY_W - 1:0] key_out_r;//Output register always@(posedge clk or negedge rst_n)begin if(!rst_n)begin state_c <= IDLE; end else begin state_c <= state_n; end end always@(*)begin case(state_c) IDLE:begin if(idle2down)begin state_n = DOWN; end else begin state_n = state_c; end end DOWN:begin if(down2idle)begin state_n = IDLE; end else if(down2hold)begin state_n = HOLD; end else begin state_n = state_c; end end HOLD:begin if(hold2up)begin state_n = UP; end else begin state_n = state_c; end end UP:begin if(up2idle)begin state_n = IDLE; end else begin state_n = state_c; end end default:state_n = state_c; endcase end assign idle2down = (state_c == IDLE) && nedge;//Falling edge detected assign down2idle = (state_c == DOWN) && (pedge&& end_cnt_20ms);//When the timing is less than 20ms and the rising edge appears, it indicates that the key jitters unexpectedly and returns to the initial state assign down2hold = (state_c == DOWN) && (~pedge && end_cnt_20ms);//When the timing reaches 20ms, there is no rising edge sign, and it remains stable after pressing the key assign hold2up = (state_c == HOLD) && (pedge);//Jump from rising edge to rising state detected assign up2idle = (state_c == UP) && end_cnt_20ms;//The counter counts to 20ms and jumps to the initial state //20ms counter always@(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt_20ms <= 0; end else if(add_cnt_20ms)begin if(end_cnt_20ms)begin cnt_20ms <= 0; end else begin cnt_20ms <= cnt_20ms + 1'b1; end end end assign add_cnt_20ms = state_c == DOWN || state_c == UP;//Start counting when the key is pressed or bounced assign end_cnt_20ms = add_cnt_20ms && ((cnt_20ms == TIME_20MS - 1) || pedge);//When the maximum value is counted or a rising edge is detected, the counter is cleared //Synchronous beat always@(posedge clk or negedge rst_n)begin if(!rst_n)begin key_r0 <= {KEY_W{1'b1}}; key_r1 <= {KEY_W{1'b1}}; end else begin key_r0 <= key_in; key_r1 <= key_r0; end end assign nedge = ~key_r0 & key_r1;//Detect falling edge assign pedge = key_r0 & ~key_r1;//Detect rising edge //Key assignment always@(posedge clk or negedge rst_n)begin if(!rst_n)begin key_out_r <= {KEY_W{1'b0}}; end else if(state_c == HOLD && hold2up)begin key_out_r <= ~key_r1; end else begin key_out_r <= {KEY_W{1'b0}}; end end assign key_out = key_out_r; endmodule
4, Simulation verification
There is no verification here. You can still go to my previous blog simulation, which is nothing more than adding 4 states and 4 state transition conditions.