有限状态机设计(Verilog HDL)

这篇具有很好参考价值的文章主要介绍了有限状态机设计(Verilog HDL)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、有限状态机

- 基本概念
有限状态机(Finite State Machine, FSM)是电路设计的经典方法,通常可以认为是组合逻辑和寄存器逻辑的组合,其中组合逻辑用于状态译码和产生输出信号,寄存器用于存储状态。

- Moore和Mealy型状态机
摩尔型(Moore)状态机: 输出只是当前状态的函数
米利型(Mealy)状态机: 输出是当前状态和当前输入的函数

似乎不太好理解,我们结合状态机模型来看一下

有限状态机设计,笔记,fpga开发,嵌入式硬件
可以看出,Moore型状态机输出只与当前状态(现态CS)有关

有限状态机设计,笔记,fpga开发,嵌入式硬件
图中可以看出,Mealy型状态机相较于Moore型状态机,其输出逻辑多了一个输入端,即上述定义所说的Mealy型状态机输出由当前状态(现态CS)和当前输入决定。

- 两种状态机的区别
由于两者模型的差别,不难看出,Mealy型状态机当输入改变时输出也会立即改变,不依赖时钟,而Moore型状态机输入状态改变时,需要经过时钟同步后输出才会改变,即Moore型状态机比Mealy型状态机输出要多一个时钟周期。实用的状态机一般都设计成同步时序模式。

二、有限状态机的Verilog描述

-状态机的设计中主要包含以下3个对象:

  • 当前状态,或称为现态(Current State, CS)
  • 下一状态,或称为次态(Next State, NS)
  • 输出逻辑(Out Logic, OL)

-Verilog描述方式

  • 三段式描述(CS、NS、OL)
  • 两段式描述(CS+NS、OL)或(CS、NS+OL)
  • 单段式描述(CS+NS+OL)

-举例(可乐机:2.5¥出可乐,可以投入0.5¥、1¥)
1.先画出状态转移图,比较丑,但大概是这样,简单起见,不考虑找零,不投硬币也不算输入。
有限状态机设计,笔记,fpga开发,嵌入式硬件
2.Verilog描述

2.1三段式描述

//三段式描述(CS、NS、OL)

module  Coke_Machine										//模块名
(
	input		wire		sys_clk		 	,				//输入时钟
	input		wire		sys_rst_n	 	,				//输入复位
	input		wire		pi_money_half	,				//输入0.5
	input		wire		pi_money_one	,				//输入1.0
	
	output	reg		po_cola
);

parameter		IDLE      = 5'b00001,			//状态编码,独热码
				HALF	  = 5'b00010,
				ONE       = 5'b00100,
				ONE_HALF  = 5'b01000,
				TWO	      = 5'b10000;

wire	[1:0]		pi_money;
reg 	[4:0]		state,next_state;

