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

news2025/1/12 8:42:21

相关阅读

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@(*) begin
	case (state)                     //根据不同的状态和输入,决定下一时钟周期的状态
		A: next_state = in ? A : B;
		B: next_state = in ? B : A;
	endcase
end

//第二段,状态转移时序逻辑
always @(posedge clk, negedge rst_n) begin
	if (!rst_n)     
        state <= B;		             //异步复位到状态B
    else 
        state <= next_state;			
    end

//第三段,输出组合逻辑
always@(*) begin
    if(state == B)
        out = 1;
    else
        out = 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@(*)begin
        case(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;
                    else
                        next_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;      
        endcase
    end
    
    //状态转移时序逻辑
    always@(posedge clk, negedge rst_n)begin
        if(!rst_n)
            state <= S_idle;
        else
            state <= next_state;
    end

    //输出组合逻辑
    always@(*) begin
        D_out = (state == S_3);
    end

    //寄存输出
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            D_out_r1 <= 0;
        else
            D_out_r1 <= D_out;
    end

    //寄存输出(下一状态)
    always@(posedge clk, negedge rst_n)begin
        if(!rst_n)
            D_out_r2 <= 0;
        else
            D_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 begin
    D_in = 0;
    clk = 0;
    rst_n = 1;
    En = 0;
  end

  initial begin
    #5 rst_n = 0;
    #4 rst_n = 1;
  end

  always begin
    #5 clk = 0;
    #5 clk = 1;
  end

  initial begin
    #5 En =1;
  end

  initial 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@(*)begin
        case(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;
                    else
                        next_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;      
        endcase
    end
    
    //状态转移时序逻辑
    always@(posedge clk, negedge rst_n)begin
        if(!rst_n)
            state <= S_idle;
        else
            state <= next_state;
    end

    //输出组合逻辑
    always@(*) begin
        D_out = (state == S_3)&(D_in == 1);
    end

    //寄存输出
    always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            D_out_r1 <= 0;
        else
            D_out_r1 <= D_out;
    end

    //寄存输出(下一状态)
    always@(posedge clk, negedge rst_n)begin
        if(!rst_n)
            D_out_r2 <= 0;
        else
            D_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 begin
    D_in = 0;
    clk = 0;
    rst_n = 1;
    En = 0;
  end

  initial begin
    #5 rst_n = 0;
    #4 rst_n = 1;
  end

  always begin
    #5 clk = 0;
    #5 clk = 1;
  end

  initial begin
    #5 En =1;
  end

  initial begin
    #5 D_in = 1;
    #30 D_in = 0;
    #10 D_in = 1;
    #37 D_in = 0;
  end
endmodule

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

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

相关文章

JAVA弑神大阵之装饰者大阵

架构说明 构成简述&#xff1a; 总接口&#xff1a; 装饰者跟被装饰者都要来实现他&#xff08;或者理解成父接口&#xff09;&#xff0c;作用&#xff1a;对被装饰者做转换 被装饰者&#xff1a; 此处实现总接口。什么都不需要动&#xff0c;他只是被增强的功能&#xff0…

【ArcGIS Pro微课1000例】0030:ArcGIS Pro中自带晕渲地貌工具的妙用

在ArcGIS中,制作地貌晕渲效果通常的做法是先制作山体阴影效果,然后叠加在DEM的下面,再改变DEM的透明度来实现。而在ArcGIS Pro中自带了效果显著的晕渲地貌工具。 文章目录 一、晕渲地貌工具1. 符号系统2. 栅格函数二、山体阴影效果1. 工具箱2. 栅格函数打开ArcGIS Pro3.0,加…

监控和数据采集软件架构和详细设计

介绍 监控和数据采集软件通过提供实时监控、数据收集和分析功能&#xff0c;在各个行业中发挥着至关重要的作用。这些软件应用程序可帮助企业收集有价值的见解、优化流程并做出明智的决策。在本文中&#xff0c;我们将探讨监测和数据采集软件的软件架构、编程技术和详细设计规范…

『亚马逊云科技产品测评』活动征文|搭建带有“弱”图像处理功能的流媒体服务器

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 本文基于以下软硬件工具&#xff1a; aws ec2 frp-0.52.3 mediamtx-1.3…

链动2+1模式系统开发之区域代理深度解析

区域代理的保护机制&#xff1a;在链动商城系统里设定的代理有唯一性&#xff0c;每个省只有一个省代&#xff0c;每个市只有一个市代&#xff0c;每个区县只有一个区县代。这样也是保护每个代理的收益权益。 区域代理包含的权益类别&#xff1a;购物奖励折扣&#xff1b;区域实…

iOS群控手机App的开发难点是什么?

随着智能手机的普及&#xff0c;手机App已经成为我们生活中不可或缺的一部分&#xff0c;在众多手机操作系统中&#xff0c;iOS系统因其封闭性、安全性和流畅性而备受用户青睐&#xff0c;然而&#xff0c;开发一款针对iOS系统的手机App却并非易事。 一、开发语言与框架 iOS系…

Antv/G2 折线图 使用 DataSet 进行数据排序

DataSet 文档 G2 3.2 DataSet 文档 安装 浏览器引入 可以通过 <script> 标签引入在线资源或者本地脚本&#xff1a; <!-- 引入在线资源 --> <script src"https://unpkg.com/antv/data-set"></script><!-- 引入本地脚本 --> <sc…

解决pikachu中RCE中文乱码的问题

这个问题我在DVWA中的RCE栏目同样遇到过&#xff0c;今天在做pikachu的RCE的时候也遇到了&#xff0c;所以特此来解决一下这个问题&#xff0c;解决方法很简单&#xff0c;在源码中加入下一行代码。 $result iconv("GBK", "UTF-8", $result);加在68行前面…

虚拟仪器软件结构VISA

1、什么是VISA VISA是虚拟仪器软件结构(Virtual Instrument Software Architectuere)的简称&#xff0c;是由VXI plug & play系统联盟所统一制定的I/O接口软件标准及其相关规范的总称。一般称这个I/O函数库为VISA库&#xff08;用于仪器编程的标准I/O函数库&#xff09;。…

专业调色软件 3D LUT Creator Pro 激活中文 for mac

3D LUT Creator与彩 色 图 像一起工作的简单性和清晰度不会让任何人无动于衷。此外&#xff0c;扩展名为.3dl的文件可以导入到Adobe Photoshop&#xff0c;因此您可以将这些设置作为调整图层应用&#xff0c;不仅可以将它们应用于位图图像&#xff0c;还可以将其应用于矢量图形…

RT-DETR算法优化改进:一种新颖的动态稀疏注意力(BiLevelRoutingAttention) | CVPR2023

💡💡💡本文独家改进: 提出了一种新颖的动态稀疏注意力(BiLevelRoutingAttention),以实现更灵活的计算分配和内容感知,使其具备动态的查询感知稀疏性 1)代替RepC3进行使用; 2)BiLevelRoutingAttention直接作为注意力进行使用; 推荐指数:五星 RT-DETR魔术师专栏介…

