赞
踩
状态机设计如下:
(0) 首先,根据状态机的个数确定状态机编码。利用编码给状态寄存器赋值,代码可读性更好。
(1) 状态机第一段,时序逻辑,非阻塞赋值,传递寄存器的状态。
(2) 状态机第二段,组合逻辑,阻塞赋值,根据当前状态和当前输入,确定下一个状态机的状态。
(3) 状态机第三代,时序逻辑,非阻塞赋值,因为是 Mealy 型状态机,根据当前状态和当前输入,确定输出信号。
// 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 module 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 ; //(1) state transfer always @(posedge clk or negedge rstn) begin if (!rstn) begin st_cur <= 'b0 ; end else begin st_cur <= st_next ; end end //(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 ; endmodule
将 3 段式状态机 2、3 段描述合并,其他部分保持不变,状态机就变成了 2 段式描述。
修改部分如下:
//(2) state switch, and output logic //all using block assignment for combination-logic reg [1:0] change_r ; reg sell_r ; always @(*) begin //all case items need to be displayed completely case(st_cur) IDLE: begin change_r = 2'b0 ; sell_r = 1'b0 ; case (coin) 2'b01: st_next = GET05 ; 2'b10: st_next = GET10 ; default: st_next = IDLE ; endcase // case (coin) end GET05: begin change_r = 2'b0 ; sell_r = 1'b0 ; case (coin) 2'b01: st_next = GET10 ; 2'b10: st_next = GET15 ; default: st_next = GET05 ; endcase // case (coin) end GET10: case (coin) 2'b01: begin st_next = GET15 ; change_r = 2'b0 ; sell_r = 1'b0 ; end 2'b10: begin st_next = IDLE ; change_r = 2'b0 ; sell_r = 1'b1 ; end default: begin st_next = GET10 ; change_r = 2'b0 ; sell_r = 1'b0 ; end endcase // case (coin) GET15: case (coin) 2'b01: begin st_next = IDLE ; change_r = 2'b0 ; sell_r = 1'b1 ; end 2'b10: begin st_next = IDLE ; change_r = 2'b1 ; sell_r = 1'b1 ; end default: begin st_next = GET15 ; change_r = 2'b0 ; sell_r = 1'b0 ; end endcase default: begin st_next = IDLE ; change_r = 2'b0 ; sell_r = 1'b0 ; end endcase end
将 3 段式状态机 1、 2、3 段描述合并,状态机就变成了 1 段式描述。
修改部分如下:
//(1) using one state-variable do describe reg [1:0] change_r ; reg sell_r ; always @(posedge clk or negedge rstn) begin if (!rstn) begin st_cur <= 'b0 ; change_r <= 2'b0 ; sell_r <= 1'b0 ; end else begin case(st_cur) IDLE: begin change_r <= 2'b0 ; sell_r <= 1'b0 ; case (coin) 2'b01: st_cur <= GET05 ; 2'b10: st_cur <= GET10 ; endcase end GET05: begin case (coin) 2'b01: st_cur <= GET10 ; 2'b10: st_cur <= GET15 ; endcase end GET10: case (coin) 2'b01: st_cur <= GET15 ; 2'b10: begin st_cur <= IDLE ; sell_r <= 1'b1 ; end endcase GET15: case (coin) 2'b01: begin st_cur <= IDLE ; sell_r <= 1'b1 ; end 2'b10: begin st_cur <= IDLE ; change_r <= 2'b1 ; sell_r <= 1'b1 ; end endcase default: begin st_cur <= IDLE ; end endcase // case (st_cur) end // else: !if(!rstn) end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。