Verilog基础:三段式状态机与输出寄存

相关阅读

Verilog基础icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12263729.html


        对于Verilog HDL而言,有限状态机(FSM)是一种重要而强大的模块,常见的有限状态机书写方式可以分为一段式,二段式和三段式,笔者强烈建议使用三段式因为这样能使状态机逻辑清晰且易于维护。

        有限状态机有两种基本类型:Mealy机和Moore机。两者的区别在于:Mealy机的下一状态和输出都取决于当前状态和当前输入,而Moore机的下一状态取决于当前状态和当前输入,输出只取决于当前状态。这两类有限状态机的下一状态和输出都是组合逻辑的形式的(指输出不直接来自寄存器的输出),两类状态机的结构如图1、图2所示。

图1 Mealy型状态机

图2 Moore型状态机

        下面以一个简单的例子说明三段式Moore型状态机的书写方式。图3是一个有两个状态的异步复位的Moore机。

图3 一个简单的Moore机 

module top_module (input clk,input in,input rst_n,output reg out
);
parameter A = 0;
parameter B = 1;
reg state, next_state;               //定义寄存器变量保存状态信息//第一段,下一状态组合逻辑
always@(*) begincase (state)                     //根据不同的状态和输入,决定下一时钟周期的状态A: next_state = in ? A : B;B: next_state = in ? B : A;endcase
end//第二段,状态转移时序逻辑
always @(posedge clk, negedge rst_n) beginif (!rst_n)     state <= B;		             //异步复位到状态Belse state <= next_state;			end//第三段,输出组合逻辑
always@(*) beginif(state == B)out = 1;elseout = 0;
end//因为输出比较简单,这里的第三段的输出组合逻辑也可以用assign连续赋值
//但out此时不能定义为reg
//assign out = (state == B);endmodule

        对于Mealy型状态机,因为输出直接受输出影响,可能在某些情况下会出现毛刺(即不在时钟边沿的输出变化),所以可以使用寄存器采集输出。对于Moore型状态机,虽然没有输出毛刺的问题,但也可以使用寄存器采集输出以避免大段组合逻辑输出。图4和图5分别给出了寄存输出的Mealy型状态机和Moore型状态机的结构。

图4 寄存输出的Mealy型状态机

图5 寄存输出的Moore型状态机

        上面两图不难理解,但是一个新的问题出现了,即输出会延后一个周期得到,如果既需要当前周期给出输出,又需要对输出寄存,就不能使用当前状态和输入确定输出,而是应该使用下一状态组合逻辑和输入确定输出。图6和图7给出了这种情况下的Mealy型状态机和Moore型状态机。

图6 寄存输出的Mealy型状态机(下一状态)

 图7  寄存输出的Moore型状态机(下一状态)

        对于Mealy状态机,因为需要状态转移和相应状态的输出同时出现,输出寄存器需要保存由下一状态组合逻辑和的输入推导的输出。对于Moore状态机,输出寄存器需要保存由下一状态组合逻辑推导的输出。

        下面用一个更加复杂的有限状态机为例,说明寄存输出的具体写法。这是一个序列检测器,用于检测输入序列中三个连续的1信号,首先给出Moore型序列检测器的Verilog描述。

module Seq_Rec_Moore(output reg D_out, D_out_r1, D_out_r2, input D_in, En, clk, rst_n);parameter S_idle = 3'd0;parameter S_0 = 3'd1;parameter S_1 = 3'd2;parameter S_2 = 3'd3;parameter S_3 = 3'd4;reg [2:0] state, next_state;//下一状态组合逻辑always@(*)begincase(state)S_idle: if((En == 1)&&(D_in == 1))next_state = S_1;else if((En == 1)&&(D_in == 0))next_state = S_0;else next_state = S_idle;S_0:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_1;elsenext_state = S_idle;S_1:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_2;else next_state = S_idle;S_2:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_3;else next_state = S_idle;S_3:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_3;else next_state = S_idle;default:    next_state = S_idle;      endcaseend//状态转移时序逻辑always@(posedge clk, negedge rst_n)beginif(!rst_n)state <= S_idle;elsestate <= next_state;end//输出组合逻辑always@(*) beginD_out = (state == S_3);end//寄存输出always @(posedge clk, negedge rst_n) beginif(!rst_n)D_out_r1 <= 0;elseD_out_r1 <= D_out;end//寄存输出(下一状态)always@(posedge clk, negedge rst_n)beginif(!rst_n)D_out_r2 <= 0;elseD_out_r2 <= (next_state == S_3);end
endmodule

        一个简单的testbench如下所示,图8所示的仿真截图显示了三种不同形式的输出。

