上一篇博文观察了 一段式 状态机的底层电路情况,把上边的状态机写成 三段式 ,看看底层电路是什么样 !
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条评论)
登录后参与讨论