【附源码】基于fpga的自动售货机(使用三段式状态机实现)

news2024/12/23 22:26:39

目录

1、VL38 自动贩售机1

题目介绍

思路分析

代码实现

仿真文件

2、VL39 自动贩售机2

题目介绍:

题目分析

代码实现

仿真文件

3、状态机基本知识


1、VL38 自动贩售机1

题目介绍

        设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。

ps:

        1、投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号

        2、注意rst为低电平复位

信号示意图:

波形示意图:

思路分析

代码实现

module seller1(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,			//0.5元
	input wire d2 ,			//1.0元
	input wire d3 ,			//2.0元
	
	output reg 		out1,	//饮料
	output reg [1:0]out2	//零钱
);
//*************code***********//


parameter [2:0]	s0 = 3'b000,
				s1 = 3'b001,		
				s2 = 3'b010,
				s3 = 3'b011,
				s4 = 3'b100,	
				s5 = 3'b101,
				s6 = 3'b110;
						
reg [2:0] curr_state;
reg [2:0] next_state;

//第一段 状态转移
always @(posedge clk or negedge rst)begin
	if(!rst)
		curr_state <= s0;
	else
		curr_state <= next_state;
	end

//第二段 转移状况
always @(*)begin
	case(curr_state)
		s0:begin	
			if(d1) 		next_state = s1;
			else if(d2) next_state = s2;
			else if(d3) next_state = s3;
			else 		next_state = next_state;	//为什么保持原值next_state,而不是s0?
		   end
		s1:begin	
			if(d1) 		next_state = s2;
			else if(d2) next_state = s4;
			else if(d3) next_state = s5;
			else 		next_state = next_state;
		   end
		s2:begin	
			if(d1) 		next_state = s4;
			else if(d2) next_state = s3;
			else if(d3) next_state = s6;
			else 		next_state = next_state;
		   end
		s3,s4,s5,s6:begin next_state = s0;end	
		default: begin next_state = s0;end
	endcase	   
end
	
//第三段 状态输出 moore FSM

always @(posedge clk or negedge rst)begin	//为什么用时序电路,而不是组合电路?
	if(!rst)
		out1 <= 0;
	else if(	
		next_state == s3 || 
		next_state == s4 || 
		next_state == s5 || 
		next_state == s6
	)
		out1 <= 1;	//出货标志
	else
		out1 <= 0;	
	end

always @(posedge clk or negedge rst)begin  //为什么用时序电路,而不是组合电路?
	if(!rst)
		out2 <= 0;
	else if(next_state == s3)
		out2 <= 2'd1;	//找零5毛的数量	
	else if(next_state == s5)
		out2 <= 2'd2;	
	else if(next_state == s6)
		out2 <= 2'd3;				
	else
		out2 <= 2'b0;	
	end

//*************code***********//
endmodule

针对代码中的问题“为什么保持原值next_state,而不是s0?”

答:如下图所示,如果保持s0,因为是组合逻辑,且输入信号d1为半个时钟周期,那么就会导致next_state在s1和s0之间翻转,而不是保持正确的状态s1。

 参考这个回答:

仿真文件

仿真图:

仿真代码:

module tb_seller1;
	
	reg clk;
	reg rst;
	reg d1,d2,d3;	
	
	wire 		out1;
	wire [1:0] 	out2; 
	
//1、初始化
initial begin
	clk = 0;
	rst = 0;
	d1 = 0;
	d2 = 0;
	d3 = 0;
end	
		
//2、产生激励
always #5 clk = ~clk;
	
