6.3 Verilog 状态机

发布网友 发布时间:2024-10-19 23:06

我来回答

1个回答

热心网友 时间:2024-10-19 23:21

有限状态机(FSM),简称状态机,是一种表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。在电路设计的系统级和 RTL 级,状态机不仅是一种电路的描述工具,而且也是一种思想方法,具有广泛的应用。


Verilog 中状态机主要用于同步时序逻辑的设计,能在有限个状态之间按一定要求和规律切换时序电路的状态。状态的切换不仅取决于输入值,还取决于当前所在状态。状态机可以分为两类:Moore 状态机和 Mealy 状态机。


Moore 型状态机


Moore 型状态机的输出只与当前状态有关,与当前输入无关。输出会在一个完整的时钟周期内保持稳定,即使此时输入信号有变化,输出也不会变化。输入对输出的影响要到下一个时钟周期才能反映出来。这也是 Moore 型状态机的一个重要特点:输入与输出是隔离开来的。


Mealy 型状态机


Mealy 型状态机的输出不仅与当前状态有关,还取决于当前的输入信号。Mealy 型状态机的输出是在输入信号变化以后立刻发生变化,且输入变化可能出现在任何状态的时钟周期内。因此,同种逻辑下,Mealy 型状态机输出对输入的响应会比 Moore 型状态机早一个时钟周期。


在设计状态机时,一般使用最多的是 Mealy 型 3 段式状态机。下面将通过设计一个自动售卖机的具体实例来说明状态机的设计过程。


自动售卖机


自动售卖机的功能描述如下:饮料单价 2 元,该售卖机只能接受 0.5 元、1 元的硬币。考虑找零和出货。投币和出货过程都是一次一次的进行,不会出现一次性投入多币或一次性出货多瓶饮料的现象。每一轮售卖机接受投币、出货、找零完成后,才能进入到新的自动售卖状态。


该自动售卖机的工作状态转移图如下所示,包含了输入、输出信号状态。


其中,coin = 1 代表投入了 0.5 元硬币,coin = 2 代表投入了 1 元硬币。


下面给出自动售卖机状态机设计的具体步骤:


1. 状态机设计:3 段式(推荐)


设计一个自动售卖机状态机时,使用 3 段式设计是最推荐的。具体设计流程如下:


实例 // vending-machine // 2 yuan for a bottle of drink // only 2 coins supported: 5 jiao and 1 yuan // finish the function of selling and changing mole vending_machine_p3 ( input clk , input rstn , input [1:0] coin , //01 for 0.5 jiao, 10 for 1 yuan output [1:0] change , output sell //output the drink ); //machine state decode parameter IDLE = 3'd0 ; parameter GET05 = 3'd1 ; parameter GET10 = 3'd2 ; parameter GET15 = 3'd3 ; //machine variable reg [2:0] st_next ; reg [2:0] st_cur ;


此设计流程包括状态转移、状态切换、输出逻辑三个关键部分。


实例 // (2) state switch, using block assignment for combination-logic //all case items need to be displayed completely always @(*) begin //st_next = st_cur ;//如果条件选项考虑不全,可以赋初值消除latch case(st_cur) IDLE: case (coin) 2'b01: st_next = GET05 ; 2'b10: st_next = GET10 ; default: st_next = IDLE ; endcase GET05: case (coin) 2'b01: st_next = GET10 ; 2'b10: st_next = GET15 ; default: st_next = GET05 ; endcase GET10: case (coin) 2'b01: st_next = GET15 ; 2'b10: st_next = IDLE ; default: st_next = GET10 ; endcase GET15: case (coin) 2'b01,2'b10: st_next = IDLE ; default: st_next = GET15 ; endcase default: st_next = IDLE ; endcase end


实例 // (3) output logic, using non-block assignment reg [1:0] change_r ; reg sell_r ; always @(posedge clk or negedge rstn) begin if (!rstn) begin change_r <= 2'b0 ; sell_r <= 1'b0 ; end else if ((st_cur == GET15 && coin ==2'h1) || (st_cur == GET10 && coin ==2'd2)) begin change_r <= 2'b0 ; sell_r <= 1'b1 ; end else if (st_cur == GET15 && coin == 2'h2) begin change_r <= 2'b1 ; sell_r <= 1'b1 ; end else begin change_r <= 2'b0 ; sell_r <= 1'b0 ; end end assign sell = sell_r ; assign change = change_r ; endmole


以上设计流程确保了自动售卖机在不同状态之间正确切换,并在正确状态时执行输出逻辑。


接下来,给出自动售卖机的 testbench 设计示例,用于验证状态机设计的正确性。在仿真中,模拟了 4 种情景,分别对应不同的投币顺序。


在设计测试例时,需要考虑不同的硬币投递顺序和状态转移情况,确保状态机在各种场景下都能正确工作。


例如,在 case1 中,连续投入 4 个 5 角硬币;case2 中,先投入 1 元硬币,再投入 5 角硬币,然后再投入 1 元硬币;case3 中,先投入 5 角硬币,再投入 1 元硬币,再投入 5 角硬币;case4 中,连续投入 3 个 5 角硬币,然后再投入 1 元硬币。


通过这些测试情景,可以验证自动售卖机状态机设计的正确性和鲁棒性。


总之,通过以上步骤和实例,可以清楚地了解如何使用 Verilog 设计一个自动售卖机状态机,确保其在不同投币和出货情况下的正确工作。同时,通过比较不同状态机设计(如 2 段式、1 段式和 Moore 型状态机)之间的差异,可以更深入地理解状态机设计的原理和方法。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com