有限状态机FSM书写模板主要包含以下几部分
1、文件描述:包含了文件功能描述、文件名、作者、编辑历史等
2、预定义区域,`define关键字
3、模块申明
4、输入输出申明
5、参数申明,包含了parameter和localparam,其中parameter可以在实例化时重载,而localparam不行
6、net和寄存器类型申明,既包含了输入输出,也包含了状态机的转换寄存器和其他寄存器
7、数据流定义,主要用在assign关键字和赋值
8、状态机第一步:以rst_n 或clk作为普通事件触发,实现now_state和next_state之间的转换
9、状态机第二步:以now_state作为普通事件触发,主要用于确定状态转换成功之后需要进行的操作
10、状态机第三步:以触发源(Trigger)和now_state作为普通事件触发,主要用于确定转换条件以及在条件符合的时候改变next_state的值
(这里用触发源(Trigger)和now_state作为普通事件触发是因为部分状态机状态转换的时候不需要触发源,只需要内部完成某些操作即可,如果在不同状态之间进行状态转换时需要增加延迟,就应该在这个地方增加。因为FSM第一步执行的不仅仅是不同状态之间的转换,还有相同状态之间的转换,所以延迟不能加在FSM 第一步。)
//=========================================
// file description :
// file name :
// owner :
// revision history :
//==========================================
// predefine of module
`define USER_PREDEFINE1 1'b1
`define USER_PERDEFINE2 1'b0
module Module_Name
(
system_clk
,system_rst_n
// user_input
,user_input1
,user_input2
,user_input3
// user_output
,user_output1
,user_output2
,user_output3
);
// input and output declaration
input system_clk;
input system_rst_n;
input user_input1;
input user_input2;
input user_input3;
output user_output1;
output user_output2;
output user_output3;
// parameter declaration
parameter S0 3'd0
parameter S1 3'd1
parameter S2 3'd2
parameter S3 3'd3
parameter S4 3'd4
parameter USER_PARAMETER 32'd30
localparam USER_LOCALPARAM 32'd30
// reg and wire declaration
wire clk;
wire rst_n;
wire user_input1;
wire [1:0] user_input2;
wire [2:0] user_input3;
wire user_output1;
reg user_output2;
reg [2:0] user_output3;
reg [2:0] user_output3;
reg [1:0] now_state;
reg [1:0] next_state;
// data flow assignment
assign user_output = rst_n && user_input1;
// essential code (first step of FSM )
// connection between now_state and next_state
always (@ posedge clk or rst_n)
begin
if (~rst_n)
now_state <= S0;
else
now_state <= next_state;
end
// essential code (second step of FSM)
// something is going to be done after state transform
always @ (now_state)
begin
// start value of the reg in FSM
user_output2 <= 1'd1;
user_output3 <= 2'd1;
// something is going to be done after state transform
case (now_state)
S0:
S1:
S2:
S3:
S4:
...
default:
endcase
end
always @ (Trigger_Source or now_state)
begin
case(now_state):
S0: if(Trigger_Source)
...
else
...
S1:
S2:
S3:
S4:
...
default:
endcase
end
endmodule