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

news2025/4/14 20:15:22

状态机-重叠序列检测

`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机,

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

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

相关文章

仓储革新:AR技术引领物流进入智慧时代

根据《2022年中国物流行业研究&#xff1a;深度探析行业现状&#xff08;智能设备及智能软件&#xff09;》&#xff0c;报告中提及&#xff1a;“中国社会物流总额依然保持着较为良好的增长态势&#xff0c;年增速已恢复至常年平均水平。2021年社会物流总额细分中工业物流总额…

机器视觉实战应用:手势、人脸、动作以及手势鼠标构建(一)

CV实战应用手势、人脸、动作以及手势鼠标构建&#xff08;一&#xff09;总起 核心思想 手势识别是一种常见的计算机视觉应用&#xff0c;它可以通过摄像头或者预先录制的视频图像来追踪和识别人类手势。手势识别的应用非常广泛&#xff0c;例如在游戏、虚拟现实、人机交互等…

ActiveMQ漏洞合集

目录 介绍CVE-2015-5254&#xff1a;Apache ActiveMQ任意代码执行漏洞漏洞介绍 & 环境准备漏洞发现Nuclei❌Vulmap✅漏洞验证漏洞利用 CVE-2016-3088&#xff1a;Apache ActiveMQ Fileserver远程代码执行漏洞漏洞发现Nuclei✅Vulmap✅MSF✅第三方工具1&#xff08;漏洞探测…

谷歌Linux内核自动测试平台架构介绍-用自动测试测试难以测试的问题

1 摘要 内核和硬件等低级系统已被证明极难进行有效测试&#xff0c;因此&#xff0c;许多内核测试都是以手动为主方式进行的。现有的大多数测试框架都是为测试与底层平台隔离的高级软件而设计的&#xff0c;而底层平台被假定是稳定可靠的。测试底层平台本身需要一套全新的假设…

单字符检测模型charnet使用方法,极简

Git链接 安装按照上面的说明&#xff0c;说下使用。 把tools下面的test做了一点修改&#xff0c;可以读取一张图片&#xff0c;把里面的单个字符都检测和识别出来。 然后绘制到屏幕上。 import torch from charnet.modeling.model import CharNet import cv2, os import num…

第5课 使用openCV捕获摄像头并实现预览功能

这节课我们开始利用ffmpeg和opencv来实现一个rtmp推流端。推流端的最基本功能其实就两个:预览画面并将画面和声音合并后推送到rtmp服务器。 一、FFmpeg API 推流的一般过程 1.引入ffmpeg库&#xff1a;在代码中引入ffmpeg库&#xff0c;以便使用其提供的功能。 2.捕获摄像头…

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

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

【Spark精讲】一文搞懂Spark钨丝Tungsten

Tungsten 内存管理机制 催生 Tungsten 内存管理优化的原因主要来自两个方面 。 • Java对象占用内存空间大。 相对于 C/C等更加底层的程序语言&#xff0c; Java对象的存储密度相对偏低。 例如&#xff0c;即使最简单的 “abed” 字符串&#xff0c;用Java的UTF-16编码的情况…

ssm基于web 的个人时间管理系统+vue论文

基于web 的个人时间管理系统的设计与实现 摘要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。传统的个人时间信息管理模式&#xff0c;采用人工登记的方式保存相关数据&#xff0c;这种以人…

Ksher H5页面支付实例指导 (PHP实现)

前文 背景介绍 前两天&#xff0c;公司的项目&#xff0c;为了满足泰国客户的支付需求&#xff0c;要求使用 Ksher (开时支付) 对接任务突然就给了鄙人&#xff0c;一脸懵 … 通过了解客户的使用场景、以及参考官网指导 发现&#xff1a;Ksher支付 最令人满意的便是 —— 提供了…

GitHub 一周热点汇总 第3期 (2023/12/24-12/30)

GitHub一周热点汇总第三期 (2023/12/24-12/30)&#xff0c;梳理每周热门的GitHub项目&#xff0c;了解热点技术趋势&#xff0c;掌握前沿科技方向&#xff0c;发掘更多商机。元旦就要到了&#xff0c;提前祝大家新年快乐。 #1 StreamDiffusion 项目名称&#xff1a;StreamDiff…

Powermill各版本安装指南

下载链接 https://pan.baidu.com/s/1CsrYEUQNmDa820RxDV2G6Q?pwd0531 1.鼠标右击【PowerMill2024(64bit)】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;【解压到 PowerMill2024(64bit)】。 2.打开解压后的文件夹&#xff0c;双击打开【Setup】文…

Qt基础之四十五:Qt国际化(I18N)

国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),这种奇葩的缩写方式,让我想起了NBA球星“字母哥”。 下面看下Qt实现的动态语言切换效果。 一.效果 二.源码 QHSettingDialog.h #ifndef QHSETTINGDIALOG_H #define QHSETTINGDIALOG_H#…

获取Windows10系统原始安装日期

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 目标 获取Windows10系统最原始的安装日期&#xff1b;例如&#xff1a;刚买电脑时安装系统的时间。 步骤 第一步&#xff0c;请打开PowerShell&#xff0c;单击Windows P…

PAT 乙级 1033 旧键盘打字

旧键盘上坏了几个键&#xff0c;于是在敲一段文字的时候&#xff0c;对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键&#xff0c;打出的结果文字会是怎样&#xff1f; 输入格式&#xff1a; 输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其…

使用Android Studio等idea工具开发flutter应用,必备的debug调试技能,非常好用

我们程序员不论开发什么软件&#xff0c;都需要一把锋利的调试工具&#xff0c;这是必不可少的&#xff0c;不然出现问题了&#xff0c;你都不知道问题是啥&#xff0c;出现在哪&#xff0c;就更别说怎么解决了。所以我这里就介绍一下android studio开发flutter必备的调试技能&…

ssrf之dict协议和file协议

1.dict协议 dict是什么协议呢&#xff1f; 定义&#xff1a;词典网络协议&#xff0c;在RFC 2009中进行描述。它的目标是超越Webster protocol&#xff0c;并允许客户端在使 用过程中访问更多字典。Dict服务器和客户机使用TCP端口2628。 官方介绍&#xff1a;http://dict.o…

【STM32】STM32学习笔记-PWM驱动LED呼吸灯 舵机 直流电机(16)

00. 目录 文章目录 00. 目录01. 输出比较相关API1.1 TIM_OC1Init1.2 TIM_OCInitTypeDef结构体1.3 TIM_OCMode1.4 TIM_OutputState1.5 TIM_OutputNState1.6 TIM_OCPolarity1.7 TIM_OCNPolarity1.8 TIM_OCPolarity1.9 TIM_OCNPolarity 02. PWM实现呼吸灯接线图03. PWM实现呼吸灯示…

livox avia平台搭建

硬件平台搭建 硬件平台的搭建除了livox雷达外还需要以下物料 焊接12V稳压模块接口 livox雷达需要12V的稳定电压供电,因此需要在电池与雷达之间加入8-35V转12V的稳压模块 组装 将各组建组装起来即可。 220V交流电供电 电池供电

数据结构 模拟实现LinkedList单向不循环链表

目录 一、链表的简单介绍 二、链表的接口 三、链表的方法实现 &#xff08;1&#xff09;display方法 &#xff08;2&#xff09;size得到单链表的长度方法 &#xff08;3&#xff09;addFirst头插方法 &#xff08;4&#xff09;addLast尾插方法 &#xff08;5&#xf…