Vivado下有限状态机的实现

news2025/2/25 12:04:20

文章目录

  • 1011状态机的实现
  • 四状态下的移位操作

处理相对复杂的逻辑时就会用到有限状态机,设定好不同的状态,根据触发条件跳转到相应的状态,然后在不同的状态下做相应的处理。有限状态机主要用到 always 语句和 case 语句。


1011状态机的实现

文章 Quartus II下设计一个用于识别2进制序列“1011”的状态机 是在 Quartus II 软件中设计的一个识别2进制序列“1011”的状态机,这里在 Vivado 中对该例子再进行实现。
设计源代码如下。

module timing(
    input  clk, 
    input  rst, 
    input  en,
    input  in, 
    output reg out
);

parameter ST0 = 0;
parameter ST1 = 1;
parameter ST2 = 2;
parameter ST3 = 3;
parameter ST4 = 4;

reg [2:0] state;
reg [2:0] next_state;

initial
begin
    next_state = ST0;
end

always @ (in or en or state)
begin
  case (state)
    ST0:
    begin 
		if(en == 1 && in == 1) 
			next_state = ST1;
		else 
			next_state = ST0;
	end
    ST1:
    begin 
		if(en == 1 && in == 0) 
		    next_state = ST2; 
		else if(en == 1 && in == 1) 
		    next_state = ST1;
		else 
		    next_state = ST0;
		end
    ST2:
    begin 
		if(en == 1 && in == 1) 
		    next_state = ST3; 
		else 
		    next_state = ST0;
		end
    ST3:
    begin 
		if(en == 1 && in == 1)
		    next_state = ST4;           
		else if(en == 1 && in == 0) 
		    next_state = ST2;
		else 
		    next_state = ST0;
		end
	//ST4:
	   //next_state = ST0;
   endcase 
end

always @ (posedge clk or negedge rst)
begin
  if(!rst)
    state <= ST0;
  else
    state <= next_state;
end

always @ (state or posedge clk) 
begin
  if(state == ST4)
    begin
        state = ST1;
        out = 1;
    end
  else 
     out = 0;
end

endmodule

仿真测试源代码如下。

module sim_timing();
reg clk;
reg rst;
reg en;
reg in;
wire out;

initial
begin
    en = 0;
    clk = 0;
    rst = 1;
    #50 
    en = 1;
    #400
    rst = 0;
    #50
    rst = 1;
end

initial
begin
    in = 0;
    forever
    begin
    #20
    in = {$random}%2;
    end 
end

always #10 clk = ~clk;

timing uut_timing(
    .clk(clk),
    .rst(rst),
    .en(en),
    .in(in),
    .out(out)
);
endmodule

仿真输出结果如下图所示。
在这里插入图片描述
通过上图可知,每输入一个“1011”序列,输出 out 就置为1,持续一个时钟周期后清零,输出结果与预想的一致。


四状态下的移位操作

下图中给出了四个状态,初始状态是 Idle,在此状态下判断移位开始信号 shift_start 是否为高,如果为高就进入Start 状态,在Start 状态下延迟若干个周期,进入 Run 状态,然后进行移位处理,如果移位停止信号shift_stop有效,进入Stop 状态,把存储器中的值清零然后返回到 Idle 状态。
在这里插入图片描述
Mealy 有限状态机的输出不仅与当前状态有关,也与输入信号有关。
Mealy 有限状态机的设计源代码如下。

module timing(
    input  clk, 
    input  rst, 
    input  in,
    input  shift_start, 
    input  shift_stop, 
    output reg[7:0] out
);

parameter Idle = 0;
parameter Start = 1;
parameter Run = 2;
parameter Stop = 3;

reg [1:0] state;
reg [3:0] count;

