用状态机实现简单的自动售卖机(Verilog)并验证

2024-03-23 03:10

本文主要是介绍用状态机实现简单的自动售卖机(Verilog)并验证,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、设计要求

二、分析

1、输入输出

(1)input

(2)output

2、状态

3、状态机

三、源代码

1、FSM.v

2、FSM_tb.v

四、仿真波形


一、设计要求

使用FSM实现自动售卖机。FSM的概念可参考:https://blog.csdn.net/qq_42922513/article/details/130828381icon-default.png?t=N7T8https://blog.csdn.net/qq_42922513/article/details/130828381售卖机描述:商品为可乐,一瓶可乐5元钱,每次只能投三种人民币中的一种,分别是:1元,2元,5元。当投够5元时,出一瓶可乐,并找零。

二、分析

1、输入输出

(1)input

输入包括:时钟信号clk,低电平复位信号rst_n,投币in_m

clk, rst_n, [3:0] in_m;

(2)output

输出包括:可乐goods,找零out_m

goods, [3:0] out_m;

2、状态

根据售卖机中有多少钱,将状态机共划分为5个状态,分别为:IDLE(0元)、S0(1元)、S1(2元)、S2(3元)、S3(4元)。

3、状态机描述

本文采用mealy型状态机。对各状态采用独热码进行编码,5个状态需要5bit。

三、源代码

1、FSM.v

`timescale 1ns/1nsmodule FSM (input clk,input rst_n,input [3:0] in_m,output reg goods,output reg [3:0] out_m
);reg [4:0] CS, NS;parameter [4:0]IDLE = 'b00001,S0   = 'b00010,S1   = 'b00100,S2   = 'b01000,S3   = 'b10000;//第一always块,同步时序逻辑
always @ (posedge clk or negedge rst_n) beginif (!rst_n)CS <= IDLE;elseCS <= NS;
end//第二always块,组合逻辑
always @ (*) begincase (CS)IDLE:if (in_m == 4'd1)		NS = S0;else if (in_m == 4'd2)	NS = S1;else if (in_m == 4'd5)	NS = IDLE;else					NS = IDLE;S0:if (in_m == 4'd1)		NS = S1;else if (in_m == 4'd2)	NS = S2;else if (in_m == 4'd5)	NS = IDLE;else					NS = S0;S1:if (in_m == 4'd1)		NS = S2;else if (in_m == 4'd2)	NS = S3;else if (in_m == 4'd5)	NS = IDLE;else					NS = S1;S2:if (in_m == 4'd1)		NS = S3;else if (in_m == 4'd2)	NS = IDLE;else if (in_m == 4'd5)	NS = IDLE;else					NS = S2;S3:if (in_m == 4'd1)		NS = IDLE;else if (in_m == 4'd2)	NS = IDLE;else if (in_m == 4'd5)	NS = IDLE;else					NS = S3;default:NS = IDLE;endcase
end//第三always块,同步时序逻辑
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginout_m <= 'd0;goods <= 'd0;endelse begincase (CS)IDLE: beginout_m <= 'd0;if (in_m == 'd5)    goods <= 'd1;else                goods<= 'd0;endS0: beginout_m <= 'd0;if (in_m == 'd1 || in_m == 'd2) begingoods <= 'd0;out_m <= 'd0;endelse begingoods <= 'd1;out_m <= 'd1;endendS1: beginout_m <= 'd0;if (in_m == 'd1 || in_m == 'd2) begingoods <= 'd0;out_m <= 'd0;endelse begingoods <= 'd1;out_m <= 'd2;endendS2: beginout_m <= 'd0;if (in_m == 'd1) begingoods <= 'd0;out_m <= 'd0;endelse if (in_m == 'd2) begingoods <= 'd1;out_m <= 'd0;endelse begingoods <= 'd1;out_m <= 'd3;endendS3: begingoods <= 'd1;if (in_m == 'd1)		out_m <= 'd0;else if (in_m == 'd2)	out_m <= 'd1;else					out_m <= 'd4;enddefault: begingoods <= 'd1;out_m <= 'd0;endendcaseend
end
endmodule

2、FSM_tb.v

//FSM_tb.v`timescale 1ns/1nsmodule FSM_tb;reg clk;
reg rst_n;
reg [3:0] in_m;
wire [3:0] out_m;
wire goods;FSM u(.clk(clk),.rst_n(rst_n),.in_m(in_m),.goods(goods),.out_m(out_m)
);initial beginrst_n = 'b0;clk = 'b0;#50rst_n = 'b1;
endalways #20 clk = ~clk;initial beginin_m = 0;#50in_m = 'd1;#40in_m = 'd1;#40in_m = 'd1;#40in_m = 'd1;#40in_m = 'd1;#40in_m = 'd2;#40in_m = 'd2;#40in_m = 'd2;#40in_m = 'd5;#40in_m = 'd2;#40in_m = 'd5;#40$stop;
endendmodule

3、FSM_tb.sv

使用system verilog进行随机验证。SV相关基础可参考:System Verilog基础_qq_42922513的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_42922513/article/details/130984574

//FSM_tb.sv
`timescale 1ns/1nsmodule FSM_tb;bit clk;
bit rst_n;
bit [3:0] in_m;
bit [3:0] out_m;
bit goods;FSM u(.clk(clk),.rst_n(rst_n),.in_m(in_m),.goods(goods),.out_m(out_m)
);initial beginrst_n = 'b0;clk = 'b0;#50rst_n = 'b1;
endalways #20 clk = ~clk;class packet;rand bit [3:0] money_in;constraint c{money_in dist{1:=1, 2:=1, 5:=1};}
endclassinitial beginin_m = 0;packet M;M = new();#50repeat(20) beginassert(M.randomize());in_m = M.money_in;$display("******* in_m = %0d********/n", in_m);#40;end#40$stop;
endendmodule

四、仿真波形

1、工具:VIVADO,testbench文件:FSM_tb.v

2、工具:VIVADO,testbench文件:FSM_tb.sv

                           

                                     PS:果觉得有用可以点赞并收藏!!!

这篇关于用状态机实现简单的自动售卖机(Verilog)并验证的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836946

相关文章

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法