`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