always @ (posedge clk or negedge rst)
begin
  if(!rst)
    begin
        state <= Idle;
        count <= 0;
        out <= 0;
    end
  else
  case(state)
    Idle:
        begin
            if(shift_start)
                state <= Start;
        end
    Start:
        begin
            if(count == 4'd10)
            begin
                count <= 0;
                state <= Run;
            end 
            else
                count <= count + 1'b1;   
        end
     Run:
        begin
            if(shift_stop)
                state <= Stop;
            else
                out <= {out[6:0],in};
        end
     Stop:
        begin
            out <= 0;
            state <= Idle;
        end
     default : state <= Idle;
     endcase 
end
endmodule

Moore 有限状态机的输出只与当前状态有关,与输入信号无关,输入信号只影响状态的改变,不影响输出。比如本例中的计数信号和输出信号。
Moore 有限状态机的设计源代码如下。

module timing(
    input  clk, 
    input  rst, 
    input  in,
    input  shift_start, 
    input  shift_stop, 
    output reg[7:0] out
);

parameter Idle = 0;
parameter Start = 1;
parameter Run = 2;
parameter Stop = 3;

reg [1:0] cur_state;
reg [1:0] next_state;
reg [3:0] count;

always @ (posedge clk or negedge rst)
begin
  if(!rst)
      cur_state <= Idle;
  else
      cur_state <= next_state;
end

always@(*)
begin
  case(cur_state)
    Idle:
        begin
            if(shift_start)
                next_state <= Start;
            else
                next_state <= Idle;
        end
    Start:
        begin
            if(count == 4'd10)
                next_state <= Run;
            else
                next_state <= Start;
        end
     Run:
        begin
            if(shift_stop)
                next_state <= Stop;
            else
                next_state <= Run;
        end
     Stop:
        next_state <= Idle;
     default : next_state <= Idle;
     endcase 
end

always@(posedge clk or negedge rst)
begin
    if(!rst)
        count <= 0;
    else if (cur_state == Start)
        count <= count + 1'b1;
    else
        count <= 0;
end

always@(posedge clk or negedge rst)
begin
    if(!rst)
        out <= 0;
    else if (cur_state == Run)
        out <= {out[6:0],in};
    else
        out <= 0;
end

endmodule

在上面两个程序中用到了两种方式的写法,第一种的 Mealy 状态机,采用了一段式的写法,代码中只用了一个 always 语句,所有的状态转移、判断状态转移条件、数据输出都在一个 always 语句里。这种写法的缺点是如果状态太多,会使整段程序显的冗长。第二种是 Moore 状态机,采用了三段式的写法,状态转移用了一个 always 语句,判断状态转移条件用了一个 always 语句,数据输出也用了一个 always 语句,这样写下来的代码比较直观清晰,状态很多时也不会显得繁琐。
两者的仿真测试代码是一样的,如下所示。

module sim_timing();
reg  clk;
reg  rst; 
reg  in;
reg  shift_start; 
reg  shift_stop; 
wire [7:0] out;

initial
begin
    clk = 0;
    rst = 0;
    in = 0;
    #100 
    rst = 1;
    forever
    begin
        #({$random}%100)
        in = ~in;
    end
end

initial
begin
    shift_start = 0;
    shift_stop = 0;
    #200
    shift_start = 1;
    #500
    shift_start = 0;
    shift_stop = 1;
    #50
    shift_stop = 0;
    shift_start = 1;
end

always #10 clk = ~clk;

timing uut_timing(
    .clk(clk),
    .rst(rst),
    .in(in),
    .shift_start(shift_start),
    .shift_stop(shift_stop),
    .out(out)
);
endmodule

仿真输出结果如下图所示。
在这里插入图片描述
由上图可以看到,在 Start 状态下,计数到 10 后就跳转到 Run 状态开始移位操作。上面的图是整体的仿真过程,移位操作看得不清楚,所以将输出 out 以二进制显示,放大图如下,可以看到在 shift_start 有效时,向左移位操作正确的进行。
在这里插入图片描述


以上就是 Vivado下有限状态机实现的所有内容了!
参考资料:
ZYNQ 开发平台 FPGA 教程 AX7020

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

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

相关文章

【C#项目实战】Winform音频播放器的制作

Hello大家好,我是雷工! 本篇记录Winform音频播放器的制作过程。 一、开发运行环境 1、系统开发平台:Visual Studio 2022。 2、系统开发语言:C#。 二、功能说明及效果演示 1、该音频播放器可以通过音频列表,显示可播放的音频名称,通过列表框下的添加、删除按钮可以向列…

简单、漂亮、容易上手的开源 SAAS 多租户快速开发平台,已开源

简介 开源里面UI较好、较容易上手的、中台 、SAAS 、 多租户功能、最最少的代码实现功能的快速开发平台。 特点 链路追踪&#xff1a; 支持 skywalking、zikpin、pinpoint 等多种链路追踪&#xff08;案例采用 skywalking&#xff09; 布局优雅&#xff1a; 简洁、多套主题以…

40从零开始学Java之方法重写和方法重载到底有哪些区别?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在前面的两篇文章中&#xff0c;壹哥给大家讲解了面向对象中的封装和继承&#xff0c;现在还有一个多…

物联网开发愈加深化,如何保障应用安全?

在如今的iot物联网定制市场&#xff0c;许多产品都在“物物互联”&#xff0c;通过远程通信和连接设备来提供数据采集和处理能力。智能设备与智能家居、智慧城市等领域的结合也越发紧密。而对于企业而言&#xff0c;应用物联网设备时&#xff0c;也需要注意其中的安全问题。那么…

苹果WWDC 2023发布会总结

今年的全球开发者大会没有让人失望。在今天的主题演讲中&#xff0c;苹果首次展示了备受期待的混合现实耳机&#xff0c;证实了过去几个月出现的许多谣言。 虽然这次苹果的 Vision Pro耳机成为了焦点&#xff0c;但该公司还发布了一些其他令人兴奋的硬件和软件相关公告。这是活…

Java 泛型机制详解

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; 文章目录 一、Java 中…

python中对excel工作表的基础操作:xlrd、xlwt模块笔记

模块介绍 &#xff08;1&#xff09;什么是xlrd模块&#xff1f; python操作excel主要用到xlrd和xlwt这两个库&#xff0c;即xlrd是读excel&#xff0c;xlwt是写excel的库。 &#xff08;2&#xff09;为什么使用xlrd模块&#xff1f; 在UI自动化或者接口自动化中数据维护是一…

突然断电没保存的文档如何找回?给你支几招!

概述&#xff1a;突然断电没保存的文档如何找回&#xff1f;我们在办公中经常会用到Word/PPT/EXCEL等文档&#xff0c;要是正在编辑时&#xff0c;电脑突然断电了&#xff0c;而文档还来得及保存怎么办&#xff1f;不要着急&#xff0c;下面教你找回未保存的文档。 一、突然断…

nodered-环境搭建及使用

nodered-环境搭建及使用 一、准备工作 - 安装node.js二、 nodered安装2.1 windows10环境下安装2.2 linux环境下安装 三、 nodered使用3.1 面板操作3.2 公共节点的使用3.3 上下文、全局变量 四、node缓存清理五、后台运行六、 nodered卸载 IBM发行了一套开源可视化界面开发工具&…

Hive学习---6、文件格式和压缩

1、文件格式和压缩 1.1 Hadoop压缩概述 由于Hive是相当于与Hadoop的客户端&#xff0c;所以hadoop会啥压缩&#xff0c;Hive基本就会啥压缩。 压缩格式算法文件扩展名是否可切分DEFLATEDEFLATE.deflate否GzipDEFLATE.gz否bzip2bzip2.bz2是LZOLZO.lzo是SnappySnappy.snappy否…

页面置换算法(LRU,CLOCK,LFU)

在操作系统的数据库中&#xff0c;使用驱逐算法来实现内存和磁盘之间的交互。当内存空间已满且需要将磁盘上的页面添加到内存中时&#xff0c;就需要将内存中的一个页面换出&#xff0c;以保证内存空间不会溢出。我们希望尽可能多地访问内存中的页面。 LRU算法 LRU算法&#…

0基础学习VR全景平台篇第38章:场景功能-AI虚拟人实操完整教程

AI虚拟人功能正式上线&#xff01; 依托“虚拟数字人引擎”结合VR全景&#xff0c;为各行各业提供虚拟形象生成、驱动、交互服务&#xff0c;帮助海量用户的VR全景作品&#xff0c;打造成为更具沉浸感的VR交互项目&#xff0c;提升作品变现能力。 功能位置示意 一、什么是AI虚…

会声会影视频乱码什么原因 会声会影视频乱码怎么处理

会声会影编辑视频的过程中&#xff0c;如果遇到素材乱码的问题&#xff0c;是会让人十分崩溃的。毕竟素材来之不易&#xff0c;无论是重新下载还是重新录制素材&#xff0c;操作起来都是相当困难的。那么&#xff0c;会声会影视频乱码什么原因&#xff0c;会声会影视频乱码怎么…

C++设计模式之原型模式(Prototype)

[C]22种设计模式的C实现大纲 文章目录 定义别名前言1. 问题2. 解决方案 结构1. 基本实现2. 原型注册表实现 适用场景实现方式优点缺点与其他模式的关系实例 定义 原型是一种创建型设计模式&#xff0c;使你能够复制已有对象&#xff0c;而又无需使代码依赖它们所属的类。 别…

利用fabric绘画矩形和多边形

需求在一张图片上标注矩形和多边形&#xff0c;支持回显&#xff1b; fabric版本&#xff1a;4.6.0&#xff1b; Fabric.js 是一个功能强大且操作简单的 Javascript HTML5 canvas 工具库。 官方文档 参考链接 组件代码drawer.vue createUuid 是为了让每一个图形有自己的id&…

【 Python 全栈开发 - 语法基础篇 - 20 】数据可视化

文章目录 一、数据可视化二、pandas1. 折线图2. 散点图3. 柱状图4. 饼图 三、matplotlib1. 折线图2. 散点图3. 柱状图4. 饼图 四、seaborn1. 安装和导入Seaborn2. 加载数据集3. 绘制散点图4. 绘制直方图5. 绘制核密度图6. 绘制条形图7. 绘制热力图 五、plotly安装plotly创建图表…

chatgpt赋能python:如何重新运行Python程序:完整指南

如何重新运行Python程序&#xff1a;完整指南 Python是最受欢迎的编程语言之一&#xff0c;因为其语法简单易懂&#xff0c;使得编写高效可读性代码更加轻松。但在编程过程中经常会出现需要重新运行程序的情况&#xff0c;本文将为您介绍如何重新运行Python程序。 重新运行Py…

chatgpt赋能python:Python如何降低memory的方法

Python如何降低memory的方法 Python已经成为了世界上最流行的编程语言之一&#xff0c;它在开发web应用、机器学习、数据分析等领域中拥有广泛的应用。然而&#xff0c;由于Python的内存管理机制&#xff0c;可能会导致程序的内存占用过高&#xff0c;影响系统的性能。在本文中…

excel文档翻译软件怎么使用?告诉你怎么翻译整个excel文档

excel是一款电子表格软件&#xff0c;广泛应用于数据分析、统计和管理等领域。然而&#xff0c;当我们需要处理包含其他语言的excel文档时&#xff0c;可能会遇到语言障碍。不用担心&#xff0c;现在有一些方便的软件可以帮助我们轻松翻译excel文档。今天我们就一起来看看excel…

UniApp个人总结:新建页面大汇总

文章目录 往期回顾正文本篇目标环境安装如何新建模板页面页面布局推荐新建模板文件 总结 往期回顾 uniapp 踩坑记录 uni.$on为什么不能修改data里面的数据 uniApp页面通讯大汇总&#xff0c;如何页面之间传值 uniApp 页面通讯统一解决方案 uniapp sqlite 数据库操作封装 un…