当前位置: 首页 > news >正文

ASIC-WORLD Verilog(13)状态机FSM

写在前面

        在自己准备写一些简单的verilog教程之前,参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加点自己的理解)分享给大家。

        这是网站原文:Verilog Tutorial

        这是系列导航:Verilog教程系列文章导航


有限状态机FSM简介

        状态机(FSM)是许多数字设计的核心。计数器就是 FSM 的一种简单形式。当我学习Verilog时,我曾经想知道“如何在Verilog中编码FSM”和“编码它的最佳方法是什么”。接下来我将尝试回答这两个问题。

状态机类型

        根据状态机的输出类型分类,有两种类型的状态机。第一种是 Moore 状态机,其输出仅是当前状态的函数;第二种是 Mealy 状态机,其输出是当前状态和输入的函数。

Moore 状态机

Mealy 状态机


        状态机还可以根据所使用的状态编码进行分类。编码类型也是决定FSM的速度和复杂度的关键因素。二进制编码、格雷码、独热码是最常见的几种 FSM 状态编码类型。

状态机建模

        编码 FSM 时需要记住的一件事:组合逻辑和时序逻辑应该位于两个不同的always块中。在上两图中,下一状态逻辑(next state logic)始终是组合逻辑;而状态逻辑(state logic)和输出逻辑(output logic)则是时序逻辑。任何到下一个状态逻辑的异步信号在馈送到 FSM 之前都必须进行同步化处理。你应该尽量将状态机FSM 保存在单独的 Verilog 文件中。

        使用parameter或`define 等常量声明来定义 FSM 的状态可使代码更具可读性,且更易于管理。

示例:仲裁器

        接下来将以仲裁器作为案例,看看该如何实现一个完整的FSM。

        FSM 代码应包含三个部分:

  • 状态编码部分
  • 组合逻辑部分
  • 时序逻辑部分

状态编码

        状态编码有许多方式,其中最常用的是:

  • 二进制码(Binary Encoding)
  • 独热码(One Hot Encoding)
  • 格雷码(Gray Encoding)

独热码(One Hot Encoding)

parameter  [4:0]  IDLE  = 5'b0_0001;
parameter  [4:0]  GNT0  = 5'b0_0010;
parameter  [4:0]  GNT1  = 5'b0_0100;
parameter  [4:0]  GNT2  = 5'b0_1000;
parameter  [4:0]  GNT3  = 5'b1_0000;

二进制码(Binary Encoding)

parameter  [2:0]  IDLE  = 3'b000;
parameter  [2:0]  GNT0  = 3'b001;
parameter  [2:0]  GNT1  = 3'b010;
parameter  [2:0]  GNT2  = 3'b011;
parameter  [2:0]  GNT3  = 3'b100;

格雷码(Gray Encoding)

parameter  [2:0]  IDLE  = 3'b000;
parameter  [2:0]  GNT0  = 3'b001;
parameter  [2:0]  GNT1  = 3'b011;
parameter  [2:0]  GNT2  = 3'b010;
parameter  [2:0]  GNT3  = 3'b110;

组合逻辑部分

        这一部分可以使用函数、assign 语句或者always块来实现。

always @ (state or req_0 or req_1 or req_2 or req_3)
begin       next_state = 0;case(state)IDLE : if (req_0 == 1'b1) beginnext_state = GNT0;end else if (req_1 == 1'b1) beginnext_state= GNT1;end else if (req_2 == 1'b1) beginnext_state= GNT2;end else if (req_3 == 1'b1) beginnext_state= GNT3;end else beginnext_state = IDLE;end			GNT0 : if (req_0 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT0;endGNT1 : if (req_1 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT1;endGNT2 : if (req_2 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT2;endGNT3 : if (req_3 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT3;enddefault : next_state = IDLE;endcase
end

时序逻辑部分

        这一部分只能使用边沿敏感逻辑例如带posedge clock或者negedge clock的always块来实现。

always @ (posedge clock)
begin : OUTPUT_LOGICif (reset == 1'b1) begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;gnt_2 <= #1 1'b0;gnt_3 <= #1 1'b0;state <= #1 IDLE;end else beginstate <= #1 next_state;case(state)IDLE : begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;gnt_2 <= #1 1'b0;gnt_3 <= #1 1'b0;endGNT0 : begingnt_0 <= #1 1'b1;endGNT1 : begingnt_1 <= #1 1'b1;endGNT2 : begingnt_2 <= #1 1'b1;endGNT3 : begingnt_3 <= #1 1'b1;enddefault : beginstate <= #1 IDLE;endendcaseend
end

使用二进制编码的完整FSM代码

module fsm_full(
clock , // Clock
reset , // Active high reset
req_0 , // Active high request from agent 0
req_1 , // Active high request from agent 1
req_2 , // Active high request from agent 2
req_3 , // Active high request from agent 3
gnt_0 , // Active high grant to agent 0
gnt_1 , // Active high grant to agent 1
gnt_2 , // Active high grant to agent 2
gnt_3   // Active high grant to agent 3
);
// Port declaration here
input clock ; // Clock
input reset ; // Active high reset
input req_0 ; // Active high request from agent 0
input req_1 ; // Active high request from agent 1
input req_2 ; // Active high request from agent 2
input req_3 ; // Active high request from agent 3
output gnt_0 ; // Active high grant to agent 0
output gnt_1 ; // Active high grant to agent 1
output gnt_2 ; // Active high grant to agent 2
output gnt_3 ; // Active high grant to agent // Internal Variables
reg    gnt_0 ; // Active high grant to agent 0
reg    gnt_1 ; // Active high grant to agent 1
reg    gnt_2 ; // Active high grant to agent 2
reg    gnt_3 ; // Active high grant to agent parameter  [2:0]  IDLE  = 3'b000;
parameter  [2:0]  GNT0  = 3'b001;
parameter  [2:0]  GNT1  = 3'b010;
parameter  [2:0]  GNT2  = 3'b011;
parameter  [2:0]  GNT3  = 3'b100;reg [2:0] state, next_state;always @ (state or req_0 or req_1 or req_2 or req_3)
begin  next_state = 0;case(state)IDLE : if (req_0 == 1'b1) beginnext_state = GNT0;end else if (req_1 == 1'b1) beginnext_state= GNT1;end else if (req_2 == 1'b1) beginnext_state= GNT2;end else if (req_3 == 1'b1) beginnext_state= GNT3;end else beginnext_state = IDLE;end			GNT0 : if (req_0 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT0;endGNT1 : if (req_1 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT1;endGNT2 : if (req_2 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT2;endGNT3 : if (req_3 == 1'b0) beginnext_state = IDLE;end else beginnext_state = GNT3;enddefault : next_state = IDLE;endcase
endalways @ (posedge clock)
begin : OUTPUT_LOGICif (reset) begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;gnt_2 <= #1 1'b0;gnt_3 <= #1 1'b0;state <= #1 IDLE;end else beginstate <= #1 next_state;case(state)IDLE : begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;gnt_2 <= #1 1'b0;gnt_3 <= #1 1'b0;endGNT0 : begingnt_0 <= #1 1'b1;endGNT1 : begingnt_1 <= #1 1'b1;endGNT2 : begingnt_2 <= #1 1'b1;endGNT3 : begingnt_3 <= #1 1'b1;enddefault : beginstate <= #1 IDLE;endendcaseend
endendmodule

测试脚本

`include "fsm_full.v"module fsm_full_tb();
reg clock , reset ;
reg req_0 , req_1 ,  req_2 , req_3; 
wire gnt_0 , gnt_1 , gnt_2 , gnt_3 ;initial begin$display("Time\t    R0 R1 R2 R3 G0 G1 G2 G3");$monitor("%g\t    %b  %b  %b  %b  %b  %b  %b  %b", $time, req_0, req_1, req_2, req_3, gnt_0, gnt_1, gnt_2, gnt_3);clock = 0;reset = 0;req_0 = 0;req_1 = 0;req_2 = 0;req_3 = 0;#10 reset = 1;#10 reset = 0;#10 req_0 = 1;#20 req_0 = 0;#10 req_1 = 1;#20 req_1 = 0;#10 req_2 = 1;#20 req_2 = 0;#10 req_3 = 1;#20 req_3 = 0;#10 $finish;
endalways#2 clock = ~clock;fsm_full U_fsm_full(
clock , // Clock
reset , // Active high reset
req_0 , // Active high request from agent 0
req_1 , // Active high request from agent 1
req_2 , // Active high request from agent 2
req_3 , // Active high request from agent 3
gnt_0 , // Active high grant to agent 0
gnt_1 , // Active high grant to agent 1
gnt_2 , // Active high grant to agent 2
gnt_3   // Active high grant to agent 3
);endmodule

 仿真结果


  • 📣您有任何问题,都可以在评论区和我交流📃!
  • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵,博客主页:wuzhikai.blog.csdn.net
  • 📣您的支持是我持续创作的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!