initial begin
	#10;
	rst = 1'b1;
	
	#20;
	@(posedge clk); {d1,d2,d3}=3'b100;	//0.5
	@(posedge clk); {d1,d2,d3}=3'b000;	
	#50;                    
	@(posedge clk); {d1,d2,d3}=3'b010;	//1.5
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#30;                    
	@(posedge clk); {d1,d2,d3}=3'b100;	//0.5
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#60;                    
	@(posedge clk); {d1,d2,d3}=3'b100;	//1
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#50;                    
	@(posedge clk); {d1,d2,d3}=3'b001;	//3
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#50;                    
	@(posedge clk); {d1,d2,d3}=3'b001;	//2
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#30;                    
	@(posedge clk); {d1,d2,d3}=3'b100;	//0.5
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#60;                    
	@(posedge clk); {d1,d2,d3}=3'b001;	//2.5
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#50;                    
	@(posedge clk); {d1,d2,d3}=3'b010;	//1
	@(posedge clk); {d1,d2,d3}=3'b000;		
	#60;                    
	@(posedge clk); {d1,d2,d3}=3'b010;	//2
	@(posedge clk); {d1,d2,d3}=3'b000;		
end	
	
//3、仿真暂停
initial begin
	#1000 
	$finish();
end		
	
//4、实例化
seller1 u1_seller1(
	.clk(clk),
	.rst(rst),
	.d1 (d1),		//0.5元
	.d2 (d2),		//1.0元
	.d3 (d3),		//2.0元
	.out1(out1),	//饮料
	.out2(out2)		//零钱
);
	
endmodule

2、VL39 自动贩售机2

题目介绍:

        设计一个自动贩售机,输入货币有两种,为0.5/1元,饮料价格是1.5/2.5元,要求进行找零,找零只会支付0.5元。

ps:

        1、投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号

        2、此题忽略出饮料后才能切换饮料的问题

        注意rst为低电平复位

波形示意图:

题目分析

代码实现

module seller2(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,			//0.5元
	input wire d2 ,			//1.0元
	input wire sel ,		//0选择1.5元、1选择2.5元
		
	
	output reg 		out1,	//饮料1(1.5元)
	output reg 		out2,	//饮料2(2.5元)
	output reg [1:0]out3	//零钱
	
);
//*************code***********//


parameter [2:0]	s0 = 3'b000,
				s1 = 3'b001,		
				s2 = 3'b010,
				s3 = 3'b011,
				s4 = 3'b100,	
				s5 = 3'b101,
				s6 = 3'b110;
						
reg [2:0] curr_state;
reg [2:0] next_state;

//第一段 状态转移
always @(posedge clk or negedge rst)begin
	if(!rst)
		curr_state <= s0;
	else
		curr_state <= next_state;
	end

//第二段 转移状况
always @(*)begin
	case(curr_state)
		s0:	begin
				if(d1) 		next_state = s1;
				else if(d2) next_state = s2;
				else 		next_state = next_state;	
			end
		s1:	begin	
				if(d1) 		next_state = s2;
				else if(d2) next_state = s3;
				else 		next_state = next_state;	
			end
		s2:	begin
				if(d1) 		next_state = s3;
				else if(d2) next_state = s4;
				else 		next_state = next_state;	
			end
		s3:	begin	
			if(!sel)  	//选择饮料是1.5元还是2元
				begin next_state = s0; end		
			else begin 
				if(d1) 		next_state = s4;
				else if(d2) next_state = s5;
				else 		next_state = next_state;
			end
			end
		s4:	begin	
			if(!sel) 
				begin next_state = s0; end		
			else begin 
				if(d1) 		next_state = s5;
				else if(d2) next_state = s6;
				else 		next_state = next_state;
			end
			end		   
		s5:	begin next_state = s0; end
		s6:	begin next_state = s0; end	
		default: begin next_state = s0;end
	endcase	   
end
	
/********* 第三段 状态输出 moore FSM ************/

//出货标志
always @(posedge clk or negedge rst)begin	
	if(!rst)begin
		out1 <= 0;
		out2 <= 0;
	end	
	else if(sel==0 && (next_state == s3 || next_state == s4) )
		out1 <= 1;	//饮料1 
	else if(sel==1 && (next_state == s5 || next_state == s6) )
		out2 <= 1;	//饮料2 	
	else begin
		out1 <= 0;
		out2 <= 0;
	end		
end

