有限状态机设计(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设计编程(四) 有限状态机设计

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

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

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

    12-同步状态机的结构以及Mealy和Moore状态机的区别,Verilog实现有限状态机的4种方式,以及总结有限状态机设计的一般步骤

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

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

    基于FPGA的DDS原理信号发生器设计 quartusII 9.1平台 Verilog HDL语言编程 可产生正弦波

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

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

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

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

    【Verilog HDL】FPGA-Verilog文件的基本结构

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

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

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

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

    FPGA用verilog HDL实现串口通讯协议

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

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

    【Verilog HDL】FPGA-testbench基础知识

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

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

    【FPGA】组合逻辑电路三种建模方式(Verilog HDL 门级建模、Verilog HDL 数据流建模、组合电路行为级建模)

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

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

    verilog键盘输入示例代码及分析(摩尔型有限状态机)

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

    2024年02月07日
    浏览(7)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包