一、状态机设计要点
1、概述
(2)状态机的转移图
(3)结构:
(4)设计标准
(5)状态机三段设计方法
第一:
第二:
第三:
(6)三段状态机设计注意点
二、Verilog实现状态机练习题
(1)简单的状态切换
实现思路:三段
对应的代码如下:
module exercise37(clk,rst_n,en,state_c);
parameter STATE_WID = 2;
parameter IDLE = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
input clk;
input rst_n;
input en;
output [STATE_WID-1:0] state_c;
reg [STATE_WID-1:0] state_c;
reg [STATE_WID-1:0] state_n;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
state_c<=IDLE;
end
else begin
state_c<=state_n;
end
end
always @(*)begin
case(state_c)
IDLE:begin
if(en==1'b1)begin
state_n=S1;
end
else begin
state_n=IDLE;
end
end
S1:begin
if(en==1'b1)begin
state_n=S2;
end
else begin
state_n=S1;
end
end
S2:begin
if(en==1'b1)begin
state_n=IDLE;
end
else begin
state_n=S2;
end
end
default:begin
state_n=state_c;
end
endcase
end
endmodule
(2)根据条件切换状态
代码实现:
module state2(clk,rst_n,en,state_c);
parameter STATE_WID = 2;
parameter IDLE = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
input clk;
input rst_n;
input en;
output [STATE_WID-1:0] state_c;
reg [STATE_WID-1:0] state_c;
reg [STATE_WID-1:0] state_n;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
state_c<=IDLE;
end
else begin
state_c<=state_n;
end
end
always @(*)begin
case(state_c)
IDLE:begin
if(en==1'b1)begin
state_n=S1;
end
else begin
state_n=IDLE;
end
end
S1:begin
if(count==4)begin
state_n=S2;
end
else begin
state_n=S1;
end
end
S2:begin
if(count==6)begin
state_n=IDLE;
end
else begin
state_n=S2;
end
end
default:begin
state_n=state_c;
end
endcase
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
count <= 0;
end
else if(state_c==S1)begin
if(count==4)
count <= 0;
else
count <= count + 1;
end
else if(state_c==S2)begin
if(count==6)
count <= 0;
else
count <= count + 1;
end
else begin
count <= 0;
end
end
endmodule
(3)状态机实现流水灯
module led(clk,rst_n,led);
input clk ;
input rst_n ;
output reg [3:0]led ;
reg [1:0] state_c;
reg [1:0] state_n;
parameter IDLE = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
reg [31:0] count;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
state_c<=IDLE;
end
else begin
state_c<=state_n;
end
end
always @(*)begin
case(state_c)
IDLE:begin
if(count==49999999)begin
state_n=S1;
end
else begin
state_n=IDLE;
end
end
S1:begin
if(count==49999999)begin
state_n=S2;
end
else begin
state_n=S1;
end
end
S2:begin
if(count==49999999)begin
state_n=IDLE;
end
else begin
state_n=S2;
end
end
default:begin
state_n=state_c;
end
endcase
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
led <= 4'b1111;
end
else if(state_c==S1)begin
led=4'b0011;
end
else if(state_c==S2)begin
led=4'b1100;
end
else begin
led <= 4'b1111;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
count <= 0;
end
else begin
if(count==49999999)
count <= 0;
else
count <= count + 1;
end
end
endmodule