自动收售报机

设计一个自动售报机,报纸价钱为八角,纸币有1角,2角,5角,一元。该自动售报机不考虑投币为大额面值等特殊情况。
下图为自动售报机的状态转移图:

在这里插入图片描述
S0~S7为状态机的8个状态,下角标代表已投币的总和,八个状态分别代表没有投币、已投币1角、已投币2角、已投币3角、已投币4角、已投币5角、已投币6角、已投币7角。
M代表输入,M1表示投入1角硬币,M2表示投入2角硬币,M5表示投入5角硬币,M10表示投入一元。
data_out = 1表示给出报纸,data_out_return1 = 1表示找回1角硬币,data_out_return2 = 1表示找回2角硬币。
代码如下:

module auto_sellor(current_state, data_out, data_out_return1, data_out_return2, clk, rst_n, data_in);
	parameter state_width = 3, data_in_width = 3;
	output [state_width-1:0]current_state;
	output data_out, data_out_return1, data_out_return2;
	input [data_in_width-1:0]data_in;
	input clk, rst_n;
	reg [state_width-1:0]current_state, next_state;
	reg data_out, data_out_return1, data_out_return2;
	always@(current_state or data_in)
		case(current_state)
			3'b000:case(data_in)//0
				3'b000:begin
					next_state <= 3'b000;//0+0=0
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b001;//0+1=1
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b010;//0+2=2
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b011:begin
					next_state <= 3'b101;//0+5=5
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b100:begin
					next_state <= 3'b000;//0+10=10
					data_out <= 1'b1;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b1;
				end
			endcase
			3'b001:case(data_in)//1
				3'b000:begin
					next_state <= 3'b001;//1+0=0
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b010;//1+1=2
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b011;//1+2=3
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b011:begin
					next_state <= 3'b110;//1+5=6
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
			endcase
			3'b010:case(data_in)//2
				3'b000:begin
					next_state <= 3'b010;//2+0=2
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b011;//2+1=3
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b100;//2+2=4
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b011:begin
					next_state <= 3'b111;//2+5=7
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
			endcase
			3'b011:case(data_in)//3
				3'b000:begin
					next_state <= 3'b011;//3+0=3
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b100;//3+1=4
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b101;//3+2=5
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b011:begin
					next_state <= 3'b000;//3+5=8
					data_out <= 1'b1;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
			endcase
			3'b100:case(data_in)//4
				3'b000:begin
					next_state <= 3'b000;//4+0=4
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b101;//4+1=5
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b110;//4+2=6
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b011:begin
					next_state <= 3'b000;//4+5=9
					data_out <= 1'b1;
					data_out_return1 <= 1'b1;
					data_out_return2 <= 1'b0;
				end
			endcase
			3'b101:case(data_in)//5
				3'b000:begin
					next_state <= 3'b101;//5+0=5
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b110;//5+1=6
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b111;//5+2=7
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b011:begin
					next_state <= 3'b000;//5+5=10
					data_out <= 1'b1;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b1;
				end
			endcase
			3'b110:case(data_in)//6
				3'b000:begin
					next_state <= 3'b110;//6+0=6
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b111;//6+1=7
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b010:begin
					next_state <= 3'b000;//6+2=8
					data_out <= 1'b01
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
			endcase
			3'b111:case(data_in)//7
				3'b000:begin
					next_state <= 3'b111;//7+0=7
					data_out <= 1'b0;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
				3'b001:begin
					next_state <= 3'b000;//7+1=8
					data_out <= 1'b1;
					data_out_return1 <= 1'b0;
					data_out_return2 <= 1'b0;
				end
			endcase
		endcase
		always@(posedge clk or rst_n)
			if(!rst_n)
				current_state <= 3'b000;
			else
				current_state <= next_state;

endmodule

上述代码中大的case语句里current_state分别对应S0到S7,即当前已投币的数目总和;而每个大case中的小case里的data_in则对应M0,M1,M2,M5,M10这几个投入硬币的数目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值