Verilog 有限状态机

2023-05-16

状态机基本概念

状态机,全称是有限状态机( Finite State Machine,缩写为FSM),是一种在有限个状态之间按一定规律转换的时序电路,可以认为是组合逻辑和时序逻辑的一种组合。 状态机通过控制各个状态的跳转来控制流程,使得整个代码看上去更加清晰易懂,在控制复杂流程的时候,状态机优势明显,因此基本上都会用到状态机,如SDRAM控制器等。
 

时钟同步的状态机结构(Mealy 状态机)

上图表示的是数字电路设计中常用的时钟同步状态机的结构。其中状态寄存器是由一组触发器组成,用来记忆状态机当前所处的状态。如果状态寄存器由n个触发器组成,这个状态机最多可以记忆2°个状态。所有的触发器的时钟端都连接在一个共同的时钟信号上,所以状态的改变只可能发生在时钟的跳变沿上。可能发生的状态的改变由正跳变还是由负跳变触发﹐取决于触发器的类型。状态是否改变,怎样改变还将取决于产生下一状态的组合逻辑F的输出,F是当前状态和输入信号的函数。状态机的输出是由输出组合逻辑G提供的,G也是当前状态和输人信号的函数。现代电路设计常用正跳变沿触发的D触发器,特别是在可编程逻辑器件上实现的用综合工具自动生成的状态机,其电路结构往往都是使用正跳变沿触发的D触发器。目前的JK触发器,其他类型的触发器和锁存器已经很少使用。图中的F和G两部分都是纯组合逻辑,它们的逻辑函数表达式如下:
下一个状态=F(当前状态,输入信号);

输出信号一G(当前状态,输入信号);

根据输出信号是否还取决于输入,状态机分为两类:

  • Moore(摩尔) 状态机:组合逻辑的输出只取决于当前状态;即输出信号一G(当前状态)。
  • Mealy (米勒)状态机:组合逻辑的输出不仅取决于当前状态,还取决于输入信号;即输出信号一G(当前状态,输入信号)
时钟同步的状态机结构(Moore 状态机)

 状态机设计流程

根据设计需求画出状态转移图,确定使用状态机类型,并标注出各种输入输出信号,更有助于编程。一般使用最多的是 Mealy 型 3 段式状态机。

三段式状态机

状态机设计如下:

  • (0) 首先,根据状态机的个数确定状态机编码。利用编码给状态寄存器赋值,代码可读性更好。
  • (1) 状态机第一段,时序逻辑,非阻塞赋值,传递寄存器的状态。
  • (2) 状态机第二段,组合逻辑,阻塞赋值,根据当前状态和当前输入,确定下一个状态机的状态。
  • (3) 状态机第三代,时序逻辑,非阻塞赋值,因为是 Mealy 型状态机,根据当前状态和当前输入,确定输出信号。