//找零数量
always @(posedge clk or negedge rst)begin 
	if(!rst)
		out3 <= 0;	
	else if(sel==0 && (next_state == s4) )
		out3 <= 2'd1;	//饮料1 
	else if(sel==1 && (next_state == s6) )
		out3 <= 2'd1;	//饮料2 					
	else
		out3 <= 2'b0;	
end

//*************code***********//
endmodule

仿真文件

仿真图如下:

3、状态机基本知识

 


以上是mealy和moore型状态机的实现区别,注意在代码里理解!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135359.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式Linux驱动开发笔记(八)

嵌入式Linux驱动开发笔记&#xff08;八&#xff09; 交叉编译工具说明&#xff1a; 正点原子提供两种交叉编译工具链。这两种交叉编译工具链解释如下图。 我们只需要知道上面的第二种通用的交叉编译器去学习【正点原子】 I.MX6U 嵌入式 Linux 驱动开发指南这本教程。第一种…

lscpu查看cpu信息

$ lscpu Architecture: x86_64 # 架构CPU op-mode(s): 32-bit, 64-bitAddress sizes: 45 bits physical, 48 bits virtualByte Order: Little Endian # 字节序 CPU(s): 2 # 逻辑cpu数On-line CPU(s) list: 0,1 Vendo…

GitHub上 7 个Spring Boot 优质开源项目

前后端分离已经在慢慢走进各公司的技术栈&#xff0c;不少公司都已经切换到这个技术栈上面了。即使贵司目前没有切换到这个技术栈上面&#xff0c;松哥也非常建议大家学习一下前后端分离开发&#xff0c;以免在公司干了两三年&#xff0c;SSH 框架用的滚瓜烂熟&#xff0c;出来…

hcip第四天实验

实验步骤 配置ip 所有设备可以与公网可以通信&#xff0c;在边界路由器上配置缺省指向ISP 配置普通GRE 启OSPF&#xff0c;对于不规则区域使用重发布 优化LSA更新量 R5&#xff1a; [r5]acl 2000 [r5-acl-basic-2000]rule permit source any [r5]int GigabitEthernet…

数据库知识

关系数据库标准语言SQL 写在开头这一章应该把更多的功夫放在实践上面&#xff0c;书中的语句繁杂多样&#xff0c;不亲自写一写是不容易学会的。其次&#xff0c;理论学了那么多&#xff0c;不会有人不想实践敲一下吧[doge]&#xff1f;建议先搞数据更新中的插入数据后再看查询…

【回答问题】ChatGPT上线了!写出coco数据集的图像分类训练和预测函数代码?

写出coco数据集的图像分类训练代码 好的&#xff0c;我会尽力写出图像分类训练代码。首先&#xff0c;你需要准备好 COCO 数据集的图像和标签&#xff0c;并将其转换成适合你模型使用的格式。其次&#xff0c;你需要选择一个图像分类模型&#xff0c;并定义好模型的结构。接下…

【课程太贵,学习无门,让你们了解CSS3入门知识】

文章目录‍❤️‍&#x1f525;CSS简介‍‍‍‍❤️‍&#x1f525;CSS选择器❣️选择器一❣️选择器二❣️关系选择器‍❤️‍&#x1f525;CSS属性❣️字体属性❣️背景属性❣️文本属性❣️表格属性‍❤️‍&#x1f525;CSS文档流‍❤️‍&#x1f525;CSS浮动‍❤️‍&…

【编程导航】设计模式学习笔记

设计模式日常学习(一)设计模式 软件设计模式的概念 软件设计模式&#xff08;Software Design Pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的…

windows下编译dtkwidget

参考 https://blog.csdn.net/yuxue321/article/details/109552210 步骤 安装官方qt5.12.3&#xff0c;安装时勾选64位版本、32位版本 下载glib和pkg&#xff0c;到mingw73_32目录下&#xff0c;解压到当前文件夹 https://brltty.app/archive/Windows/MinGW/glib_2.34.3-1_wi…

【大数据】Hadoop完全分布式配置(超详细)