相关文章:

ASIC-WORLD Verilog(13)状态机FSM

写在前面 在自己准备写一些简单的verilog教程之前&#xff0c;参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好&#xff0c;奈何没有中文&#xff0c;在下只好斗胆翻译过来&#xff08;加点自己的理解&#xff09;分享给大家。 这是网站原文&…...

设置微软Edge浏览器主页和新标签页,摆脱扰人和分散注意力的主页

默认情况下,Microsoft Edge会向您显示世界上最令人分心和讨厌的主页(也称为主屏幕)。微软不想只向你展示一个搜索框,也许还有一个漂亮的背景或一些你喜欢的网站的快捷方式,而是想在你面前扔一堆新闻标题和广告。 你可能会打开浏览器阅读电子邮件,结果被Microsoft Edge主…...

视频汇聚平台EasyCVR安防视频监控平台新增经纬度选取功能的详细介绍

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…...

HCIP-HCS华为私有云的使用

1、概述 HCS&#xff08;HuaweiCoudStack&#xff09;华为私有云&#xff1a;6.3 之前叫FusionSphere OpenStack&#xff0c;6.3.1 版本开始叫FusionCloud&#xff0c;6.5.1 版本开始叫HuaweiCloud Stack (HCS)华为私有云软件。 开源openstack&#xff0c;发放云主机的流程&am…...