`timescale 1ns / 1ns
module t_Seq();reg D_in, clk, rst_n,En;wire D_out, D_out_r1, D_out_r2;Seq_Rec_Moore Seq_Rec_Moore_1 (.D_in(D_in), .clk(clk), .rst_n(rst_n), .D_out(D_out), .En(En), .D_out_r1(D_out_r1), .D_out_r2(D_out_r2));initial beginD_in = 0;clk = 0;rst_n = 1;En = 0;endinitial begin#5 rst_n = 0;#4 rst_n = 1;endalways begin#5 clk = 0;#5 clk = 1;endinitial begin#5 En =1;endinitial begin#5 D_in = 1;end
endmodule

图8 Moore状态机仿真截图 

        下面是Mealy型序列检测器的Verilog描述。

module Seq_Rec_Mealy(output reg D_out, D_out_r1, D_out_r2, input D_in, En, clk, rst_n);parameter S_idle = 3'd0;parameter S_0 = 3'd1;parameter S_1 = 3'd2;parameter S_2 = 3'd3;parameter S_3 = 3'd4;reg [2:0] state, next_state;//下一状态组合逻辑always@(*)begincase(state)S_idle: if((En == 1)&&(D_in == 1))next_state = S_1;else if((En == 1)&&(D_in == 0))next_state = S_0;else next_state = S_idle;S_0:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_1;elsenext_state = S_idle;S_1:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_2;else next_state = S_idle;S_2:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_3;else next_state = S_idle;S_3:    if(D_in == 0)next_state = S_0;else if(D_in == 1)next_state = S_3;else next_state = S_idle;default:    next_state = S_idle;      endcaseend//状态转移时序逻辑always@(posedge clk, negedge rst_n)beginif(!rst_n)state <= S_idle;elsestate <= next_state;end//输出组合逻辑always@(*) beginD_out = (state == S_3)&(D_in == 1);end//寄存输出always @(posedge clk, negedge rst_n) beginif(!rst_n)D_out_r1 <= 0;elseD_out_r1 <= D_out;end//寄存输出(下一状态)always@(posedge clk, negedge rst_n)beginif(!rst_n)D_out_r2 <= 0;elseD_out_r2 <= (next_state == S_3)&(D_in == 1);end
endmodule

 图9 Mealy状态机仿真截图 

一个简单的testbench如下所示,图9的仿真截图显示了如果使用寄存输出,而输入无法维持到下个时钟沿,则会丢失寄存输出信号。

`timescale 1ns / 1ns
module t_Seq();reg D_in, clk, rst_n,En;wire D_out, D_out_r1, D_out_r2;Seq_Rec_Mealy Seq_Rec_Mealy_1 (.D_in(D_in), .clk(clk), .rst_n(rst_n), .D_out(D_out), .En(En), .D_out_r1(D_out_r1), .D_out_r2(D_out_r2));initial beginD_in = 0;clk = 0;rst_n = 1;En = 0;endinitial begin#5 rst_n = 0;#4 rst_n = 1;endalways begin#5 clk = 0;#5 clk = 1;endinitial begin#5 En =1;endinitial begin#5 D_in = 1;#30 D_in = 0;#10 D_in = 1;#37 D_in = 0;end
endmodule

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】深入理解Docker:一种革新性的容器技术

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

基于servlet+jsp+mysql网上书店系统

基于servletjspmysql网上书店系统 一、系统介绍二、功能展示四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于servletjspmysql网上书店系统 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 前端技…

二叉树题目:二叉树最大宽度

文章目录 题目标题和出处难度题目描述要求示例数据范围 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;二叉树最大宽度 出处&#xff1a;662. 二叉树最大宽度 难度 5 级 题目描述 要求 给定一个二叉树的根结点 …

完全免费!超好用的IDEA插件推荐:Apipost-Helper

Idea 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它可以帮助开发人员更加高效地编写、调试和部署软件应用程序,Idea 还具有许多插件和扩展&#xff0c;可以根据开发人员的需要进行定制和扩展&#xff0c;从而提高开发效率,今天我们就来介绍一款国产的…

未来之选:为什么向量数据库是您的数据管理利器

文章目录 前言什么是向量数据库&#xff1f;向量数据库的机制向量数据库的优点‍查询向量数据库 什么是向量Embedding&#xff1f;Amazon OpenSearch Service总结 前言 向量数据库擅长处理复杂的高维数据&#xff0c;正在彻底改变商业世界的数据检索和分析。它们执行相似性搜索…

【Unity插件】2D模拟绳子的插件——Rope 2D Editor

文章目录 前言资源unity商店地址&#xff1a;我这里有一个比较老旧的版本&#xff1a; 使用创建绳子场景使用时效果 参考完结 前言 最近发现一个很有意思的插件Rope 2D Editor&#xff0c;这是一个简单而强大的 2d 绳索编辑器。这是我为我的游戏&#xff08;Dabdob&#xff09…

Linux——vim简介、配置方案(附带超美观的配置方案)、常用模式的基本操作

vim简介、配置方案、常用模式的基本操作 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的xmind和.png文件都已同步导入至资源 1. vim简介 vim是Linux常用的文本编辑器&#xff0c;每个Linux账户都独有一个vim编辑器 本篇我们介绍vim最常用的三种模式&#xff1a;…

