12.30序列检测(重叠、不重叠、连续、不连续、含无关项)——移位寄存器,状态机;状态机(二段式,三段式)

状态机-重叠序列检测

`timescale 1ns/1ns

module sequence_test2(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
    parameter S0=0, S1=1, S2=2, S3=3, S4=4;
    reg [2:0] state, nstate;
    
    always@(posedge clk or negedge rst) begin
        if(~rst)
            state <= S0;
        else
            state <= nstate;
    end
    
    always@(*) begin
        if(~rst)
            nstate <= S0;
        else
            case(state)
                S0     : nstate <= data? S1: S0;
                S1     : nstate <= data? S1: S2;
                S2     : nstate <= data? S3: S0;
                S3     : nstate <= data? S4: S2;
                S4     : nstate <= data? S1: S2;
                default: nstate <= S0;
            endcase
    end
    
    always@(posedge clk or negedge rst) begin
        if(~rst)
            flag <= 0;
        else
            flag <= state==S4;
    end

//*************code***********//
endmodule

状态机-非重叠的序列检测

只检测一次的序列,这才是真正的不用考虑其它的,匹配就行,不用考虑不匹配的

`timescale 1ns/1ns

module sequence_test1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
parameter idle=0,s1=1,s2=2,s3=3,s4=4,s5=5;
reg[2:0]cs;
reg[2:0]ns;
always@(posedge clk,negedge rst)begin
	if(!rst)begin
		cs<=idle;
	end
	else begin
		cs<=ns;
	end
end
always@(*)begin
	case(cs)
	idle:ns=(data==1)?s1:idle;
	s1:ns=(data==0)?s2:idle;
	s2:ns=(data==1)?s3:idle;
	s3:ns=(data==1)?s4:idle;
	s4:ns=(data==1)?s5:idle;
	default:ns=idle;
	endcase
end
always@(posedge clk,negedge rst)begin
	if(!rst)begin
		flag<=0;
	end
	else begin
		flag<=ns==s5;
	end
end
endmodule

不重叠序列检测

状态机

这种还是用状态机比较方便,对于序列检测,就是根据特点选方法,最简便的是MOORE型,到底慢不慢一拍,直接在输出判断时更改CS,NS,要慢就CS,不慢就NS

nS的MOORE和MEALY型是一样的同步

不重叠的话,不匹配时就直接回到初始状态,都不用Kmp匹配了

移位寄存器

