基于fpga的自动售货机(三段式状态机)

news2024/9/25 19:17:24

目录

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/129949.html

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

相关文章

JS概览 (JS基础 DOM BOM)

目录 JavaScript JS基础 JS数据类型 函数 变量的作用域 作用域链 预解析 DOM DOM树 获取元素的方法 事件高级 注册和解绑事件 DOM事件流 BOM 和DOM的区别 window 对象的常见事件 window.onload JS执行机制 具体的执行流程 例子 JavaScript JS基础 JS数据类…

鉴源论坛 · 观模丨基于AUTOSAR的TTCAN通信协议的形式化建模与分析

作者 | 郭建 上海控安可信软件创新研究院特聘专家 版块 | 鉴源论坛 观模 汽车工业发展至今&#xff0c;硬件方面如车身材料、发动机等已无太大升值空间&#xff0c;而汽车电子则有着广阔的前景。为此各大汽车厂商对汽车电子的研究都投入了大量的人力财力。2003 年&#xff0c…

链式二叉树的代码总结

今天我带来链式二叉树的代码总结。 目录前言链式二叉树代码实现的五个文档二叉树的例子前序遍历中序遍历后序遍历层序遍历求结点个数的函数求叶子的个数的函数求k层结点个数的函数查找某一个值的函数求二叉树高度的函数判断二叉树是否是完全二叉树的函数开辟二叉树结点的函数销…

【设计模式】工厂方法模式

简单工厂模式的弊端 在简单工厂模式中只提供一个工厂类&#xff0c;该工厂类处于对产品类进行实例化的中心位置&#xff0c;它需要知道每一个产品对象的创建细节&#xff0c;并决定何时实例化哪一个产品类。简单工厂模式最大的缺点是当有新产品要加入到系统中时&#xff0c;必…

实现isReactive和isReadonly

08_实现isReactive和isReadonly 一、实现isReactive isReactive: 检查一个对象是否是由 reactive 创建的响应式代理。 1. 单元测试 // src/reactivity/tests/reactive.spec.tsimport { reactive, isReactive } from ../reactive;describe(reactive, function () {it(happy pa…

Callable接口

前言 获取多线程的方法&#xff0c;我们都知道有三种&#xff0c;还有一种是实现Callable接口 实现Runnable接口实现Callable接口实例化Thread类使用线程池获取Callable接口 Callable接口&#xff0c;是一种让线程执行完成后&#xff0c;能够返回结果的 在说到Callable接口…

【Unity天空盒】卡通渲染中如何实现云的消散效果

写在前面 完成大气渲染之后&#xff0c;接下来就是考虑云渲染了。因为我想做的天空盒本身是想跟着这位大佬Unity 卡通渲染 程序化天空盒 - 知乎里叙述的进程来的&#xff0c;里面云实现的是原神里的云&#xff0c;原神又是在崩3的基础上加上了消散效果。但现在能找到的一些教程…

线程中的sleep, yield, join

1. 前言 今天以具体实例的方法来详细记录下实战中的sleep, yield, join。 到底是什么意思&#xff0c;应该怎么用呢&#xff1f;&#xff1f;&#xff1f; 2. 适合人群 对该类方法的概念比较模糊的人 3. 开始 3.1 sleep 此方法是一个静态方法&#xff0c;可以通过类名直接调…

【MyBatis】安装 + 框架搭建 + 使用 + 优化(全程一条龙服务讲解~)

目录 前言 一、准备工作 1.1、下载MyBatis 1.2、数据库设计 二、搭建框架 2.1、创建Maven项目 2.2、jar包、引入依赖 2.3、创建MyBatis核心配置文件 2.4、映射文件 2.5、通过junit测试功能 2.6、框架优化 三、小结——注意事项 前言 本篇全程从0到1搭建MyBatis框架…

Python编程 简单春节倒计时教程(附源代码)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.应用的技术 1.Tkinter 2.PHotoimage 函数 3.label组件 二.效果图 三…

