FPGA状态机的理解
1.状态机的分类
moore型状态机
功能框图:
mealy型状态机
功能框图
2.二者的区别
moore型状态机的输出G只与当前的状态有关,而mealy状态机的输出不但与当前的状态有关还与输入有关
注:在实际的生活中,mealy型状态机的出现场景较多。
3.状态机的设计(三段式)
无论是moore型状态机还是mealy型的状态机,一般都使用三段式状态机来设计。在设计之前首先要明白在什么情况下应该使用状态机,virelog语言表示的思想是并行思想,这就在将fpga用于处理先后发生的事件的情况下,verilog并行处理思想就显得不合适,于是我们可以知道,只有在发生有先后顺序的情况下,状态机应运而生,以此来解决问题。
首先,通过上面的两幅图片,我们可以知道三段式状态机分别是哪三段。
第一段----状态寄存器
在这一段我认为是最好写的,甚至可以当作模板来写,下面是第一段状态机通常情况下的代码展示。
always @(posedge sys_clk or negedge sys_rst) begin
if(!sys_rst)
current_state <= IDLE;
else
current_state <= next_state;
end
但是这里有一个值得注意的点,current_state和next_state的位宽应该与状态变量相同。例如:使用独热码设置分别设计四个状态:
localparam IDLE = 4'b0001;
localparam START = 4'b0010;
localparam RD_DATA = 4'b0100;
localparam STOP = 4'b1000;
那么current_state和next_state也应该要定义为4位,如果不同位,则会少状态。
第二段–组合逻辑表示状态转移
在这一阶段,我们要明白每个状态在什么条件下会发生状态的转移。例如以串口接受状态机为例。
always @(*) begin
next_state = IDLE;
case(current_state)
IDLE:
if(work_en == 1'b1)
next_state = START;
else
next_state = IDLE;
START:
if(boud_cnt == BAUD_CNT_MAX - 1'b1)
next_state = RD_DATA;
else
next_state = START;
RD_DATA:
if((bit_cnt == 4'd7)&&(boud_cnt == BAUD_CNT_MAX - 1'b1))
next_state = STOP;
else
next_state = RD_DATA;
STOP:
if(boud_cnt == BAUD_CNT_MAX/2- 1'b1)
next_state = IDLE;
else
next_state = STOP;
default:next_state = IDLE;
endcase
end
以IDLE到START状态为例,当work_en信号为高时,才发生状态的转移。同理可以理解其他时刻的状态转移,有关串口接受状态机的具体分析我将会在下一节具体分析,这里只以实际例子作为讲解。
第三段----产生输出的组合/时序逻辑
以串口发送模块的状态的第三段为例:
always @(posedge sys_clk or negedge sys_rst) begin
if(!sys_rst)
tx_data_r <= 1'b1;
else
case(current_state)
IDLE:
tx_data_r <= 1'b1;
START:
tx_data_r <= 1'b0;
TX_DATA:
tx_data_r <= tx_data_latch[Bit_cnt];
STOP:
tx_data_r <= 1'b1;
default: tx_data_r <= 1'b1;
endcase
end
这一段的意思就是在相应的状态下,系统的输出是什么,这一点可以根据波形图来确定。
状态机的实际使用练习将在下一节串口通信讲解具体怎么用。文章来源:https://www.toymoban.com/news/detail-758070.html
总结:
又功能框图可知,状态机的使用重要的是确定输入和输出,状态有哪些,以及在各个状态下系统的输出是什么和状态跳转的条件,只有清楚的知道这些,状态机的编写才是轻松的,不迷糊的。文章来源地址https://www.toymoban.com/news/detail-758070.html
到了这里,关于FPGA状态机的理解与设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!