深度学习1.卷积神经网络-CNN

目录 卷积神经网络 – CNN CNN 解决了什么问题&#xff1f; 需要处理的数据量太大 保留图像特征 人类的视觉原理 卷积神经网络-CNN 的基本原理 卷积——提取特征 池化层&#xff08;下采样&#xff09;——数据降维&#xff0c;避免过拟合 全连接层——输出结果 CNN …...

浏览器输入一个URL之后发生了什么?

URL解析DNS解析TCP连接TSL连接HTTP请求TCP挥手接收并解析响应 URL 解析 主要分为&#xff1a; 协议&#xff0c;eg http,https域名或者ip地址&#xff0c;eg www.baidu.com 域名相对于ip地址来说&#xff0c;更方便人们记忆&#xff0c;但是实际的网络传输中使用的是ip地址 端…...

uniapp 布局(自定义导航栏加固定高度的主要内容)

不想让整体页面出现滚动条 页面大致分为三部分&#xff0c;导航栏、主题内容、tabbar&#xff0c;不想让整个页面出现滚动条&#xff0c;只想让主要内容滚动。 我这里是直接用了uni.getSystemInfoSync()&#xff0c;整体分为两部分&#xff0c;自定义头部和滚动内容&#xff…...

android手机销售app(IDEA,SpringBoot,SSM,MySQL)+支付宝支付+全套视频教程

本项目亮点: 支付宝支付 eCharts柱状图图表数据统计 【项目功能介绍】 本系统包含后台管理和前端app双端系统&#xff0c;后台管理的功能包含: 登录, 退出, 修改管理员信息(基本信息与头像),资源管理,角色管理,资源权限分配,字典管理,用户管理,图书管理,订单管理,订单统计; a…...

深入探讨Java虚拟机(JVM)的工作原理与优化策略

摘要&#xff1a;本文对Java虚拟机&#xff08;JVM&#xff09;的工作原理进行深入探讨&#xff0c;包括其内存管理、垃圾回收以及代码执行等方面。同时&#xff0c;文章还通过具体的代码示例&#xff0c;阐述了JVM的优化策略&#xff0c;旨在提高Java程序的性能。 一、引言 …...