网络安全之认识托管威胁检测与响应(MDR)

随着数字化转型加速&#xff0c;企业的IT环境日益复杂&#xff0c;面临的网络安全威胁也在不断增加。传统的防御措施已经无法有效应对新型威胁&#xff0c;而且很多企业缺乏专业的网络安全团队和技术手段&#xff0c;导致大量的安全事件未能及时被发现和处理。 在这种背景下&a…

[Mac软件]Adobe Media Encoder 2024 V24.0.2免激活版

软件说明 使用Media Encoder&#xff0c;您将能够处理和管理多媒体。插入、转码、创建代理版本&#xff0c;并几乎以任何可用的格式输出。在应用程序中以单一方式使用多媒体&#xff0c;包括Premiere Pro、After Effects和Audition。 紧密整合 与Adobe Premiere Pro、After …

学用 DevChat 的 VSCode 插件,体验AI智能编程工具 (一)

简单说DevChat是一个辅助编程的智能工具&#xff0c;它可以通过自然语言对话的方式与开发者进行交流&#xff0c;帮助开发者更高效地完成编程任务。 有了人工智能工具&#xff0c;编程进入一个新天地。 闻名已久&#xff0c;不若体验一下。 一.准备工作 1.运行环境. A. p…

京东商品详情API接口使用方法以及示例代码,可高并发请求

京东商品详情API接口是一种用于获取京东商品详细信息的接口。通过该接口&#xff0c;开发人员可以获取到商品的ID、名称、价格、销量、评价等信息&#xff0c;从而进行进一步的数据分析和应用开发。本文将介绍京东商品详情API接口的使用方法、注意事项以及示例代码。 一、使用…

开放领域问答机器人2——开发流程和方案

开放领域问答机器人是指在任何领域都能够回答用户提问的智能机器人。与特定领域问答机器人不同&#xff0c;开放领域问答机器人需要具备更广泛的知识和更灵活的语义理解能力&#xff0c;以便能够回答各种不同类型的问题。 开发开放领域问答机器人的流程和方案可以包括以下步骤…

MySQL | 查询接口性能调优、编码方式不一致导致索引失效

背景 最近业务反馈&#xff0c;列表查询速度过慢&#xff0c;需要优化。 到正式环境系统去验证&#xff0c;发现没筛选任何条件的情况下&#xff0c;查询需要三十多秒&#xff0c;而筛选了条件之后需要13秒。急需优化。 先说结论&#xff1a;连表用的字段编码方式不一致导致索…

达梦数据库答案

1、 创建数据库实例&#xff0c;到/dm8/data下&#xff0c;数据库名&#xff1a;DEMO&#xff0c;实例名DEMOSERVER&#xff08;10分&#xff09; [dmdbadmServer ~]$ cd /dm8/tool [dmdbadmServer tool]$ ./dbca.sh1、 簇大小32&#xff0c;页大小16&#xff0c;登录密码&…

第12章 PyTorch图像分割代码框架-3:推理与部署

推理模块 模型训练完成后&#xff0c;需要单独再写一个推理模块来供用户测试或者使用&#xff0c;该模块可以命名为test.py或者inference.py&#xff0c;导入训练好的模型文件和待测试的图像&#xff0c;输出该图像的分割结果。inference.py主体部分如代码11-7所示。 代码11-7 …

性能测试:Jenkins+Ant+Jmeter自动化框架的搭建方法

前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入&#xff0c;我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段&#xff0c;需要在每个版本中&#xff0c;对某些新增接口进行性能测试&#xff0c;有时还需要在一天中的不同时段分别进行…

Python数据结构:元组(Tuple)详解

1.介绍和基础操作 Python中的元组&#xff08;Tuple&#xff09;是不可变有序序列&#xff0c;可以容纳任意数据类型&#xff08;包括数字、字符串、布尔型、列表、字典等&#xff09;的元素&#xff0c;通常用圆括号() 包裹。与列表&#xff08;List&#xff09;类似&#xff…

【matlab】KMeans KMeans++实现手写数字聚类

目录 matlab代码kmeans matlab代码kmeans MNIST DATABASE下载网址: http://yann.lecun.com/exdb/mnist/ 聚类 将物理或抽象对象的集合分成由类似特征组成的多个类的过程称为聚类(clustering)。 对于给定N个n维向量x1&#xff0c;…&#xff0c;xN∈Rn&#xff0c;聚类的目标…

iOS如何通过在线状态来监听其他设备登录的状态

前提条件 1、完成 3.9.1 或以上版本 SDK 初始化 2、了解环信即时通讯 IM API 的 使用限制。 3、已联系商务开通在线状态订阅功能 实现方法 你可以通过调用 subscribe 方法订阅自己的在线状态&#xff0c;从而可以监听到其他设备在登录和离线时的回调&#xff0c;示例代码如下…