分类预测 | Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多输入分类预测

分类预测 | Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多输入分类预测 目录 分类预测 | Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多输入分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 Matlab实现PSO-GRU粒子群算法优化门控循环单元的数据多…

通讯协议学习之路(实践部分):IIC开发实践

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 本文…

【JavaEE】Servlet(创建Maven、引入依赖、创建目录、编写及打包、部署和验证、smart Tomcat)

一、什么是Servlet&#xff1f; Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app 1.1 Servlet能干什么&#xff1f; &#x1f695;允许程序猿注册一个类, 在 Tomcat 收到某个特定的 HTTP 请求的时候, 执行这个类…

【Redis】Hash哈希类型

上一篇&#xff1a; set集合 https://blog.csdn.net/m0_67930426/article/details/134366814?spm1001.2014.3001.5502 目录 Hset Hget Hlen Hkeys Hvals Hincrby Hdecrby Hsetex Hsetnx 官网&#xff1a; https://redis.io/commands/?grouphash Hset 创建哈希集…

Facebook平台特征概述

Facebook是全球最大的社交媒体平台之一&#xff0c;拥有数十亿的用户。它的独特特征和功能使其成为人们分享、互动和连接的理想场所。下面小编将讲一下关于Facebook平台的特征的详细概述。 1、用户个人资料 每个Facebook用户都有一个个人资料页面&#xff0c;可以在上面分享个…

数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

文章目录 数据结构上机实验1.要求2.图的实现&#xff08;以无向邻接表为例&#xff09;2.1创建图2.1.1定义图的顶点、边及类定义2.1.2创建无向图和查找2.1.3插入边2.1.4打印函数 2.2图的深度优先搜索&#xff08;DFS&#xff09;2.3图的广度优先搜索&#xff08;BFS&#xff09…

RT-DETR算法优化改进:可变形大核注意力(D-LKA Attention),超越自注意力,实现暴力涨点 | 2023.8月最新发表

💡💡💡本文独家改进: 可变形大核注意力(D-LKA Attention),采用大卷积核来充分理解体积上下文的简化注意力机制,来灵活地扭曲采样网格,使模型能够适当地适应不同的数据模式 1)代替RepC3进行使用; 推荐指数:五星 RT-DETR魔术师专栏介绍: https://blog.csdn.n…

Java图像编程之:Graphics2D

一、介绍 1、Java图像编程的核心类 BufferedImage&#xff1a;用于表示图像的类&#xff0c;可以进行像素级的操作。Image&#xff1a;表示图像的抽象类&#xff0c;是所有图像类的基类。ImageIcon&#xff1a;用于显示图像的类&#xff0c;可以将图像嵌入到Swing组件中。Ima…

麒麟信安登录央视,深度展现为中国信息安全铸“魂”之路

麒麟信安登录央视&#xff0c;深度展现为中国信息安全铸“魂”之路 近日&#xff0c;麒麟信安登录央视频道&#xff0c;《麒麟信安——为中国信息安全铸“魂”》在CCTV-4中文国际频道、CCTV-7国防军事频道、CCTV-10 科教频道、CCTV-12社会与法频道、CCTV-17农业农村频道&#x…