题解 | #自动售卖机#
自动售卖机
https://www.nowcoder.com/practice/487953e6d3e3434988e0dd6960b6c9f8
`timescale 1ns/1ns
module sale(
input clk ,
input rst_n ,
input sel ,//sel=0,5$dranks,sel=1,10&=$drinks
input [1:0] din ,//din=1,input 5$,din=2,input 10$
output reg [1:0] drinks_out,//drinks_out=1,output 5$ drinks,drinks_out=2,output 10$ drinks
output reg change_out
);
//------------------------//
//这个题目有个坑,就是当sel=1,din=1时,即选择购买B饮料且投币5元时,正常输出应该是
//drinks_out=0,change_out=1;即无饮料输出且找零5元(退钱)。
//但是,这个题目要求钱不够时,必须要继续投币,继续购买饮料。
//因此当sel=1,din=1时,输出drinks_out=0,change_out=0;注意此时售卖机内还有5元,
//那么就有可能出现输出B饮料同时找零5元这种情况
//我的思路时按输出结果,划分成6种状态,分别是:
//A:没有饮料输出且没有找零,这个状态也可以作为默认初始状态;
//B:输出A饮料且没有找零;
//C: 输出A饮料且找零;
//D: 输出B饮料且没有找零;
//E: 没有饮料输出且没有找零,但是售卖机内还有5元;
//F: 输出B饮料且找零。
//------------------------//
reg [2:0] state, next_state;
parameter A = 0, B = 1,C = 2, D = 3, E = 4, F = 5;
always @(posedge clk, negedge rst_n) begin
if(!rst_n) begin
state <= A;
end else begin
state <= next_state;
end
end
always @(*) begin
case(state)
A: begin
case({sel,din})
3'b000: next_state <= A;
3'b001: next_state <= B;
3'b010: next_state <= C;
3'b100: next_state <= A;
3'b101: next_state <= E;
3'b110: next_state <= D;
default: next_state <= A;
endcase
end
B: begin
case({sel,din})
3'b000: next_state <= A;
3'b001: next_state <= B;
3'b010: next_state <= C;
3'b100: next_state <= A;
3'b101: next_state <= E;
3'b110: next_state <= D;
default: next_state <= A;
endcase
end
C: begin
case({sel,din})
3'b000: next_state <= A;
3'b001: next_state <= B;
3'b010: next_state <= C;
3'b100: next_state <= A;
3'b101: next_state <= E;
3'b110: next_state <= D;
default: next_state <= A;
endcase
end
D: begin
case({sel,din})
3'b000: next_state <= A;
3'b001: next_state <= B;
3'b010: next_state <= C;
3'b100: next_state <= A;
3'b101: next_state <= E;
3'b110: next_state <= D;
default: next_state <= A;
endcase
end
E: begin
case({sel,din})
3'b100: next_state <= E;
3'b101: next_state <= D;
3'b110: next_state <= F;
default: next_state <= A;
endcase
end
F: begin
case({sel,din})
3'b000: next_state <= A;
3'b001: next_state <= B;
3'b010: next_state <= C;
3'b100: next_state <= A;
3'b101: next_state <= E;
3'b110: next_state <= D;
default: next_state <= A;
endcase
end
endcase
end
always @(*) begin
case(state)
A: drinks_out <= 2'd0;
B: drinks_out <= 2'd1;
C: drinks_out <= 2'd1;
D: drinks_out <= 2'd2;
E: drinks_out <= 2'd0;
F: drinks_out <= 2'd2;
default: drinks_out <= 2'd0;
endcase
end
always @(*) begin
case(state)
A: change_out <= 1'b0;
B: change_out <= 1'b0;
C: change_out <= 1'b1;
D: change_out <= 1'b0;
E: change_out <= 1'b0;
F: change_out <= 1'b1;
default: change_out <= 1'b0;
endcase
end
endmodule