自動售飲料機的verilog實現。
每瓶飲料2.5元,可投入0.5與1.0兩種硬幣,具有找零功能。
說明:此處只是功能的簡單實現,沒有過多考慮實際售飲料機功能的完整性,可根據需要在此基礎上進行修改,、。
代碼:
1 module drink_seller(rst_n, 2 clk, 3 buy, 4 money, 5 drink, 6 change 7 ); 8 input rst_n; 9 input clk; 10 input buy; 11 input [1:0] money; 12 13 output drink; 14 output [1:0] change; 15 16 parameter IDLE = 6'b000001; //空閑狀態 17 parameter S0 = 6'b000010; //投幣0.5元 18 parameter S1 = 6'b000100; //投幣0.5元 19 parameter S2 = 6'b001000; //投幣1.0元 20 parameter S3 = 6'b010000; //投幣1.5元 21 parameter S4 = 6'b100000; //投幣2.0元 22 23 reg [5:0] cur_state; 24 reg [5:0] nxt_state; 25 26 reg drink; 27 reg [1:0] change; 28 29 //狀態寄存,時序邏輯 30 always@(posedge clk) 31 if(!rst_n) 32 cur_state <= 6'b0; 33 else 34 cur_state <= nxt_state; 35 36 //狀態轉換,組合邏輯 37 always@(*) 38 if(!rst_n) 39 //nxt_state = 6'b0; 40 nxt_state = IDLE; 41 else 42 begin 43 case(cur_state) 44 IDLE : if(buy) 45 nxt_state = S0; 46 else 47 nxt_state = IDLE; 48 S0 : case(money) //開始投幣 49 2'b00 : nxt_state = S0; 50 2'b01 : nxt_state = S1; 51 2'b10 : nxt_state = S2; 52 2'b11 : nxt_state = S3; 53 endcase 54 S1 : case(money) //已投幣0.5 55 2'b00 : nxt_state = S1; 56 2'b01 : nxt_state = S2; 57 2'b10 : nxt_state = S3; 58 2'b11 : nxt_state = S4; 59 endcase 60 S2 : case(money) //已投幣1.0 61 2'b00 : nxt_state = S2; 62 2'b01 : nxt_state = S3; 63 2'b10 : nxt_state = S4; 64 2'b11 : nxt_state = IDLE; 65 endcase 66 S3 : case(money) //已投幣1.5 67 2'b00 : nxt_state = S3; 68 2'b01 : nxt_state = S4; 69 2'b10 : nxt_state = IDLE; 70 2'b11 : nxt_state = IDLE; 71 endcase 72 S4 : case(money) //已投幣2.0 73 2'b00 : nxt_state = S4; 74 2'b01 : nxt_state = IDLE; 75 2'b10 : nxt_state = IDLE; 76 2'b11 : nxt_state = IDLE; 77 endcase 78 endcase 79 end 80 81 //輸出控制,組合邏輯 82 always@(*) 83 if(!rst_n) 84 begin 85 drink = 1'b0; 86 change = 2'b00; 87 end 88 else begin 89 case(cur_state) 90 IDLE,S0,S1: 91 begin 92 drink = 1'b0; 93 change = 2'b00; 94 end 95 S2 : case(money) 96 2'b11 : 97 begin 98 drink = 1'b1; 99 change = 2'b00; 100 end 101 default : 102 begin 103 drink = 1'b0; 104 change = 2'b00; 105 end 106 endcase 107 S3 : case(money) 108 2'b10 : 109 begin 110 drink = 1'b1; 111 change = 2'b00; 112 end 113 2'b11 : 114 begin 115 drink = 1'b1; 116 change = 2'b01; 117 end 118 default : 119 begin 120 drink = 1'b0; 121 change = 2'b00; 122 end 123 endcase 124 S4 : case(money) 125 2'b01 : 126 begin 127 drink = 1'b1; 128 change = 2'b00; 129 end 130 2'b10 : 131 begin 132 drink = 1'b1; 133 change = 2'b01; 134 end 135 2'b11 : 136 begin 137 drink = 1'b1; 138 change = 2'b11; 139 end 140 default : 141 begin 142 drink = 1'b0; 143 change = 2'b00; 144 end 145 endcase 146 endcase 147 end 148 149 endmodule
testbench:
1 module drink_seller_tb; 2 3 // Inputs 4 reg rst_n; 5 reg clk; 6 reg buy; 7 reg [1:0] money; 8 9 // Outputs 10 wire drink; 11 wire [1:0] change; 12 13 // Instantiate the Unit Under Test (UUT) 14 drink_seller uut ( 15 .rst_n(rst_n), 16 .clk(clk), 17 .buy(buy), 18 .money(money), 19 .drink(drink), 20 .change(change) 21 ); 22 23 parameter CLK_PERIOD = 10; 24 25 initial begin 26 rst_n = 0; 27 clk = 1; 28 buy = 0; 29 money = 0; 30 31 #100; 32 rst_n = 1; 33 # CLK_PERIOD buy = 1; 34 # CLK_PERIOD buy = 0; 35 36 # 100 buy = 1; 37 # CLK_PERIOD buy = 0; 38 39 # 100 buy = 1; 40 41 end 42 43 always #(CLK_PERIOD/2) clk = ~clk; 44 45 always@(posedge clk) 46 if(!rst_n) 47 money = 2'b00; 48 else 49 money = 2'b01; 50 51 endmodule
ISIM仿真結果: