Verilog 实现状态机自动售卖机

Verilog 实现状态机自动售卖机

教学视频:https://www.bilibili.com/video/BV1Ve411x75W?p=33&spm_id_from=pageDriver&vd_source=19ae31dff4056e52d2729a4ca212602b

功能需求

使用1元、2元、5元面值的纸币进行支付,获取6元的物品,不设找零

  • 输入:1元,2元,5元
  • 判定条件:>=6元
  • 输出:可以交货(输入额满足判断条件)

代码思路:使用状态机进行逻辑设计(详细教学可以看最上面的链接)

verilog 复制代码
module vlg_design(
	input 		clk			,
	input 		rst_n		,
	input 		one_yuan	,
	input		two_yuan	,
	input 		five_yuan	,
	
	output 	reg done
);

//变量声明
localparam 	IDLE	=4'd0 ,
			IN_1 	=4'd1 ,
			IN_2 	=4'd2 ,
			IN_3 	=4'd3 ,
			IN_4 	=4'd4 ,
			IN_5 	=4'd5 ,
			IN_6 	=4'd6 ,
			DONE 	=4'd7 ;
			
localparam	MONEY_PAY = 4'd6;

reg [3:0] cstate,nstate;
reg [3:0] money_sum;

//时序逻辑,锁存状态
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		cstate <= IDLE;
	else
		cstate <= nstate;
end

//组合逻辑实现状态变迁
always @(*) begin
	case(cstate)
		IDLE : begin
			if(one_yuan||two_yuan||five_yuan)
				nstate = IN_1;
			else
				nstate = IDLE;
		end
		IN_1 : begin
			if(one_yuan||two_yuan||five_yuan)
				nstate = IN_2;
			else
				nstate = IN_1;
		end		
		IN_2 : begin
			if(money_sum >= MONEY_PAY)
				nstate = DONE;
			else if(one_yuan||two_yuan||five_yuan)
				nstate = IN_3;
			else
				nstate = IN_2;
		end	
		IN_3 : begin
			if(money_sum >= MONEY_PAY)
				nstate = DONE;
			else if(one_yuan||two_yuan||five_yuan)
				nstate = IN_4;
			else
				nstate = IN_3;
		end	
		IN_4 : begin
			if(money_sum >= MONEY_PAY)
				nstate = DONE;
			else if(one_yuan||two_yuan||five_yuan)
				nstate = IN_5;
			else
				nstate = IN_4;
		end	
		IN_5 : begin
			if(money_sum >= MONEY_PAY)
				nstate = DONE;
			else if(one_yuan||two_yuan||five_yuan)
				nstate = IN_6;
			else
				nstate = IN_5;
		end	
		IN_6 : begin
			if(money_sum >= MONEY_PAY)
				nstate = DONE;
			else if(one_yuan||two_yuan||five_yuan)
				nstate = DONE;
			else
				nstate = IN_6;
		end	
		DONE : nstate = IDLE;
		
		default : ;
	endcase
end

//当前状态输入钱币的累计计算
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		money_sum <= 'b0;
	else begin
		case(cstate)
			DONE : money_sum <= 'b0;
			default : begin
				if(one_yuan)
					money_sum <= money_sum + 4'd1;
				else if(two_yuan)                 
					money_sum <= money_sum + 4'd2;
				else if(five_yuan)                
					money_sum <= money_sum + 4'd5;
				else ;
			end
		endcase
	end
end

//状态机的输出赋值
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		done <= 'b0;
	else if(cstate == DONE)
		done <= 1'b1;
	else
		done <= 'b0;
end

endmodule

测试文件:

verilog 复制代码
`timescale 1ns/1ps

module tb_top();


reg clk;
reg rst_n;
reg one_yuan;
reg two_yuan;
reg five_yuan;

wire done;


vlg_design u_vlg_design(
	.clk		(clk),
	.rst_n		(rst_n),
	.one_yuan	(one_yuan),
	.two_yuan	(two_yuan),
	.five_yuan	(five_yuan),

	.done       (done)
);

//产生时钟
initial clk = 1;
always #10 clk = ~clk;

integer i;

//测试激励产生
initial begin
	rst_n = 0;
	one_yuan	=0 ;
	two_yuan	=0 ;
	five_yuan	=0 ;
	#200;
	rst_n = 1;
	
	for(i=0;i<50;i=i+1)begin
		task_random_pay();
	end
	#5000;
	
end

integer random_data;

task task_random_pay;
	begin 
		#1000;
		random_data = {$random}%3;
		@(posedge clk);
		if(random_data == 0)
			one_yuan <= 1'd1;
		else if(random_data == 1)
			two_yuan <= 1'd1;
		else if(random_data == 2)
			five_yuan <= 1'd1;
		@(posedge clk);
			one_yuan	<=0 ;
			two_yuan	<=0 ;
			five_yuan	<=0 ;
	end
endtask

always @(posedge clk) begin
	if(one_yuan)
		$display("Pay 1 yuan.");
	else if(two_yuan)
		$display("Pay 2 yuan.");
	else if(five_yuan)
		$display("Pay 5 yuan.");
	else if(done)
		$display("Got you want.\n*********\n");
	else ;
end

endmodule

仿真结果

波形:

结果:

相关推荐
2603_965148114 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
北京青翼科技6 小时前
青翼基于PCIe总线架构的4路HD-SDI/3G-SDI视频图像模拟源丨图像处理
fpga开发·图像模拟源·fpga开发板·pcie板卡
kaixin_啊啊6 小时前
【用于更准确 G×E 基因组预测的大规模作物数据集与基于深度学习的多模态融合框架】论文学习
人工智能·深度学习·学习
xier_ran6 小时前
【infra之路】AI 编译器学习笔记(六):重拾 C++——lambda 与 MLIR 中的回调
c++·笔记·学习
别动我齐刘海9 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
m4Rk_9 小时前
【论文阅读】Agent 记忆机制(99):PrisMem——从整体分数搜索走向能力驱动的记忆自进化
论文阅读·人工智能·学习·开源·github
涛tao讲道9 小时前
星载FPGA选型与抗辐射设计手册
fpga开发·抗单粒子翻转·涛tao悟道·涛的天道观·seu
艾芯微科技9 小时前
钰泰 ETA6973PQ3Y|QFN3×3 2A 同步降压 Buck,I2C 可配置多档输出,动态调压 PMIC
网络·单片机·嵌入式硬件·fpga开发·集成测试·51单片机
NamoAmitabha12810 小时前
lwIP 问答---deepseek
fpga开发
吉他英雄一里10 小时前
时钟IP核(MMCM PLL)
fpga开发