`timescale 1ns/1ns
module fsm_ex(
	input wire clk  ,
	input wire rst  ,
	input wire d1 ,
	input wire d2 ,
	input wire d3 ,
	
	output reg out1,
	output reg out2
);


reg [2 : 0] next_state, current_state;

//将输入组合起来
wire [2 : 0] data_in;
assign data_in = {d3, d2, d1};

parameter s0 = 3'd0;
parameter s1 = 3'd1;
parameter s2 = 3'd2;
parameter s3 = 3'd3;
parameter s4 = 3'd4;
parameter s5 = 3'd5;
parameter s6 = 3'd6;

//1、state transfer
//第一段:传递寄存器状态,时序逻辑,非阻塞赋值
always @(posedge clk or negedge rst) begin
    if (! rst) begin
        current_state <= s0;
    end
    else begin
        current_state <= next_state;
    end
end


//2、state switch, using block assignment for combination-logic 
//all case items need to be displayed completely 
//第二段:根据当前状态和当前输入确定下一状态,组合逻辑,阻塞赋值
always @(*) begin
    if(! rst) begin
        next_state = s0;
    end
    else begin
        case(current_state)
            s0: begin
                case(data_in) 
                    3'b001 : next_state = s1;
                    3'b010 : next_state = s2;
                    3'b100 : next_state = s4;
                    default : next_state = next_state;
                endcase
            end
            s1: begin
                case(data_in) 
                    3'b001 : next_state = s2;
                    3'b010 : next_state = s3;
                    3'b100 : next_state = s5;
                    default : next_state = next_state;
                endcase
            end
            s2: begin
                case(data_in) 
                    3'b001 : next_state = s3;
                    3'b010 : next_state = s4;
                    3'b100 : next_state = s6;
                    default : next_state = next_state;
                endcase
            end
            default : next_state = s0;
        endcase
    end
end

//3、output logic, using non-block assignment 
//第三段:Mealy状态机中,根据当前状态和当前输入确定输出,时序逻辑,非阻塞赋值
always @ (posedge clk or negedge rst) begin
    if(! rst) begin
        out1 <= 1'd0;
        out2 <= 2'd0;
    end
    else begin
        case(current_state)
            s3 : begin
                out1 <= 1'd1;
                out2 <= 2'd0;
            end
            s4 : begin
                out1 <= 1'd1;
                out2 <= 2'd1;
            end
            s5 : begin
                out1 <= 1'd1;
                out2 <= 2'd2;
            end
            s6 : begin
                out1 <= 1'd1;
                out2 <= 2'd3;
            end
        default : begin
            out1 <= 1'd0;
            out2 <= 2'd0;            
        end
        endcase
    end
end

endmodule

两段式状态机 

将 3 段式状态机 2、3 段描述合并,其他部分保持不变,状态机就变成了 2 段式描述。

参考文献:夏宇闻《Verilog数字系统设计》、 runoob Verilog教程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Verilog 有限状态机 的相关文章

  • 在verilog中使用for循环生成

    我试图理解为什么我们在verilog 中使用generate 和for 循环 一起使用生成和 for 循环 reg 3 0 temp genvar i generate for i 0 i lt 3 i i 1 begin always p
  • Verilog 位更改位置

    假设我有一个寄存器reg 15 0 my reg 其中包含一个16位signed sample 如何找到第一位变化的位置 意思是 如果假设my reg 16 b0001011011010111 我怎么知道第一个变化是0 to 1 is at
  • Verilog HDL 循环语句错误:具有非常量循环条件的循环必须终止

    我对 Verilog 完全陌生 对于我在大学学习的课程 我必须很快了解它的很多内容 我正在摆弄我的 Altera DE2 板和 quartis2 并了解其细节 我正在尝试制作一个通过开关打开和关闭的计数器 到目前为止 计数器根据按键进行计数
  • 带有always_comb结构的Systemverilog问题

    我对这个 SystemVerilog 代码有疑问 这是代码 module mult multiplicand multiplier Product clk clear Startm endm input 31 0 multiplicand
  • 「Verilog学习笔记」游戏机计费程序

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点 刷题网站用的是牛客网 timescale 1ns 1ns module game count input rst n 异位复位信号 低电平有效 input clk 时
  • x 和 z 值在 Verilog 中到底代表什么?

    Verilog 标准定义了四种类型的位值 0 1 x 和 z 其中 0 表示低 1 表示高 x 表示未知 z 表示未驱动网络 有几个问题 x 是否意味着我们不知道该值是 0 还是 1 0 或 1 或 z 或者该值是未知的并且可以是 0 1
  • 用于 Verilog 或 SystemVerilog 的 TAP(测试任何协议)模块

    是否有 TAP 测试任何协议 http testanything org Verilog 的实现 那就太好了 因为这样我就可以使用证明来自动检查我的结果 更新 10 9 09 有人问为什么不使用断言 部分 TAP 为我提供了一些很好的报告
  • 如何在verilog中逐行读取文本文件?

    我有一个 SREC 文件 它是一个简单的文本文件 我想在 verilog 中逐行读取它 我怎样才能做到这一点 以下读取文件 每个时钟周期 1 行 预期的数据格式是每行一个十进制数 integer data file file handler
  • 在逻辑中使用单端端口期待差异对?

    我使用的逻辑被设置为需要一个差分对时钟端口 然而 对于一个特定的应用程序 我只能输入一个单端时钟 由于硬件限制 修改逻辑以接受单端时钟不是一种选择 因为涉及许多文件和代码行 有没有办法可以输入单端端口并以某种方式将其馈送到模块的差异对端口
  • 如何获取值数组作为 plusargs?

    如何获取值数组作为参数 我需要从命令行获取一组未定义大小的命令 如何将这些参数放入数组或队列中 Eg CMDS READ WRITE READ N WRITE 它应该被带到一个数组中 value plusargs不支持数组 但支持字符串 看
  • 如何将时钟门映射到技术库单元

    我的设计中有以下时钟门 module my clkgate clko clki ena Clock gating latch triggered on the rising clki edge input clki input ena ou
  • verilog $readmemh 对于 50x50 像素 RGB 图像花费太多时间

    我正在尝试编译用于 FPGA 编程的 verilog 代码 我将在其中实现 VGA 应用程序 我使用 QuartusII 和 Altera 我正在尝试正确使用 readmemh 来逐像素获取图片 现在 我已经使用 matlab 将图片转换为
  • 开始后跟冒号和变量是什么意思?

    什么是data mux意思是这里 它只是块的名称吗 if PORT CONFIG 32 P0 1 b1 begin data mux end 这些是块名称 它们特别适用于generate块 例如 您可以定义一个generate块如 genv
  • 在 Verilog 设计中产生时钟故障

    我正在使用 Verilog 设计芯片 我有一个 3 位计数器 我希望当计数器处于第 8 次循环时 应该有一个时钟故障 之后就可以正常工作了 在 Verilog 设计中产生时钟故障的可能方法是什么 在时钟信号上注入毛刺的一种方法是使用forc
  • 在 Verilog 程序中使用连续分配?

    在 Verilog 程序中使用连续赋值是否可能和 或有用 例如 是否有任何理由将assign里面一个always堵塞 例如这段代码 always begin assign data in Data end 此外 是否可以用这种方法生成顺序逻
  • 如何在 Verilog 中推断 Block RAM

    我在一个项目中遇到了一个非常具体的问题 这个问题已经困扰我好几天了 我有以下 RAM 模块的 Verilog 代码 module RAM param clk addr read write clear data in data out pa
  • 学习 Verilog 的资源 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我是 Verilog 新手 有人可以推荐学习资源 书籍 视频 博客或任何他们有良好个人经验并帮助他们更
  • 为什么我们在FGPA / VHDL / VIVADO中使用REG?

    我正在使用 Xilinx 的 vivado 在 verilog 中进行编程 我想知道为什么我们使用某些输出reg 例如reg 3 0 encoder output我们使用它是因为我们的 16 到 4 编码器有 4 个输出 对吧 我假设我们使
  • 仿真输出全为零

    我的设计模块和测试平台代码已编译 但是 当我模拟时 我没有得到正确的输出 谁能告诉我我的代码哪里出了问题 这是测试平台的代码 module testbench reg 511 0 FROM LS reg CLK reg 63 0 TO IF
  • 修改verilog模式缩进

    我试图让 verilog 模式使用 2 个空格缩进除 decls 和always 之外的所有内容 这是我添加到 emacs 中的内容 define are not indented setq veril

随机推荐

  • 拓扑排序的C++实现

    tags C 43 43 DSA Sort GT 写在前面 写一下有向无环图 DAG Directed Acyclic Graph 上的拓扑排序 废话不多说了 介绍部分大家可以参考算法导论或者 oi wiki https oi wiki o
  • Windows上使用winedt提示系统找不到文件的情况分析+texlive安装与配置

    tags LaTeX Debug 问题 最近有同学问我在 Windows 上使用 WinEdt 这款编辑器为什么会提示系统找不到文件 我搜索一下发现大概率是 TeX L i v e
  • LaTeX常见错误与常用Debug方法总结

    tags LaTeX Debug 前言 在LaTeX中 常常会出现很多意想不到的错误 我一开始学习的时候 就常常被这种看似玄学的错误整的焦头烂额 常常是打开一堆CSDN界面各处翻找而没有一个合适的解决方案 之后在不断的使用和摸索中 我对于
  • SQL中的七种关联代数与额外关联代数总结

    tags SQL 写在前面 总结一下 cmu15445 第一节课的内容 前面的可以不听 主要是 40 分钟往后的内容 视频 01 Relational Model amp Relational Algebra CMU Intro to Da
  • 如何恢复MAC苹果电脑系统数据文件恢复详细教程

    Mac电脑也可以使用shift加delete进行文件的永久删除 xff0c 因为这样不仅方便快速 xff0c 还能够不占回收站的内存 但是如果你不小心永久删除了重要的数据 xff0c 也就意味着不能从回收站还原了 xff0c 该怎么办呢 x
  • 快速解决 MacOS 启动台程序删除之后图标仍存在显示问号的问题

    解决 第一个方案是更新 sqlite 数据库 但是这个方案会改动启动台图标的顺序 还是不推荐的 第二个方案最近摸索出来的 直接把图标拖拽到废纸篓即可 怒赞
  • Jekyll博客中添加分类与多目录存放博客的方法

    categories Frontend tags Frontend HTML 写在前面 最近发现一个问题 博客数量越来越多了 都放在 posts下实在是有点不方便 于是想着分个类 Google 了一圈 找到了一篇不错的博客 如下 Jekyl
  • 推荐三本wpf的书

    1 葵花宝典WPF 2 WPF深入浅出 3 WPF编程宝典 个人粗略浏览了一遍 xff0c 第二本收获比较多 xff0c 第三本比较全面 xff0c 第一本相对来说没那么枯燥 xff0c 前两本我有pfd的资源文件 xff0c 需要的留言我
  • C++实现A钱买A鸡问题

    总时间限制 10000ms 单个测试点时间限制 1000ms 内存限制 131072kB 描述 A钱买A鸡 的问题 xff1a 3文钱可以买1只公鸡 xff0c 2文钱可以买1只母鸡 xff0c 1文钱可以买3只小鸡 xff0c 要用A文钱
  • equals 和 hashCode 的区别

    1 equals 和 hashCode 的区别 equals 和 hashcode 这两个方法都是从 Object 类中继承过来的 hashCode xff1a 计算出对象实例的哈希码 xff0c 并返回哈希码 xff0c 又称为散列函数
  • (踩坑)windows下的linux子系统迁移至非系统盘

    踩坑如下 xff1a 先在微软应用市场下载linux然后安装完 xff0c 再做目录链接会出现linux启动失败问题 先做目录链接会导致应用市场下载linux失败 xff0c 如下图 xff1a 正确操作如下 xff1a 注意两个路径 xf
  • 2、Zabbix 添加主机和监控项

    一 修改用户密码 1 zabbix默认会监控zabbix server本机 xff0c 如果不想监控可以在 xff08 配置 主机 xff09 里禁用掉 2 zabbix的用户都属于某个用户组 xff0c 而权限的控制都是通过用户组的 xf
  • Ubuntu进入文件夹路径及查看文件夹目录

    在Ubuntu中 xff0c 我们进入了一个文件夹 xff0c 如何看这个文件夹此时的路径呢 xff1f 通过Ctrl 43 L 可以看到路径 xff0c 然后Ctrl 43 C复制路径 再通过命令行中cd 路径 进入刚刚的文件夹 如何查看
  • WebService实例

    一 发布webservice服务 1 编写服务接口 package com nari test webservice import javax jws WebMethod import javax jws WebParam import j
  • C#使用selenium写爬虫提高速度的关键

    这段时间一直在搞爬虫 xff0c 学了一段时间之后 xff0c 最后还是使用的selenium模拟浏览器来进行爬取 就来记录一下自己踩的坑 一开始在网上找提升selenium爬虫速度的方法 xff0c 都是说什么多线程 xff0c 关闭图片
  • coreldraw2022直装版下载 永久免费使用 附安装教程( 仅限 win 10 用户 )

    CorelDRAW2022又被大家伙简称为cdr2022 xff0c 这是由加拿大Corel公司制作推出的一款老牌图形平面设计软件 xff0c 当然虽然该软件是好早之前就有了 xff0c 但是本次小编要介绍的是该系列最新的2022版本 在该
  • win10/11下WSL 图形界面安装配置指南

    win10 11下WSL 图形界面安装配置指南 一 首先安装WSL xff08 这里安装的是Ubuntu 20 04 LTS xff09 二 MobaXterm安装 xff1a 神器MobaXterm xff0c 能同时支持XShell和X
  • WSL安装迁移以及可能会遇到的问题

    可能需要的命令 xff1a 查看ubuntu版本 xff1a lsb release a 修改文件参数 xff1a G WSL grant 34 rx OI CI F 34 查看一下wsl的版本 xff0c PowerShell 命令行并输
  • namespace “std“没有成员“function“

    添加头文件 include lt functional gt 确保C 43 43 版本为C 43 43 11或更高
  • Verilog 有限状态机

    状态机基本概念 状态机 xff0c 全称是有限状态机 xff08 Finite State Machine xff0c 缩写为FSM xff09 xff0c 是一种在有限个状态之间按一定规律转换的时序电路 xff0c 可以认为是组合逻辑和时