1.題目: 飲料1.5 元, 可投入硬幣1 元 0.5 元,輸出飲料 零錢
2. 畫出狀態機。
3.模擬結果:coin=1 --> 0.5 元 coin=2-->1元
4.關鍵程式碼分析:
本次設計採用了5個狀態,輸出結果採用暫存器輸出,確保輸出後穩定可靠,採用的是case(nx_state )語句輸出判斷的結果,提前一個週期判斷,就可以確保輸出與當前狀態想要的條件到達時的輸出條件一直。如上在S3 狀態時,直接輸出10,S4狀態時,直接輸出11. 同樣的功能還可以用assign 語句,assign {drink_out,change}=(state==S3)?10:00; 但這是組合邏輯輸出形式。對於後續模組時序上不太友好。
5.完整程式碼:
module auto_machine( input clk,rst_n, input [1:0] coin, output reg drink_out, change );//coin =0 no coin ,coin =1--->0.5 yuan coin =2---> 1 yuan reg [2:0] state,nx_state; parameter [2:0] IDLE=3'd0,S1=3'd1,S2=3'd2 ,S3=3'd3,S4=3'd4; always @(posedge clk or negedge rst_n) if(!rst_n) state<=IDLE; else state<=nx_state; always @(*) begin nx_state=IDLE; case(state) IDLE: if(coin==2'd1) nx_state=S1;else if(coin==2'd2) nx_state=S2; else nx_state=IDLE; S1: if(coin==2'd1) nx_state=S2;else if(coin==2'd2) nx_state=S3; else nx_state=S1; S2: if(coin==2'd1) nx_state=S3;else if(coin==2'd2) nx_state=S4; else nx_state=S2; S3: nx_state=IDLE; S4: nx_state=IDLE; default:nx_state=IDLE; endcase end always @(posedge clk or negedge rst_n) if(!rst_n) {drink_out, change}<='b0; else case(nx_state) S3: {drink_out, change}<=10; S4: {drink_out, change}<=11; endcase endmodule
6.測試程式碼;
`timescale 1ns/1ps module auto_tb(); reg rst_n,clk; reg [1:0]coin; wire drink_out, change; initial begin rst_n=0; clk=0; coin=2'd0; #100 rst_n=1; #10 coin=2'd1; #20 coin=2'd0; #20 coin=2'd1; #20 coin=2'd1; //have drink_out #20 coin=2'd1; #20 coin=2'd2; //have drink_out #20 coin=2'd2; #20 coin=2'd2; //have drink_out and change out #20 coin=2'd2; end always #10 clk=~clk; auto_machine auto2( clk,rst_n, coin, drink_out, change ); endmodule