WPF数据绑定

数据绑定是一个很强大且优雅的技能&#xff0c;之前用过好多次&#xff0c;但有些地方总不是特别清晰&#xff0c;常常需要重新翻阅资料来回顾&#xff0c;于是这次用了几天时间好好梳理一下&#xff0c;记录一下。 首先数据绑定对数据对象的要求&#xff1a;需要是公有属性&a…...

Android学习之路(6) 其他UI控件

ImageView(图像视图) RadioButton(单选按钮)&Checkbox(复选框) 开关按钮ToggleButton和开关Switch ProgressBar(进度条) SeekBar(拖动条) RatingBar(星级评分条) ScrollView(滚动条)...

matlab实现牛顿迭代法求解非线性方程

非线性方程是指含有未知数的方程&#xff0c;且方程中至少有一个未知数的次数大于一或者含有非一次幂的函数&#xff08;如指数、对数、三角函数等&#xff09;。例如&#xff0c;$f(x) x^3 - 2x - 5 0$就是一个非线性方程。非线性方程通常没有显式的解析解&#xff0c;因此需…...

Cpp学习——编译链接

目录 ​编辑 一&#xff0c;两种环境 二&#xff0c;编译环境下四个部分的 1.预处理 2.编译 3.汇编 4.链接 三&#xff0c;执行环境 一&#xff0c;两种环境 在程序运行时会有两种环境。第一种便是编译环境&#xff0c;第二种则是执行环境。如下图&#xff1a; 在程序运…...

android - fragment 数据丢失?状态丢失?

最佳答案 一些状态丢失的例子: 1. 假设您有一个按钮和一个 TextView 。在代码中&#xff0c;你已经定义了初始值为 0 的整数 i&#xff0c;它通过单击按钮递增 1&#xff0c;并且它的值显示在 TextView 中。假设你已经按下按钮 5 次&#xff0c;那么 textview 将被设置为 0。也…...

Git基本操作

本地仓库 当我们初始化&#xff08;git init&#xff09;之后&#xff0c;会在当前目录下生成一个与项目并列的.git文件夹&#xff0c;当我们对项目作出更改之后使用git commit命令&#xff0c;一般是将修改提交到本地仓库&#xff0c;也就是该文件夹下面的文件会对应修改&…...

Nginx配置文件详解

Nginx配置文件详解 1、Nginx配置文件1.1主配置文件详解1.2子配置文件 2、全局配置部分2.1修改启动的工作进程数&#xff08;worker process) 优化2.2cpu与worker process绑定2.3 PID 路径修改2.4 修改工作进程的优先级2.5调试工作进程打开的文件的个数2.6关闭master-worker工作…...

【0217】stats collector(统计信息收集器)进程启动原理(1)

文章目录 1. 启动 stats collector进程1.1 stats collector进程启动过程1.1.1 检查套接字 pgStatSock 是否存在1.1.2 重新启动失败的stats collector频率1.1.3 fork() 三种返回值处理1.2 detach所有共享内存段1.3 detach 共享内存段1.4 stats collecotr进程启动的主体相关阅读:…...

【应用层】网络基础 -- HTTPS协议

HTTPS 协议原理加密为什么要加密常见的加密方式对称加密非对称加密 数据摘要&&数据指纹 HTTPS 的工作过程探究方案1-只使用对称加密方案2-只使用非对称加密方案3-双方都使用非对称加密方案4-非对称加密对称加密中间人攻击-针对上面的场景 CA认证理解数据签名方案5-非对…...

实验篇—— 基因家族Motif 分析

实验篇—— 基因家族Motif 分析 文章目录 前言一、名词解释二、实操1. MEME工具箱2. Motif Discovery&#xff08;基序发现&#xff09;1. 结果网页2. 在TBtools中&#xff08;额外&#xff09; 2. Motif Enrichment&#xff08;基序富集分析&#xff09;3. Motif Search&#…...

Linux拓展之阻止或禁用普通用户登录