文章目录概述1.准备Linux2.安装JDK3.克隆两台虚拟机4.免密登陆5.安装Hadoop6.配置Hadoop配置文件7.启动服务8.在集群上测试一个jar包-单词统计的功能问题总结概述 Hadoop完全分布式配置-具体步骤如下 默认前提&#xff1a; 1.在Windows平台下安装Vmware平台&#xff08;默认已…

数据库的三大范式

数据库的三大范式 设计关系数据库时&#xff0c;需要遵从不同的规范要求&#xff0c;设计出合理的关系型数据库&#xff0c;这些不同的规范要求被称为不同的范式&#xff0c;越高的范式数据冗余度越低。 实际开发中涉及到的范式一般有三种&#xff1a;第一范式、第二范式、第…

WindowsTerminal_01 配置SSH连接

文章目录1 前言2 过程参考1 前言 windows terminal 功能强大&#xff0c;可以自定义终端。由于实验需求&#xff0c;需要用到Linux服务器&#xff0c;所以打算使用Windows Termial 来配置终端&#xff0c;以此来方便地登录服务器&#xff0c;执行一些简单的命令 2 过程 自定…

MongoDB基础

目录简介安装基操pymongo简介 MongoDB 是一个非关系型数据库非常适合超大数据集的存储&#xff0c;由 C 语言编写&#xff0c;旨在为 WEB 应用提供可扩展的高性能数据存储解决方案MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰…

TC275——03开发环境搭建

开发环境与工具链的搭配有很多&#xff0c;这里选择最省事的英飞凌自己推出的一款基于eclipse的IDE&#xff0c;主要是学习&#xff0c;不用于商业用途。 安装ADS开发环境 下载网址&#xff1a; AURIX™ Development Studio - Infineon Technologies 下载这个安装包 双击安装…

Springboot-Vue项目框架每部分的介绍

Springboot-Vue项目框架每部分的介绍 文章目录Springboot-Vue项目框架每部分的介绍前端后端前端 后端 如上图所示&#xff0c;在Springboot项目中&#xff0c;目录结构有代码层结构和资源文件的结构 SpringBoot项目框架对工程结构并没有特殊的限制&#xff0c;只要是良好的工程…

C语言--图书管理项目

C语言图书管理系统项目 第一节 C 语言基础以及基本数据类型 第二节 C 语言运算符 第三节 C 语言控制语句 第四节 C 语言自定义函数 第五节 C 语言修饰变量的关键字 第六节 C 语言构造数据类型–数组 第七节 C 语言字符串 第八节 C 语言指针 第九节 指针与函数、指针函数、函数…

【Linux多线程编程】1. 多线程与单线程

什么是单线程 在描述什么是多线程之前&#xff0c;先讲讲什么是单线程。 int var 100; // 全局变量 var&#xff0c;初始值为 100 void func(){var 100;std::cout << "now var is: " << var << std::endl; // c 语法&#xff0c;意思为输出 va…

【强训】day02

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、选择二、 编程1. 排序子序列2. 倒置字符串答案1. 选择2. 编程普通小孩也要热爱生活&#xff01; 一、选择 阅读如下代码。 请问&#xff0c;对语句行 test.hello(). 描述正确的有&#xff08;&#xff09; pa…

网站备案信息查询,网站备案号在哪里查询

网站备案号一般是在工信部官方查询&#xff0c;也可以使用第三方工具查询。 1、使用工信部域名信息备案管理系统网站查询 打开工信部的域名信息备案管理系统网站https://beian.miit.gov.cn/&#xff0c;点击ICP备案信息查询&#xff0c;添加需要查询的域名&#xff08;网站网址…

Drools基础与实现(操作实例)

简介&#xff1a; Drools 是用 Java 语言编写的开放源码规则引擎&#xff0c;使用 Rete 算法对所编写的规则求值。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则&#xff0c;从而便于学习和理解。并且&#xff0c;还可以将 Java 代码直接嵌入到规则…