状态机
什么叫状态机,虽然verilog描述的电路都是并行的,但是也有的电路需要顺序执行,需要一些硬件来实现一些具有一定的顺序的工作,这就要用到的思想就叫做状态机。简单来说就是通过不同的状态迁移来完成一定的特殊顺序逻辑。硬件的并行性决定了verilog描述的硬件逻辑的并行性,所以Verilog 中状态机主要用于同步时序逻辑的设计,能够在有限个状态之间按一定要求和规律切换时序电路的状态。状态的切换方向不但取决于各个输入值,还取决于当前所在状态。 状态机根据其状态变化是否与输入条件相关可分为 2 类:Moore 状态机和 Mealy 状态机。
moore型状态机的输出只和当前状态有关,与当前输入无关,输出会在一个完整的时钟周期内保持稳定,即使此时输入信号有变,输出也不会变化。输入与输出隔离开,(我觉得是输入和输出的时延性)这是moore型状态机的特点。
mealy型状态机,这种状态机的输出不仅和当前的状态有关,也和当前的输入有关,既输入有变化,输出也就改变,不管现在输出的状态是稳定还是输入的小改变,都要改变。
状态机也还分为有限状态机(FSM)和无限状态机(ISM),我们一般讨论的都是有限状态机。
三段状态机
状态机一般有三种不同的写法,即一段式,二段式和三段式。他们的在速度,面积,使用范围上都各有优缺点,
根据状态机的个数确定状态机编码。利用编码给状态寄存器赋值,代码可读性更好。
(1) 状态机第一段,时序逻辑,非阻塞赋值,传递寄存器的状态。
(2) 状态机第二段,组合逻辑,阻塞赋值,根据当前状态和当前输入,确定下一个状态机的状态。
(3) 状态机第三段,时序逻辑,非阻塞赋值,因为是 Mealy 型状态机,根据当前状态和当前输入,确定输出信号。
代码在这里:6.3 Verilog 状态机 | 菜鸟教程
(这是一个售卖机模块的代码,用于实现售卖机的基本功能,包括找零和出售饮料。售卖机支持两种面额的硬币:5角和1元。每行代码的意思如下:
-
input clk, input rstn, input [1: 0] coin, output [1: 0] change, output sell
:输入时钟信号、复位信号、投入硬币(01代表0.5元,10代表1元)、输出找零、出货。 -
parameter IDLE = 3 'd0; = 3 'd1;
:定义空闲状态和接收硬币状态的两个状态码。 -
reg [2:0] st_next ; reg [2:0] st_cur ;
:定义两个寄存器,分别表示下一个状态和当前状态。 -
always @(posedge clk or negedge rstn) begin
:始终在时钟上升沿或复位信号下降沿时执行。 -
case(st_cur)
:根据当前状态执行相应操作。 -
default: st_next = IDLE ;
:如果当前状态不是空闲或接收硬币状态,则将下一个状态设置为空闲或接收硬币状态。 -
endcase
:结束case语句。 -
always @(posedge clk or negedge rstn) begin
:始终在时钟上升沿或复位信号下降沿时执行。 -
if (!rstn) begin
:如果没有复位信号,则执行以下操作。 -
change_r <= 2'b0 ; sell_r <= 1'b0 ;
:将找零输出置为0,出货输出置为0。 -
end if
:结束if语句。 -
else if ((st_cur == GET15 && coin ==2'h1) || (st_cur == GET10 && coin ==2'd2)) begin
:如果当前状态是接收1元硬币且投入的是5角硬币或者当前状态是接收10元硬币且投入的是1元硬币,则执行以下操作。 -
change_r <= 2'b0 ; sell_r <= 1'b1 ;
:将找零输出置为0,出货输出置为1。 -
end if
:结束if语句。 -
else if (st_cur == GET15 && coin == 2'h2) begin
:如果当前状态是接收1元硬币且投入的是1元硬币,则执行以下操作。 -
change_r <= 2'b1 ; sell_r <= 1'b1 ;
:将找零输出置为1,出货输出置为1。 -
end if
:结束if语句。 -
else begin
:如果以上条件都不满足,则执行以下操作。 -
change_r <= 2'b0 ; sell_r <= 1'b0 ;
:将找零输出置为0,出货输出置为0。 -
end else:结束else语句。
-
assign sell = sell_r; assign change = change_r;
:将出货输出赋值给出货变量,将找零输出赋值给找零变量。 -
endmodule
:结束模块定义。)
二段式就是将三段式中的归零操作和选择结合到一起,但是在仿真的时候,直接出现了两次不正常的峰值,就是因为并行阻塞导致干扰脉冲。
一段式将所有的逻辑都放在一个always里,缺点就是许多种逻辑糅合在一起,不易后期的维护。当状态机和输出信号较少时,可以尝试此种描述方式。
状态机修改:moore型
由于Moore型的特殊性,在设计的时候就要设计两个信号量,用来标记输出和输入的状态,最后通过assign赋值将值输出。