在移位寄存器的基础上,加了一个CNT限制’

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	output reg match,
	output reg not_match
	);
    reg[2:0]cnt;
    reg[5:0]ram;
    always@(posedge clk,negedge rst_n)begin
        if(!rst_n)
            cnt<=0;
        else
            cnt<=cnt==5?0:cnt+1;
    end
    always@(posedge clk,negedge rst_n)begin
        if(!rst_n)
            ram<=0;
        else
            ram<={ram[4:0],data};
    end
    always@(posedge clk,negedge rst_n)begin
        if(!rst_n)begin
            match<=0;
            not_match<=0;
        end
        else begin
            match<=(cnt==5)&&({ram[4:0],data}==6'b011100);
            not_match<=(cnt==5)&&({ram[4:0],data}!=6'b011100);
        end
    end
endmodule

含有无关项的序列检测

移位寄存器

用两个信号判断左右两侧是不是满足要求的,都满足了就输出1

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output match
	);
reg[8:0]temp;
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		temp<=9'b0;
	end
	else begin
		temp<={temp[7:0],a};
	end
end

reg ma;
reg mb;
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		ma<='b0;
	end
	else begin
		if(temp[8:6]==3'b011)
			ma<=1'b1;
		else
			ma<=1'b0;
	end
end
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		mb<='b0;
	end
	else begin
		if(temp[2:0]==3'b110)
			mb<=1'b1;
		else
			mb<=1'b0;
	end
end
assign match=ma&mb;
endmodule

输入序列连续的序列检测

移位寄存器

这个移位寄存器,是直接判断寄存器存的,即寄存器当前状态,所以是MOORE状态机

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
reg[7:0]atemp;
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		atemp<=8'b0;
	end
	else
		atemp<={atemp[6:0],a};
end
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		match=1'b0;
	end
	else begin
		if(atemp==8'b0111_0001)
		match=1'b1;
		else
		match='b0;
	end
end
  
endmodule

状态机 

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
parameter idle=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8;
reg[3:0]cs;
reg[3:0]ns;
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)
		cs<=idle;
	else 
		cs<=ns;
end
always@(*)begin
	case(cs)
	idle:begin
		ns=(a==0)?s1:idle;
	end
	s1:begin
		ns=(a==1)?s2:s1;
	end
	s2:begin
		ns=(a==1)?s3:s1;
	end
	s3:begin
		ns=(a==1)?s4:s1;
	end
	s4:begin
		ns=(a==0)?s5:idle;
	end
	s5:begin
		ns=(a==0)?s6:s2;
	end
	s6:begin
		ns=(a==0)?s7:s2;
	end
	s7:begin
		ns=(a==1)?s8:s1;
	end
	s8:begin
		ns=(a==1)?s3:s1;
	end
	default:ns=idle;
	endcase
end
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)
		match<=0;
	else
		match<=(cs==s8)?1:0;
end
endmodule

MOORE机中判断的是现态,所以慢一拍

MOORE机中判断次态时,与MEALY机一样,是同步输出的 

输入序列不连续的序列检测

移位寄存器(同一周期内输出,MEALY型)

在输出判断时,由现态与输入信号共同决定

就是在有效时进行移位,然后还要注意,由于是要在同一拍里输出信号,由于移位的更新是在下一位里才进行,所以这个周期里更新的ram,会在下个周期里进行判断,所以就会导致延后,所以输出的判断要结合现态,即MEALY型

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	input data_valid,
	output reg match
	);
reg[3:0]ram;
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		ram=4'b0;
	end
	else if(data_valid)begin
		ram<={ram[2:0],data};
	end
	else begin
		ram<=ram;
	end
end
always@(posedge clk,negedge rst_n)begin
	if(!rst_n)begin
		match<=0;
	end
	else begin
		match<=(ram[2:0]==3'b011)&&data&&data_valid;
	end
end
endmodule

 状态机(MOORE型)

MOORE型的话,只与现态有关,所以输出判断时,用的是ns==,即次态等于什么

而如果是MEALY,就是现态加上输入

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	input data_valid,
	output reg match
	);
	parameter idle=0,s0=1,s1=2,s2=3,s3=4;
	reg[2:0]cs;
	reg[2:0]ns;
	always@(posedge clk,negedge rst_n)begin
		if(!rst_n)begin
			cs<=idle;
		end
		else begin
			cs<=ns;
		end
	end
	always@(*)begin
		case(cs)
		idle:begin
			if(data_valid)
				ns=(data==1)?idle:s0;
			else
				ns=idle;
		end
		s0:begin
			if(data_valid)
				ns=(data==1)?s1:s0;
			else 
				ns=s0;
		end
		s1:begin
			if(data_valid)
				ns=(data==1)?s2:s0;
			else
				ns=s1;
		end
		s2:begin
			if(data_valid)
				ns=(data==0)?s3:idle;
			else
				ns=s2;
		end
		s3:begin
			if(data_valid)
				ns=(data==0)?s0:idle;
		end
		endcase
	end
	always@(posedge clk,negedge rst_n)begin
		if(!rst_n)begin
			match<=0;
		end
		else begin
			match<=(ns==s3)?1:0;
		end
	end
endmodule

状态机

需要注意,判断次态的MOORE机不满一拍,真正判断那个现态的才是满一拍的

moore机要比Mealy机多一个状态,这个状态表示初始状态

Moore机的输出由当前状态确定,mealy机的输出由当前状态与输入信号共同决定

最后的输出控制由现态单独控制,因此为摩尔机 

蓝色代表输出,摩尔机最后添加了状态S4,从状态转移上看输出节拍会晚一拍,但由于是组合逻辑输出,因此实际上并没有晚一拍

(这个就是说判断次态的MOORE机和MEALY机是一样的输出,即在同一周期内输出,而只有那种真是判断现态的MOORE机才会确实慢一个周期)

摩尔机和米勒机的区别:主要区别在于状态机的输出与当前的状态是否有关,下面用两段式来描述两者的区别。

需要注意的是,如果使用三段式描述法,两者的区别主要聚焦于第三段的判断是基于现态还是次态。

摩尔状态机要比米勒状态机少一个状态,摩尔状态机慢一个周期;米勒状态机使用当前输入和当前状态共同判断,摩尔状态机不需要当前输入。

如果要为moore机的话,那么在输出中,只能判断为次态,即次态是什么;

如果是要mealy机的话,在输出中,要判断为现态与输入信号相结合

这种为Mealy机 ,因为在输出时,输出信号由现态与输入一起控制

二段式 

所谓二段式,实际上就是专门针对MOORE机的写法,因为MOORE机的输出仅取决于现态,然后就是判断现态即可,就判断次态是什么,会晚一个周期输出,而二段式,就是省略了最后一段输出,把它揉进了状态转换里

因为是MOORE机,所以在输出里判断的是次态,不如就直接在状态转换里,确定次态时就确定好了输出

三段式 

次态到现态,用posedge,

在状态转换时,用always@(*)

输出的时候,也用posedge

在第一个和第二个进程中,由于都是同步时序,所以都用<=,在第二个进程里用=

`timescale 1ns/1ns



module fsm1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);

    parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 ;
    reg [2:0]	current_state;
    reg [2:0]	next_state;
	
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            current_state <= S0;
        end
        else begin
            current_state <= next_state;
        end
    end   
    
    always@(*)begin
        case(current_state)
            S0:begin
                next_state = data ? S1 : S0;
            end
            S1:begin
                next_state = data ? S2 : S1;
            end
            S2:begin
                next_state = data ? S3 : S2;
            end
            S3:begin
                next_state = data ? S0 : S3;
            end
            default:begin  next_state = S0; end
        endcase
    end
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            flag <= 1'b0;
        end
        else begin
            if(current_state == S3)begin
				if (data) flag <= 1'b1;
				else flag <= 1'b0;
            end
            else begin
                flag <= 1'b0;
            end
        end
    end
 
endmodule

这是一个mealy机,

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习基础知识神经网络

神经网络 1. 感知机 感知机&#xff08;Perceptron&#xff09;是 Frank Rosenblatt 在1957年提出的概念&#xff0c;其结构与MP模型类似&#xff0c;一般被视为最简单的人工神经网络&#xff0c;也作为二元线性分类器被广泛使用。通常情况下指单层的人工神经网络&#xff0c…

基于Java SSM框架实现实现中国古诗词学习平台项目【项目源码】计算机毕业设计

基于java的SSM框架实现中国古诗词学习平台系统演示 JSP技术介绍 JSP技术本身是一种脚本语言&#xff0c;但它的功能是十分强大的&#xff0c;因为它可以使用所有的JAVA类。当它与JavaBeans 类进行结合时&#xff0c;它可以使显示逻辑和内容分开&#xff0c;这就极大的方便了用…

Java:IO流——字节流和字符流

目录 IO流的基本概念 IO流体系结构 FileOutputStream字节输出流 构造方法 成员方法 细节 关流 FileInputStream字节输入流 构造方法及成员方法 read不带参数代码示例 read带参数代码示例​编辑 将字节数组或字符数组转成字符串 FileReader 字符输入流 构造方法和…

解决ELement-UI懒加载三级联动数据不回显(天坑)

最老是遇到这类问题头有点大,最后也是解决了,为铁铁们总结了一下几点 一.查看数据类型是否一致 未选择下 选择下 二.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式 三.绑定v-if 确保每次重新加载 四.绑定key 五.完整代码

对比学习简介

1. 引言 在本教程中&#xff0c;我们将介绍对比学习领域中的相关概念。首先&#xff0c;我们将讨论这种技术背后相关的理论知识&#xff1b;接着&#xff0c;我们将介绍最常见的对比学习的损失函数和常见的训练策略。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 举…

众安保险实习Java一面

说一下事务的ACID属性 原子性&#xff08;Atomicity&#xff09;&#xff1a;原子性是指事务是一个不可分割的工作单位&#xff0c;事务中的操作要么全部成功&#xff0c;要么全部失败。 一致性&#xff08;Consistency&#xff09;&#xff1a;事务按照预期生效&#xff0c;…

常用环境部署(十二)——Redis搭建主从模式(一主一从)

一、主从服务器Redis安装 1、注意事项 主从服务器Redis尽量安装同一版本&#xff0c;避免兼容性造成的一些错误产生 2、Centos安装Redis 链接&#xff1a;​​​​​​常用环境部署(十)——MySQL主从同步数据搭建(一主一从)-CSDN博客 二、 主Redis配置 1、修改主Redis配置…

让你的 Python 代码更快的 9 个技巧

在最近参加的一些技术会议上,我常常听到参会员在会中讨论技术选型时提到“Python太慢了”。然而,这种观点往往没有考虑到Python的众多优点。实际上,如果能够遵循Pythonic的编程风格,Python的运行速度可以非常快。这其中的关键在于掌握一些技术细节上的巧妙技巧。那些经验丰…

Python文本用户界面进化:探索Textual框架,编程新境界

更多Python学习内容&#xff1a;ipengtao.com 文本用户界面&#xff08;TUI&#xff09;在很多应用中扮演着重要的角色&#xff0c;尤其是在需要在终端中运行的应用程序中。Python作为一门强大的编程语言&#xff0c;提供了多种工具和库来构建文本用户界面。在本文中&#xff0…

LabVIEW开发智能火灾自动报警系统

LabVIEW开发智能火灾自动报警系统 系统基于LabVIEW虚拟仪器开发&#xff0c;由火灾报警控制器、感温感烟探测器、手动报警器、声光报警器、ZigBee无线通讯节点以及上位机电脑等组成&#xff0c;展示了LabVIEW在智能化火灾预警与控制方面的应用。该系统通过结合二总线协议和Zig…

windows PE文件都包含哪些信息【详细汇总介绍】

目录 1. DOS头 DOS头的作用 DOS头的结构 C代码判断PE文件 2. PE文件签名 PE文件签名的位置和作用 PE文件签名的结构 COFF&#xff08;Common Object File Format&#xff09;头 COFF头的结构 COFF头的作用 代码 3. 标准PE头&可选PE头 标准PE头 可选PE头 4. …

python使用openpyxl操作excel

文章目录 前提读取已有excel创建一个excel工作簿对象创建excel工作簿中的工作表获取工作表第一种&#xff1a;.active 方法第二种&#xff1a;通过工作表名获取指定工作表​​​​​​第三种&#xff1a;.get_sheet_name() 修改工作表的名称数据操作写入数据按单元格写入通过指…

如何手写一个消息队列和延迟消息队列?

Java学习面试指南&#xff1a;https://javaxiaobear.cn 第一次听到“消息队列”这个词时&#xff0c;不知你是不是和我反应一样&#xff0c;感觉很高阶很厉害的样子&#xff0c;其实当我们了解了消息队列之后&#xff0c;发现它与普通的技术类似&#xff0c;当我们熟悉之后&…

多线程编程设计模式(单例,阻塞队列,定时器,线程池)

&#x1f495;"只有首先看到事情的可能性&#xff0c;才会有发生的机会。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;多线程编程设计模式(单例,阻塞队列,定时器,线程池) 本文主要讲解多线程编程中常用到的设计模式,包括单例模式,阻塞队列,定时…

“C语言与人生:手把手教你玩转C语言数组,从此编程无难题“

各位少年&#xff0c;我是博主那一脸阳光&#xff0c;由我来给大家介绍C语言的数组的详解。 在C语言中&#xff0c;数组是一种极其重要的数据结构&#xff0c;它允许我们存储和管理相同类型的一系列相关数据。通过理解并熟练掌握数组的使用&#xff0c;开发者能够高效地处理大量…

激发AI时代操作系统创新活力,统信UOS持续拓宽生态护城河

操作系统作为信息技术产业之“魂”&#xff0c;在2023年迈进“真替真用阶段”&#xff0c;迎来强势崛起。 国产操作系统产业依托数字化转型浪潮&#xff0c;市场份额逐年递增&#xff0c;并向智能计算等方向加速进化。经过数年的深耕&#xff0c;统信软件交出漂亮成绩单。最新…

SpringCloud(H版alibaba)框架开发教程,使用eureka,zookeeper,consul,nacos做注册中心——附源码(1)

源码地址&#xff1a;https://gitee.com/jackXUYY/springboot-example 创建订单服务&#xff0c;支付服务&#xff0c;公共api服务&#xff08;共用的实体&#xff09;&#xff0c;eureka服务 1.cloud-consumer-order80 2.cloud-provider-payment8001 3.cloud-api-commons 4.…

kotlin快速入门1

在Google I/O 2017中&#xff0c;Google 宣布 Kotlin 成为 Android 官方开发语言。目前主流AndroidApp开发已经全部切换成此语言&#xff0c;因此对于Android开发而言&#xff0c;掌握Kotlin已经变成必要事情。 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言&#xff…

Armpro脱壳软件搭建教程附源代码

PHP8.0版本&#xff0c;数据库8.0版本 1.配置注册机文件&#xff0c;打开将arm.zip/res目录下&#xff0c;mt管理器搜索将其全部修改为你自己的域名或者是服务器IP 2.然后建立数据库 数据库账号arm 数据库用户名arm 数据库密码EsZfXY4tD3h2NNA4 3.导入数据库 4.配置Redi…

算法基础之滑雪

滑雪 核心思想&#xff1a;记忆化搜索 状态表示&#xff1a; f[i][j] 表示所有从(i,j) 开始滑的路径的最大值 状态计算&#xff1a; 分成四个方向 f[i][j] max(f[i][j] , f[i][j1] 1) 且h[a][b] (下一个点) 必须严格小于 h[i][j] 才能滑过去 #include<iostream>#…