售货机内有一个 2 元的商品,该售货机可以用 5 角和 1 元两种硬币进行投币,考虑找零。
(1)画出状态转移图;
(2)用Verilog编程;
(3)Modelsim仿真及验证;
分析:
1):有 0 元,0.5元,1元,1.5元这四种状态,考虑使用米利型状态机来实现;
2):din = 0 代表投入的硬币为 5角钱,din = 1,代表投入的硬币为 1元钱;
3):dout_vld = 0代表找零为 0 元,dout_vld = 1则代表找零为 0.5元;
4):dout = 1 代表输出商品,反之则不输出;
解:
(1)状态转移图如下:
(2)代码:
1 // ********************************************************************************* 2 // Project Name : shouhuoji 3 // Email : 4 // Create Time : 2020/07/02 11锛6 5 // Module Name : 6 // editor : qing 7 // Version : Rev1.0.0 8 // ********************************************************************************* 9 10 module shouhuoji( 11 input sclk , 12 input s_rst_n , 13 input din , // 涓鍒欎唬琛ㄨ緭鍏.5鍏冿紝涓鍒欎唬琛ㄨ緭鍏鍏 14 15 output reg dout , // 鍟嗗搧杈撳嚭淇″彿 16 output reg dout_vld // 鎵鹃浂淇″彿锛屼负0鍒欎唬琛ㄤ笉鐢ㄦ壘闆讹紝涓鍒欎唬琛ㄦ壘闆.5鍏 17 ); 18 19 20 //======================================================================== 21 // =========== Define Parameter and Internal signals =========== 22 //========================================================================/ 23 24 reg [3:0] current_state ; 25 reg [3:0] next_state ; 26 27 parameter IDLE = 4'b0001 ; // 0 yuan 28 parameter S0 = 4'b0010 ; // 0.5 yuan 29 parameter S1 = 4'b0100 ; // 1 yuan 30 parameter S2 = 4'b1000 ; // 1.5 yuan 31 32 //============================================================================= 33 //**************************** State Machine ******************************* 34 //============================================================================= 35 36 always @(posedge sclk or negedge s_rst_n) begin 37 if(!s_rst_n) 38 current_state <= IDLE; 39 else 40 current_state <= next_state; 41 end 42 43 always @(*) begin 44 next_state = IDLE; 45 case(current_state) 46 IDLE:begin // 0 47 if(din == 1'b0) 48 next_state = S0; 49 else 50 next_state = S1; 51 end 52 53 S0:begin // 0.5 54 if(din == 1'b0) 55 next_state = S1; 56 else 57 next_state = S2; 58 end 59 60 S1:begin // 1 61 if(din == 1'b0) 62 next_state = S2; 63 else 64 next_state = IDLE; 65 end 66 67 S2:begin // 1.5 68 if(din == 1'b0) 69 next_state = IDLE; 70 else 71 next_state = IDLE; 72 end 73 74 default:begin 75 next_state = IDLE; 76 end 77 endcase 78 end 79 80 always @(posedge sclk or negedge s_rst_n) begin 81 if(!s_rst_n) begin 82 dout <= 1'b0; 83 dout_vld <= 1'b0; 84 end 85 else if((current_state == S1 && din == 1'b1) || (current_state == S2 && din == 1'b0)) begin 86 dout <= 1'b1; 87 dout_vld <= 1'b0; 88 end 89 else if(current_state == S2 && din == 1'b1) begin 90 dout <= 1'b1; 91 dout_vld <= 1'b1; 92 end 93 else begin 94 dout <= 1'b0; 95 dout_vld <= 1'b0; 96 end 97 end 98 99 100 endmodule
testbench:
1 // ********************************************************************************* 2 // Project Name : shouhuoji 3 // Email : 4 // Create Time : 2020/07/02 11:37 5 // Module Name : shouhuoji_tb 6 // editor : qing 7 // Version : Rev1.0.0 8 // ********************************************************************************* 9 10 module shouhuoji_tb; 11 reg sclk ; 12 reg s_rst_n ; 13 reg din ; 14 15 wire dout ; 16 wire dout_vld ; 17 18 shouhuoji shouhuoji_inst( 19 .sclk (sclk ), 20 .s_rst_n (s_rst_n ), 21 .din (din ), 22 .dout (dout ), 23 .dout_vld (dout_vld ) 24 ); 25 26 initial 27 sclk = 1'b0; 28 always #10 sclk = ~sclk; 29 30 initial 31 begin 32 #3; 33 s_rst_n = 1'b0; 34 din = 1'b0; 35 #21; 36 s_rst_n = 1'b1; 37 38 money; 39 #20; 40 money; 41 end 42 43 44 task money; 45 begin 46 #20; 47 din = 1'b0; 48 #25; 49 din = 1'b1; 50 #23; 51 din = 1'b0; 52 #40; 53 54 din = 1'b1; 55 #50; 56 din = 1'b1; 57 #30; 58 59 din = 1'b0; 60 #30; 61 din = 1'b0; 62 #20; 63 din = 1'b0; 64 #21; 65 din = 1'b1; 66 67 #50; 68 end 69 endtask 70 71 endmodule
(3)Modelsim仿真:
附录:
设计一个饮料售卖机,饮料 1 块钱,硬币有 5 角,1 元两种,考虑找零;
1:画出fsm
2:用Verilog 编程;
解:
1):状态转移图:
略
2):Verilog 代码:
1 // ********************************************************************************* 2 // Project Name : shouhuoji 3 // Email : 4 // Create Time : 2020/07/02 21:52 5 // Module Name : shouhuoji 6 // editor : qing 7 // Version : Rev1.0.0 8 // ********************************************************************************* 9 10 module shouhuoji( 11 input sclk , 12 input s_rst_n , 13 14 input din , 15 16 output reg dout , // 输出商品标志 17 output reg dout_vld // 为0,则不找零;为1,则找零0.5元 18 ); 19 20 21 reg [1:0] current_state ; 22 reg [1:0] next_state ; 23 24 parameter IDLE = 2'd0 ; 25 26 parameter S0 = 2'd1 ; 27 28 29 //============================================================================= 30 //**************************** State Machine ******************************* 31 //============================================================================= 32 33 always @(posedge sclk or negedge s_rst_n) begin 34 if(!s_rst_n) 35 current_state <= IDLE; 36 else 37 current_state <= next_state; 38 end 39 40 always @(*) begin 41 next_state = IDLE; 42 case(current_state) 43 IDLE:begin 44 if(din == 1'b0) 45 next_state = S0; 46 else 47 next_state = current_state; 48 end 49 50 S0:begin 51 if(din == 1'b1) 52 next_state = IDLE; 53 else 54 next_state = IDLE; 55 end 56 57 default:begin 58 next_state = IDLE; 59 end 60 endcase 61 end 62 63 always @(posedge sclk or negedge s_rst_n) begin 64 if(!s_rst_n) begin 65 dout <= 1'b0; 66 dout_vld <= 1'b0; 67 end 68 else if((current_state == IDLE && din == 1'b1) || (current_state == S0 && din == 1'b0)) begin 69 dout <= 1'b1; 70 dout_vld <= 1'b0; 71 end 72 else if(current_state == S0 && din == 1'b1) begin 73 dout <= 1'b1; 74 dout_vld <= 1'b1; 75 end 76 end 77 78 endmodule
如有疏漏或不当之处,还望各位道友指正~