pytorch 咖啡豆识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第P6周&#xff1a;好莱坞明星识别&#x1f356; 作者&#xff1a;K同学啊一、前期准备 1.设置GPU import torch from torch import nn …

2022 年 pnpm 为什么这么火?

pnpm是 Node.js 的替代包管理器。它是 npm 的直接替代品&#xff0c;但速度更快、效率更高。 为什么更有效率&#xff1f;当你安装一个包时&#xff0c;我们将它保存在你电脑上的全局存储中&#xff0c;然后我们从它创建一个硬链接而不是复制。也就是说&#xff1a;对于模块的…

8.移动端学习-rem适配方案

1.适配方案 1、当设备尺寸发生变化时&#xff0c;页面宽高等比例变化 2、使用媒体查询根据不同设备按比例设置html字体大小&#xff0c;页面元素使用rem做单位&#xff0c;当html字体大小变化&#xff0c;元素尺寸也会发生变化&#xff0c;从而达到等比缩放的适配 2.rem实际开…

ubuntu18.04运行ORB_SLAM2

1、基础工具安装 安装cmake、git、gcc、g。 sudo apt-get install cmake git gcc g 2、安装Eigen库 在终端输入以下代码。 sudo apt-get install libeigen3-dev 3、安装Pangolin0.5 版本过高会导致错误&#xff0c;安装依赖项。 sudo apt-get install libglew-dev libpyth…

Hadoop之Hdfs

一、基本概述 1、定义 HDFS&#xff08;Hadoop Distributed File System&#xff09;&#xff0c;它是一个文件系统&#xff0c;用于存储文件&#xff0c;通过目 录树来定位文件&#xff1b;其次&#xff0c;它是分布式的。HDFS 的使用场景&#xff1a;适合一次写入&#xff0…

这是长新冠,还是我老了?浙江出国抢订单又抢CTO;脉脉发布人才迁徙报告;元宇宙产业生态图谱;GitHub今日热榜 | ShowMeAI资讯日报

&#x1f440;日报合辑 | &#x1f3a1;AI应用与工具大全 | &#x1f514;公众号资料下载 | &#x1f369;韩信子 &#x1f3a1; 这是长新冠&#xff0c;还是我老了&#xff1f; 感染后身体出现了疲劳、关节疼痛、咳嗽等新症状&#xff1f;你并不孤单&#xff01;约翰霍普金斯…

数据结构进阶 二叉树OJ题一

作者&#xff1a;小萌新 专栏&#xff1a;数据结构进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍几道二叉树的oj题 二叉树OJ题题目一 根据二叉树创建字符串题目二 二叉树的层序遍历题目三 二叉树的最近公共祖先题目一 根据…

自动化信息治理:推动价值、安全性和合规性

现代组织充斥着数据&#xff0c;但信息的洪流可能变得势不可挡&#xff0c;危及利用其价值的能力。内容服务解决方案能够减轻洪水泛滥的风险&#xff0c;并帮助组织更好地控制信息。 从信息中获取价值的不同之处在于治理。建立正确的治理框架&#xff0c;组织可以最大限度地利…

难以挖掘的真相——塑料版薯条、意大利面、披萨……

下方图片中的“美食”&#xff0c;看起来是不是十分美味&#xff1f; ▲莱佛士平面设计学生作品 可千万要擦亮眼睛&#xff0c;它们其实是&#xff1a;黄色瓶盖“蛋黄”的荷包蛋&#xff0c;黄色吸管的“薯条”&#xff0c;桔黄色的塑料带子“意大利面”&#xff0c;红色塑料袋…

Exynos4412的Linux5.4.174时钟驱动开发(四)——clk API的调用方法

系列文章目录 Exynos4412的Linux时钟驱动开发&#xff08;一&#xff09;——Exynos4412的时钟管理单元CMU Exynos4412的Linux时钟驱动开发&#xff08;二&#xff09;——clock的初始化&#xff08;CLK_OF_DECLARE的机制&#xff09; Exynos4412的Linux时钟驱动开发&#x…