assign	pi_money = {pi_money_one,pi_money_half};				//合并输入,即输入0.5为01,输入1为10

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		state <= IDLE;											//定义起始状态
	else
		state <= next_state;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		state <= IDLE;											//定义起始状态
	else	case(state)
		IDLE:		if(pi_money == 2'b01)
						next_state <= HALF;
					else if(pi_money == 2'b10)
						next_state <= ONE;
					else
						next_state <= IDLE;
		HALF:		if(pi_money == 2'b01)
						next_state <= ONE;
					else if(pi_money == 2'b10)
						next_state <= ONE_HALF;
					else
						next_state <= HALF;
		ONE:		if(pi_money == 2'b01)
						next_state <= ONE_HALF;
					else if(pi_money == 2'b10)
						next_state <= TWO;
					else
						next_state <= ONE;
		ONE_HALF:	if(pi_money == 2'b01)
						next_state <= TWO;
					else if(pi_money == 2'b10)
						next_state <= IDLE;
					else
						next_state <= ONE_HALF;
		TWO:		if(pi_money == 2'b01)
						next_state <= IDLE;
					else if(pi_money == 2'b10)
						next_state <= HALF;
					else
						next_state <= TWO;
		default:	next_state <= IDLE;
		endcase

always@(posedge sys_clk or negedge sys_rst_n)									//输出逻辑
	if(sys_rst_n == 1'b0)
		po_cola <= 1'b0;
	else if(((state == ONE_HALF) && (pi_money == 2'b10))
			|| ((state == TWO) && (pi_money == 2'b01))
			|| ((state == TWO) && (pi_money == 2'b10)))
		po_cola <= 1'b1;
	else
		po_cola <= 1'b0;
		
endmodule

2.2两段式描述(CS+NS、OL)

//两段式描述(CS+NS、OL)


module  Coke_Machine										//模块名
(
	input		wire		sys_clk		 	,				//输入时钟
	input		wire		sys_rst_n	 	,				//输入复位
	input		wire		pi_money_half	,				//输入01
	input		wire		pi_money_one	,				//输入10
	
	output	reg		po_cola
);

parameter		IDLE      = 5'b00001,			//状态编码,独热码
				HALF	  = 5'b00010,
				ONE       = 5'b00100,
				ONE_HALF  = 5'b01000,
				TWO	      = 5'b10000;

wire	[1:0]		pi_money;
reg 	[4:0]		state;

assign	pi_money = {pi_money_one,pi_money_half};				//合并输入,即输入0.5为01,输入1为10

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		state <= IDLE;											//定义起始状态
	else	case(state)
		IDLE:		if(pi_money == 2'b01)
						state <= HALF;
					else if(pi_money == 2'b10)
						state <= ONE;
					else
						state <= IDLE;
		HALF:		if(pi_money == 2'b01)
						state <= ONE;
					else if(pi_money == 2'b10)
						state <= ONE_HALF;
					else
						state <= HALF;
		ONE:		if(pi_money == 2'b01)
						state <= ONE_HALF;
					else if(pi_money == 2'b10)
						state <= TWO;
					else
						state <= ONE;
		ONE_HALF:	if(pi_money == 2'b01)
						state <= TWO;
					else if(pi_money == 2'b10)
						state <= IDLE;
					else
						state <= ONE_HALF;
		TWO:		if(pi_money == 2'b01)
						state <= IDLE;
					else if(pi_money == 2'b10)
						state <= HALF;
					else
						state <= TWO;
		default:	state <= IDLE;
		endcase

always@(posedge sys_clk or negedge sys_rst_n)									//输出逻辑
	if(sys_rst_n == 1'b0)
		po_cola <= 1'b0;
	else if(((state == ONE_HALF) && (pi_money == 2'b10))
			|| ((state == TWO) && (pi_money == 2'b01))
			|| ((state == TWO) && (pi_money == 2'b10)))
		po_cola <= 1'b1;
	else
		po_cola <= 1'b0;
		
endmodule

2.3单过程描述

//单段式描述


module  Coke_Machine										//模块名
(
	input		wire		sys_clk		 	,				//输入时钟
	input		wire		sys_rst_n	 	,				//输入复位
	input		wire		pi_money_half	,				//输入01
	input		wire		pi_money_one	,				//输入10
	
	output	reg		po_cola
);

parameter		IDLE      = 5'b00001,			//状态编码,独热码
				HALF	  = 5'b00010,
				ONE       = 5'b00100,
				ONE_HALF  = 5'b01000,
				TWO	      = 5'b10000;

wire	[1:0]		pi_money;
reg 	[4:0]		state;

assign	pi_money = {pi_money_one,pi_money_half};				//合并输入,即输入0.5为01,输入1为10

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		state <= IDLE;											//定义起始状态
	else	case(state)
		IDLE:		if(pi_money == 2'b01)
					begin
						state <= HALF;
						po_cola <= 1'b0;
					end
					else if(pi_money == 2'b10)
					begin
						state <= ONE;
						po_cola <= 1'b0;
					end
					else
					begin
						state <= IDLE;
						po_cola <= 1'b0;
					end
		HALF:		if(pi_money == 2'b01)
					begin
						state <= ONE;
						po_cola <= 1'b0;
					end
					else if(pi_money == 2'b10)
					begin
						state <= ONE_HALF;
						po_cola <= 1'b0;
					end
					else
					begin
						state <= HALF;
						po_cola <= 1'b0;
					end
		ONE:		if(pi_money == 2'b01)
					begin
						state <= ONE_HALF;
						po_cola <= 1'b0;
					end
					else if(pi_money == 2'b10)
					begin
						state <= TWO;
						po_cola <= 1'b0;
					end
					else
					begin
						state <= ONE;
						po_cola <= 1'b0;
					end
		ONE_HALF:	if(pi_money == 2'b01)
					begin
						state <= TWO;
						po_cola <= 1'b0;
					end
					else if(pi_money == 2'b10)
					begin
						state <= IDLE;
						po_cola <= 1'b1;
					end
					else
					begin
						state <= ONE_HALF;
						po_cola <= 1'b0;
					end
		TWO:		if(pi_money == 2'b01)
					begin
						state <= IDLE;
						po_cola <= 1'b1;
					end
					else if(pi_money == 2'b10)
					begin
						state <= HALF;
						po_cola <= 1'b1;
					end
					else
					begin
						state <= TWO;
						po_cola <= 1'b0;
					end
		default:	
					begin
						state <= IDLE;
						po_cola <= 1'b0;
					end
		endcase
		
endmodule

三、状态编码

常用编码方式:

  1. 顺序编码 采用顺序的二进制数编码每个状态,例有4个状态:00、01、10、11。优点是占用位数少,缺点是从一个状态转换到相邻状态时,可能有多个比特位同时变化,容易产生毛刺,引发逻辑错误。
  2. 格雷编码 采用格雷码的方式编码每个状态,例有4个状态:00、01、11、10.优点是位数少节约了逻辑单元,因为相邻状态跳转只有一个比特位的改变,也减少了瞬变次数和毛刺产生的可能。
  3. 约翰逊编码 在约翰逊计数器的基础上引出约翰逊码,把输出最高位取反再反馈到最低位,例有6个状态:000、001、011、111、110、100,同样相邻两个状态只有一个比特位不同,但占用位宽多了。
  4. 1位热码编码(独热码) 采用n个触发器编码n个状态,例有4个状态:0001、0010、0100、1000 。独热码占用位数最多,但可以有效节省和简化译码电路,用的也较多。

**参考资料:
王金明.《FPGA设计与Verilog HDL实现》.北京:电子工业出版社,2021.文章来源地址https://www.toymoban.com/news/detail-579205.html

到了这里,关于有限状态机设计(Verilog HDL)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA设计编程(四) 有限状态机设计

    目录 【实验要求】  【实验软件工具】 【实验一】设计一个交通红绿灯控制器模块,实现主干道和支路之间红绿黄灯的信号转换 1. 实验内容与原理说明   2. 实验模块程序代码和激励代码 (1)设计模块代码 (2)激励模块代码 3. 波形仿真图 4.门级电路图 【实验二】设计一个小轿

    2024年02月06日
    浏览(31)
  • 12-同步状态机的结构以及Mealy和Moore状态机的区别,Verilog实现有限状态机的4种方式,以及总结有限状态机设计的一般步骤

    由于寄存器传输级(RTL)描述的是以时序逻辑抽象所得到的有限状态机为依据,因此,把一个时序逻辑抽象成一个同步有限状态机是设计可综合风格的Verilog HDL模块的关键。 在本章节中,在了解状态机结构的基础上通过各种实例,由浅入深地介绍各种可综合风格的Verilog HDL模

    2024年01月17日
    浏览(36)
  • 基于FPGA的DDS原理信号发生器设计 quartusII 9.1平台 Verilog HDL语言编程 可产生正弦波

    基于FPGA的DDS原理信号发生器设计 quartusII 9.1平台 Verilog HDL语言编程  可产生正弦波、方波、锯齿波以及三角波   频率幅度可调节   代码+原理图 在现代电子技术领域,针对各种应用的信号发生器是一种非常核心的设备,而基于现场可编程逻辑门阵列(FPGA)的直接数字合成(

    2024年04月27日
    浏览(43)
  • 基于FPGA的多通道数据采集系统Verilog设计嵌入式

    基于FPGA的多通道数据采集系统Verilog设计嵌入式 在本文中,我们将介绍基于FPGA的多通道数据采集系统的Verilog设计,该系统可用于同时采集和处理多个通道的数据。我们将详细讨论系统的设计原理和实现步骤,并提供相应的Verilog源代码。 系统概述 多通道数据采集系统是一种

    2024年02月07日
    浏览(52)
  • 【Verilog HDL】FPGA-Verilog文件的基本结构

    🎉欢迎来到FPGA专栏~Verilog文件的基本结构 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ Verilog HDL系列博客参考书籍 《

    2024年02月04日
    浏览(73)
  • 【Verilog HDL实践】状态机:8路彩灯控制程序

    【Verilog HDL实践】8路彩灯控制程序 使用芯片:Altera Cyclone® IV EP4CE22F17C6N FPGA 开发工具:Quartus Ⅱ 开发项目: 四、设计一个8路彩灯控制程序,要求彩灯重复显示以下6种演示花型,在演示过程中,只有当一种花型演示完毕才能转向其他演示花型。 (1)8路彩灯同时亮灭; (2)从左至

    2024年02月05日
    浏览(24)
  • FPGA用verilog HDL实现串口通讯协议

    串口通信是一种通过串行传输数据的通信方式。它使用单个数据线将数据位逐个传输,而不是同时传输多个数据位。串口通信常用于连接计算机与外部设备,如打印机、调制解调器、传感器等。 串口通信一般使用的是异步传输方式,即发送方和接收方的时钟不同步。数据传输

    2024年02月05日
    浏览(46)
  • 【Verilog HDL】FPGA-testbench基础知识

    🎉欢迎来到FPGA专栏~testbench基础知识 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 📜在开发FPGA的过程中,需要掌握V

    2024年02月12日
    浏览(28)
  • 【FPGA】组合逻辑电路三种建模方式(Verilog HDL 门级建模、Verilog HDL 数据流建模、组合电路行为级建模)

    目录   Verilog HDL 门级建模 各种逻辑门的表示和使用 门级建模书写实例 Verilog HDL 数据流建模 数据流建模 数据流建模书写实例 组合电路行为级建模 always语句 条件语句 多路分支语句 循环语句 for while repeat forever 行为级建模示例   可以理解为对逻辑电路中各个门依次进行描述

    2024年04月13日
    浏览(35)
  • verilog键盘输入示例代码及分析(摩尔型有限状态机)

    往昔鸳鸯戏水,而今不相依偎,美景良辰纵然抚媚亦徒留伤悲。----《美人画卷》 本代码是一生一芯项目中,南京大学nvboard开源项目键盘扫描示例代码。我们抛开上层连接不谈,分析一下这个代码。同时我自己也理清一下思路,不然总是感觉些许混乱,或者说,明明用51单片

    2024年02月07日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包