上一篇博文观察了 一段式 状态机的底层电路情况,把上边的状态机写成 三段式 ,看看底层电路是什么样 !
parameter state0=4'd0,state1=4'd1,state2=4'd2,state3=4'd3,state4=4'd4;
reg [3:0] state;
reg [3:0] next_state;
//状态机第一段程序
always@(posedge clk or negedge rst_n) // 状态时序转移
if(!rst_n)
state<=state0;
else state<=next_state;
//状态机第二段程序
always@(state or datain1 or datain2 or datain3 or datain4) // 状态转移组合逻辑
case(state)
state0: if(datain1) next_state=state1;
else if(datain2) next_state=state2;
else if(datain3) next_state=state3;
else if(datain4) next_state=state4;
else next_state=state0;
state1: if(datain1) next_state=state0;
else if(datain2) next_state=state2;
else if(datain3) next_state=state3;
else if(datain4) next_state=state4;
else next_state=state1;
state2: if(datain1) next_state=state1;
else if(datain2) next_state=state0;
else if(datain3) next_state=state3;
else if(datain4) next_state=state4;
else next_state=state2;
state3: if(datain1) next_state=state1;
else if(datain2) next_state=state2;
else if(datain3) next_state=state0;
else if(datain4) next_state=state4;
else next_state=state3;
state4: if(datain1) next_state=state1;
else if(datain2) next_state=state2;
else if(datain3) next_state=state3;
else if(datain4) next_state=state0;
else next_state=state4;
default: next_state=state0;
endcase
//状态机第三段程序
always@(posedge clk or negedge rst_n) // 时序输出
if(!rst_n)
begin
dataout1<=4'b0;
end
else case(next_state)
state0:
begin
dataout1<=4'd5;
end
state1:
begin
dataout1<=4'd1;
end
state2:
begin
dataout1<=4'd2;
end
state3:
begin
dataout1<=4'd3;
end
state4:
begin
dataout1<=4'd4;
end
default: begin
dataout1<=4'd5;
end
endcase
endmodule
可以看出,和一段式状态机 综合的电路不一样,但大体结构一致。在电路中,也没有 parameter 定义的各个4位表示的状态常量,也没有寄存器[3:0] state 和[3:0]next_state 。每个状态也是用一个D触发器 表示 state.state0,state.state1,state.state2,state.state3,state.state4。
上边的部分综合电路图,显示的是从state1 到 state0 的过程,以及对应的输出 dataout1,都是“源同步”模式的。
上边的三段式程序,可以这样和电路对应起来理解:next_state 代表组合逻辑,各个状态触发器(state.state0,state.state1,state.state2等)前边的组合逻辑以及各个输出寄存器dataout前的组合逻辑都是用next_state来表示。每一个状态触发器state或者输入改变,就会引起next_state改变(状态机第二段程序),对应的某个状态触发器(如state.state1)前的组合逻辑以及相应的输出寄存器dataout前的组合逻辑变为高电平,时钟上升沿来时,此状态触发器(state.state1)输出高电平(状态机第一段程序),同时,输出对应的结果(状态机第三段程序)。
状态机的第三段程序:当上升沿来时,由输出dataout寄存器前的组合逻辑next_state决定输出结果。注意:并不是在上升沿后,才对比next_state等于那个state,而是在上升沿到来前,dataout前的组合逻辑电平已经等于相应状态下的电平值,上升沿来到后,只要满足“建立/保持”时间,就会输出相应结果,这就是代码行为级描述和底层电路的区别!
代码中不同的next_state组合逻辑反应到电路中,是state.staet0等状态触发器前边组合逻辑的不同值,以及输出寄存器dataout前边组合逻辑的不同值。Example: 当程序中next_state=state0时,触发器state.state0前连接的组合逻辑输出高电平,而state.state1前连接的组合逻辑输出低电平,输出寄存器dataout1前连接的组合逻辑为4'd5,所以,当上升沿到来后,state.state0输出高电平,dataout1输出4'd5,状态跳转到state0;又当next_state=state1时,触发器state.state0前连接的组合逻辑输出低电平,而state.state1前连接的组合逻辑输出高电平,输出寄存器dataout1前连接的组合逻辑为4'd1,所以,当上升沿到来后,state.state0输出低电平,dataout1输出4'd1,状态跳转到state1;
注意:这里边可能会出现“建立/保持”时间的时序违规问题 !
很多时候并不能把程序和电路直接对应,因为程序是从“行为级(功能级)”描述的,比如上边三段式状态机程序的 第二段(状态转移组合逻辑),并不能指出某一条程序对应什么电路,最后的结果,电路实现了程序描述的功能。
状态机宏观理解如下:
而底层实际综合后的结构如下:
文章评论(0条评论)
登录后参与讨论