禁止指定用户登录 chsh -s /sbin/nologin 指定用户名示例 chsh -s /sbin/nologin testuser恢复指定用户登录 chsh -s /bin/bash 指定用户名示例 chsh -s /bin/bash testuser参考 https://blog.csdn.net/cnds123321/article/details/125232580 https://www.cnblogs.com/cai…...

Linux系统USB摄像头测试程序(四)_视频旋转及缩放

下面的程序实现了视频的旋转及缩放&#xff0c;窗口中点击鼠标左键视频向左旋转&#xff0c;点击鼠标右键视频向右旋转并且视频缩小了二分之一。程序中首先把yvyv422转换成了RGB24&#xff0c;然后利用opencv进行了旋转和缩放&#xff0c;其后用sdl2进行了渲染。使用了ffmpeg、…...

大模型+学习机,是概念游戏还是双向奔赴?

众所周知&#xff0c;2023年上半年大模型概念炙手可热。各大科技公司纷纷卷入&#xff0c;或宣称布局相关领域&#xff0c;或率先官宣自研大模型。而随着资本市场对大模型概念的热情有所消退&#xff0c;属于这片战场的新一轮角逐慢慢聚焦在了技术的落地应用上。 8月15日&#…...

linux怎么查看用户属于哪个组

查看当前用户所属组 shell> groups root查看指定用户所属组 shell> groups testuser testuser : testusershell> id testuser uid1000(testuser) gid1000(testuser) groups1000(testuser)查看组文件 shell> cat /etc/group...

邂逅JavaScript

前言&#xff1a;前端三大核心 前端开发最主要需要掌握的是三个知识点&#xff1a;HTML、CSS、JavaScript 一、认识编程语言 1.计算机语言 前面我们已经学习了HTML和CSS很多相关的知识: 在之前我们提到过, HTML是一种标记语言, CSS也是一种样式语言; 他们本身都是属于计算…...

Android 中 Fragment判空

1. 判断 Fragment 是否已经被添加到 Activity 中&#xff0c;可以通过 Fragment 的 isAdded() 方法来判断。 2. 判断 Fragment 的 View 是否已经被创建&#xff0c;可以通过 Fragment 的 getView() 方法来判断。 3. 判断 Fragment 是否已经被销毁&#xff0c;可以通过 Fragme…...

软考高级系统架构设计师系列论文八十八:财务数据仓库系统的设计与实现

软考高级系统架构设计师系列论文八十八:财务数据仓库系统的设计与实现 一、摘要二、正文三、总结一、摘要 近年来,数据仓库技术在信息系统的建设中得到了广泛应用,有效地为决策提供了支持。2020年6月,本人所在单位组织开发了财务管理决策系统,该系统主要是使高层领导掌握企…...

fastdeploy部署多线程/进程paddle ocr(python flask框架 )

部署参考&#xff1a;https://github.com/PaddlePaddle/FastDeploy/blob/develop/tutorials/multi_thread/python/pipeline/README_CN.md 安装 cpu&#xff1a; pip install fastdeploy-python gpu &#xff1a;pip install fastdeploy-gpu-python #下载部署示例代码 git cl…...

【图论】拓扑排序

一.定义 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法&#xff0c;使得图中的每个顶点在排序中都位于其依赖的顶点之后。它通常用于表示一些任务之间的依赖关系&#xff0c;例如在一个项目中&#xff0c;某些任务必须在其他任务之前完成。 拓扑排序的…...

自动化备份方案

背景说明 网上有很多教程&#xff0c;写的都是从零搭建一个什么什么&#xff0c;基本上都是从无到有的教程&#xff0c;但是&#xff0c;很少有文章提及搭建好之后如何备份&#xff0c;这次通过请教GitHub Copilot Chat&#xff0c;生成几个备份脚本&#xff0c;以备后用。 注…...

win11出现安全中心空白和IT管理员已限制对此应用的某些区域的访问

问题 windows安全中心服务被禁用 winr 输入services.msc 找到windows安全中心服务查看是否被禁用&#xff0c;改为启动&#xff0c;不可以改动看第三条 打开设置&#xff0c;找到应用—windows安全中心–终止–修复–重置 重启如果还是不行看第四条 家庭版系统需要打开gped…...