当前位置 博文首页 > zhoujianjayj的博客:Verilog代码规范(四)-- 状态机简述
一般来说,verilog实现状态机一般有一段式、二段式和三段式状态。最常见和便于理解的状态机写法是三段式状态机。
一段式状态机的状态跳转,以及在不同的状态下进行的logic和数据打拍都在一个always中完成。
其缺点是状态机状态跳转,和数据操作混杂在一起,调理不清晰。因此一般不建议写成一段式状态机。
?
第一段:时序逻辑采用同步时序的方式描述状态转移;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
state <= IDLE;
else
state <= next_state;
end
第二段:组合逻辑的方式判断状态转移条件,描述状态转换规律;并在该状态下输出信号;
always @(*) begin
case (state)
IDLE: begin
if() begin
a = 1'b0;
next_state = A_STATE;
end
else begin
a = 1'b0;
next_state = B_STATE;
end
end
A_STATE: begin
a = 1'b0;
next_state = B_STATE;
end
B_STATE: begin
a = 1'b0;
next_state = A_STATE;
end
default: begin
a = 1'b0;
next_state = IDLE;
end
endcase
end
二段式状态机的输出是组合逻辑输出,这是二段式状态机不太好的地方。因为可能会产生毛刺。
?
第一段:时序逻辑采用同步时序的方式描述状态转移;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
state <= IDLE;
else
state <= next_state;
end
第二段:组合逻辑的方式判断状态转移条件,描述状态转换规律;
always @(*) begin
case (state)
IDLE: begin
if()
next_state = A_STATE;
else
next_state = B_STATE;
end
A_STATE: begin
next_state = B_STATE;
end
B_STATE: begin
next_state = A_STATE;
end
default: begin
next_state = IDLE;
end
endcase
end
第三段:使用同步时序得到方式描述每个状态下的输出(也可以和二段式一样,使用组合逻辑输出)
always @(posedge clk or negedge rst_n)
if(!rst_n)
a <= 1'b0;
else
case(state)
IDLE: a <= 1'b0;
A_STATE: a <= 1'b1;
B_STATE: a <= 1'b1;
default: a <= 1'b1;
endcase
不要把一个状态机的所有的输出都在一个always块里面!
相比于两段式,三段式的时序逻辑输出解决了两段式组合逻辑的毛刺问题,但是相对的资源消耗多一些;
cs