首页 » 互联网 » FPGA进修-序列检测器_序列_暗记

FPGA进修-序列检测器_序列_暗记

乖囧猫 2024-12-10 18:51:56 0

扫一扫用手机浏览

文章目录 [+]

在数字电路中,序列检测器(Sequence Detector)是指一种分外类型的电路,用于探求输入旗子暗记中一定模式的子序列。
该模式可以是任意模式,包括重复模式、连续模式、间隔模式等等。
常日的序列检测方法有2种:有限状态机法(FSM);移位寄存器法。

为什么须要设计序列检测电路呢?

FPGA进修-序列检测器_序列_暗记 互联网

在数字集成电路中,序列检测电路可以用于检测输入旗子暗记序列中是否存在特定的模式和序列,以及判断实际输出和理论输出是否存在差异。
序列检测器是确保数字系统的精确运行不可或缺的一部分!

那么数字IC中哪些部分须要设计呢?

数字集成电路(Digital Integrated Circuit,简称DIC)中须要设计序列检测电路的部分紧张包括以下几个方面:

数据输入端:序列检测电路可以用于检测输入数据是否符合特定的格式哀求,或者是否存在缺点或滋扰。
在数字集成电路中,输入数据常日是通过输入端口输入的,因此须要在输入端口处设计序列检测电路。

掌握旗子暗记:数字集成电路中的掌握旗子暗记常日是用于掌握数字系统的操作序列,以确保系统按照预期的顺序实行操作。
在这种情形下,序列检测电路可以用于检测掌握旗子暗记是否按照预期的序列进行。

数据输出端:序列检测电路还可以用于检测输出数据是否符合特定的格式哀求,或者是否存在缺点或滋扰。
在数字集成电路中,输出数据常日是通过输出端口输出的,因此须要在输出端口处设计序列检测电路。

内部旗子暗记:数字集成电路中的内部旗子暗记常日是在芯片内部通报的旗子暗记,例如时钟旗子暗记、地址旗子暗记、数据旗子暗记等。
在这种情形下,序列检测电路可以用于检测内部旗子暗记是否按照预期的序列进行。

在IC设计的过程中,不同的部分的序列检测器检测的序列和发挥的详细浸染不尽心相同。
因此在数字集成电路中,须要根据详细的运用处景,针对不同的部分设计相应的序列检测电路。

二、状态机法和寄存器法

对付序列检测器的设计,常规的设计方法有两种:状态机法和移位寄存器法。

状态机法最主要的是明白状态机状态的转移过程:在数据输入之后判断是否匹配,若匹配则进入下一状态,不匹配则根据输入的数据详细判断进入的下一状态(也有可能保持在原来的状态)。
状态机设计过程一定要看重状态的数量和状态转移以及状态转移条件,避免状态的缺失落以及状态转移的不合理循环。

移位寄存器法法基本事理是数据的移位和移位数据的比拟:首先将对应的初始数据缓存在寄存器中作为一个数组,数据输入后置于于数组的末端,数组其它元素左移,把最早输入的数据移出,每输入一个数据后刷新一次。
然后将数组和目标序列比拟,如果数组和目标序列相等,则解释涌现目标序列。

2.1状态机法2.11 利用状态机检测“1001”

题目:设计一个序列检测器,用来检测序列1001,用_状态机完成电路,可重复检测_序列1001(即本文第三部分的重叠检测)。

第一步,剖析状态机状态转移,剖析如下:

IDLE: 初始状态,代表目前没有吸收到知足哀求的数据。

seq_in = 1时,即是1001中的第一个数,进入S1状态;

seq_in = 0时,保持状态。

S1:代表目前已经有了1个匹配的数据。

seq_in = 0时,当前序列为10,即是1001中的前两个数,进入S2状态;

seq_in = 1时,当前序列为11,不是1001的前两个数,但1是1001的第一个数,以是保持S1状态。

S2:代表目前已经有了2个匹配的数据。

seq_in = 0时,当前序列为100,即是1001中的前三个数,进入S3状态;

seq_in = 1时,当前序列为101,不是1001的前三个数,但1是1001的第一个数,以是进入S1状态。

S3:代表目前已经有了3个匹配的数据。

seq_in = 1时,当前序列为1001,与哀求序列匹配,进入S4状态;

seq_in = 0时,当前序列为1000,与哀求序列不配,0与初始状态匹配,以是进入IDLE状态。

S4:终极状态,代表目前已经得到了匹配的序列,输出旗子暗记翻转。

seq_in = 1时,当前序列为10011,1与哀求序列的第一个数匹配,以是进入S1状态;

seq_in = 0时,当前序列为10010,10与哀求的前两个数匹配,以是进入S2状态。

第二步:根据流程转换剖析画出状态机的状态转移图,如下图所示:

第三步:根据状态机转移图用经典三段式(或者二段式)写出verilog代码

2.12 verilog代码//利用状态机设计检测“1001”的序列检测器

//可重叠检测序列“1001”

module sequence_detect01(

input clk,

input rst_n,

input seq_in,

output mismatch //考验序列是否匹配,匹配输出0,不匹配输出0

);

//采取独热码编译五个状态,初始IDLE状态为待机状态

//独热码比较二进制码和格雷码,方便电路设计判断、状态转移,且逻辑更大略

parameter IDLE = 5'b00001;

parameter S1 = 5'b00010;

parameter S2 = 5'b00100;

parameter S3 = 5'b01000;

parameter S4 = 5'b10000;

//定义两个寄存器表示状态机的目前状态和下一状态

reg [4:0] curr_state;

reg [4:0] next_state;

//第一段利用时序逻辑描述状态转移

always@(posedge clk or negedge rst_n) begin

if(!rst_n) begin

curr_state <= IDLE;

end

else begin

curr_state <= next_state;

end

end

//第二段利用组合逻辑判断状态转移条件

always@() begin

if(!rst_n) begin

next_state <= IDLE;

end

else begin

case(curr_state)

IDLE :next_state = seq_in?S1:IDLE;

S1 :next_state = seq_in?S1:S2;

S2 :next_state = seq_in?S1:S3;

S3 :next_state = seq_in?S4:IDLE;

S4 :next_state = seq_in?S1:S2;

default:next_state = IDLE; //养成良好代码风格,不能遗漏,防天生latch,也可以通过赋初值避免

endcase

end

end

//第三段描述状态输出(可以利用组合逻辑,也可以用时序逻辑)

//此处采取组合逻辑,同时也供应时序逻辑代码示例

assign mismatch = (curr_state ==S4) ? 1'b0 : 1'b1; //组合逻辑描述输出

/

//时序逻辑描述输出

always@(posedge clk or negedge rst_n) begin

if(!rst_n) begin

mismatch <= 1'b1;

end

else if(next_state == S4) begin

mismatch <= 1'b0;

end

else begin

mismatch <= 1'b1;

end

end

/

endmodule

2.13 testbench`timescale 1ns/1ps //仿真韶光单位1ns 仿真韶光精度1ps

module sequence_detect01_tb();

//旗子暗记申明

reg clk;

reg rst_n;

reg seq_in;

wire mismatch;

//天生复位旗子暗记

//为时钟旗子暗记和复位旗子暗记赋初值

initial begin

clk = 0;

rst_n = 1;

seq_in = 1;

#5 rst_n = 0;

#10 rst_n = 1;

end

always #6 seq_in = $random; //天生随机数作为旗子暗记输入

always #5 clk = ~clk; //天生时钟旗子暗记

//模块实例化(将申明的旗子暗记连接起来即可)

sequence_detect01 u_sequence_detect01

(.clk (clk),

.rst_n (rst_n),

.seq_in (seq_in),

.mismatch (mismatch)

);

endmodule

2.14仿真结果

)

Testbench中采取随机数来验证序列检测器的准确性,当时间来到705ns,随机数连续输出1001,mismatch在吸收四位数字进行旗子暗记翻转。

2.2移位寄存器法2.21 利用移位寄存器法检测1001

题目:设计一个序列检测器,用来检测序列 1001,用_移位寄存器_完成电路设计。

移位寄存器方法比较大略。
设置一个和序列等长的寄存器,在数据输入后将输入移入寄存器的最低位,并判断寄存器中的值是否与序列相同。
由于移位寄存器的事情事理,设计出来的序列检测器可以重叠检测序列。

2.22 verilog代码//利用移位寄存器设计检测“1001”的序列检测器

//可重叠检测序列“1001”

module sequence_detect02(

input clk,

input rst_n,

input seq_in,

output reg mismatch //时序逻辑中须要定义为reg型

);

reg [3:0] seq_in_r; //定义一个寄存器缓存数据

//利用时序逻辑完成复位和移位寄存器移位过程

always@(posedge clk or negedge rst_n) begin

if (!rst_n) begin

seq_in_r <= 4'b0; //中间寄存器复位

end

else begin

seq_in_r <= {seq_in_r[2:0],seq_in}; //输入数据置于数组右端,移位寄存器左移位

end

end

//利用时序逻辑完成复位与输出

always@(posedge clk or negedge rst_n) begin

if (!rst_n) begin

mismatch <= 1'b1;

end

else if (seq_in_r == 4'b1001) begin //若检测到1001则将mismatch置1,表明检测到序列1001

mismatch <= 1'b0;

end

else begin

mismatch <= 1'b1; //养成良好代码风格,不能遗漏,防天生latch,可通过赋初值避免

end

end

endmodule

2.23 testbench`timescale 1ns/1ps //仿真韶光单位1ns 仿真韶光精度1ps

module sequence_detect02_tb;

//旗子暗记申明

reg clk;

reg rst_n;

reg seq_in;

wire mismatch;

//复位旗子暗记天生

//时钟旗子暗记与复位旗子暗记赋初值

initial begin

clk = 0;

rst_n = 1;

seq_in = 1;

#5 rst_n = 0;

#10 rst_n = 1;

end

always #6 seq_in = $random; //天生随机数作为旗子暗记输入

always #5 clk = ~clk; //天生时钟旗子暗记

//模块实例化(将申明的旗子暗记连接起来即可)

sequence_detect01 u_sequence_detect01

(.clk (clk),

.rst_n (rst_n),

.seq_in (seq_in),

.mismatch (mismatch)

);

endmodule

2.24仿真结果

Testbench中采取随机数来验证序列检测器的准确性,当时间来到705ns,随机数连续输出1001,mismatch在吸收四位数字且在时钟上升沿进行旗子暗记翻转。

三、重叠检测与非重叠检测(检测序列1001)

数字IC序列检测中的重叠检测和非重叠检测是两种不同的检测办法。

重叠检测是指在一个序列中,子序列之间会有部分重叠的情形,而重叠区域也须要进行检测,并被剖断为单独的子序列。

非重叠检测则是指在一个序列中,每个子序列之间没有重叠部分,因此只须要检测每个子序列本身是否知足特定的条件即可。

3.1重叠检测3.11 重叠检测方法

题目:设计一个序列检测器,用来检测序列 1001,用_状态机完成电路,可重复检测_序列1001

第一步,剖析状态机状态转移,剖析如下:

IDLE: 初始状态,代表目前没有吸收到知足哀求的数据。

seq_in = 1时,即是1001中的第一个数,进入S1状态;

seq_in = 0时,保持状态。

S1:代表目前已经有了1个匹配的数据。

seq_in = 0时,当前序列为10,即是1001中的前两个数,进入S2状态;

seq_in = 1时,当前序列为11,不是1001的前两个数,但1是1001的第一个数,以是保持S1状态。

S2:代表目前已经有了2个匹配的数据。

seq_in = 0时,当前序列为100,即是1001中的前三个数,进入S3状态;

seq_in = 1时,当前序列为101,不是1001的前三个数,但1是1001的第一个数,以是进入S1状态。

S3:代表目前已经有了3个匹配的数据。

seq_in = 1时,当前序列为1001,与哀求序列匹配,进入S4状态;

seq_in = 0时,当前序列为1000,与哀求序列不配,0与初始状态匹配,以是进入IDLE状态。

S4:终极状态,代表目前已经得到了匹配的序列,输出旗子暗记翻转。

seq_in = 1时,当前序列为10011,1与哀求序列的第一个数匹配,以是进入S1状态;

seq_in = 0时,当前序列为10010,10与哀求的前两个数匹配,以是进入S2状态。

第二步:根据流程转换剖析画出状态机的状态转移图,如下图所示:

第三步:根据状态机转移图用经典三段式(或者二段式)写出verilog代码

3.12verilog代码//利用状态机设计检测“1001”的序列检测器

//可重叠检测序列“1001”

module sequence_detect03(

input clk ,

input rst_n,

input seq_in,

output reg mismatch //考验序列是否匹配,匹配输出0,不匹配输出0

);

//采取独热码编译五个状态,初始IDLE状态为待机状态

//独热码比较二进制码和格雷码,方便电路设计判断、状态转移,且逻辑更大略

parameter IDLE = 5'b00001;

parameter S1 = 5'b00010;

parameter S2 = 5'b00100;

parameter S3 = 5'b01000;

parameter S4 = 5'b10000;

//定义两个寄存器表示状态机的目前状态和下一状态

reg [4:0] curr_state;

reg [4:0] next_state;

//第一段利用时序逻辑描述状态转移

always@(posedge clk or negedge rst_n) begin

if(!rst_n) begin

curr_state <= IDLE;

end

else begin

curr_state <= next_state;

end

end

//第二段利用组合逻辑判断状态转移条件

always@() begin

if(!rst_n) begin

next_state <= IDLE;

end

else begin

case(curr_state)

IDLE :next_state = seq_in?S1:IDLE;

S1 :next_state = seq_in?S1:S2;

S2 :next_state = seq_in?S1:S3;

S3 :next_state = seq_in?S4:IDLE;

S4 :next_state = seq_in?S1:S2;

default:next_state = IDLE; //养成良好代码风格,不能遗漏,防天生latch,也可以通过赋初值避免

endcase

end

end

//第三段描述状态输出(可以利用组合逻辑,也可以用时序逻辑)

//此处采取时序逻辑,同时也供应组合逻辑代码示例

always@(posedge clk or negedge rst_n) begin //时序逻辑描述输出

if(!rst_n) begin

mismatch <= 1'b1;

end

else if(next_state == S4) begin

mismatch <= 1'b0;

end

else begin

mismatch <= 1'b1;

end

end

//assign mismatch = (curr_state ==S4) ? 1'b0 : 1'b1; //组合逻辑描述输出

endmodule

3.13Testbench`timescale 1ns/1ps //仿真韶光单位1ns 仿真韶光精度1ps

module sequence_detect03_tb();

//旗子暗记申明

reg clk;

reg rst_n;

reg seq_in;

wire mismatch;

//复位旗子暗记天生

//输入旗子暗记天生,输入旗子暗记为“1001001001001”

//时钟旗子暗记与复位旗子暗记赋初值

initial begin

clk = 0;

rst_n = 1;

#5 rst_n = 0;

#10 rst_n = 1;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

end

//时钟旗子暗记天生

always #5 clk = ~clk;

//模块实例化(将申明的旗子暗记连接起来即可)

sequence_detect03 u_sequence_detect03(

.clk (clk),

.rst_n (rst_n),

.seq_in (seq_in),

.mismatch (mismatch)

);

endmodule

3.14仿真结果

输入序列1001001001001,根据可重复检测理论上可检测四次旗子暗记翻转,从仿真结果可以看到mismatch发生四次翻转,且第二次翻转的1001中的第一个1来自第一组1001中末了一个1,即发生重叠亦可检测。

3.2非重叠检测3.21 非重叠检测方法

题目:设计一个序列检测器,用来检测序列 1001,用状态机完成电路,可重复检测序列1001

第一步,剖析状态机状态转移,剖析如下:

IDLE: 初始状态,代表目前没有吸收到知足哀求的数据。

seq_in = 1时,即是1001中的第一个数,进入S1状态;

seq_in = 0时,保持状态。

S1:代表目前已经有了1个匹配的数据。

seq_in = 0时,当前序列为10,即是1001中的前两个数,进入S2状态;

seq_in = 1时,当前序列为11,不是1001的前两个数,但1是1001的第一个数,以是保持S1状态。

S2:代表目前已经有了2个匹配的数据。

seq_in = 0时,当前序列为100,即是1001中的前三个数,进入S3状态;

seq_in = 1时,当前序列为101,不是1001的前三个数,但1是1001的第一个数,以是进入S1状态。

S3:代表目前已经有了3个匹配的数据。

seq_in = 1时,当前序列为1001,与哀求序列匹配,进入S4状态;

seq_in = 0时,当前序列为1000,与哀求序列不配,0与初始状态匹配,以是进入IDLE状态。

S4:终极状态,代表目前已经得到了匹配的序列,输出旗子暗记翻转。

seq_in = 1时,当前序列为10011,1与哀求序列的第一个数匹配,以是进入S1状态;

seq_in = 0时,当前序列为10010,10与哀求的前两个数匹配,但是哀求非重叠检测,以是进入IDLE状态。

第二步:根据流程转换剖析画出状态机的状态转移图,如下图所示

第三步:根据状态机转移图用经典三段式(或者二段式)写出verilog代码

3.22verilog代码//利用状态机设计检测“1001”的序列检测器

//非重叠检测序列“1001”

module sequence_detect04(

input clk ,

input rst_n,

input seq_in,

output reg mismatch //考验序列是否匹配,匹配输出0,不匹配输出0

);

//采取独热码编译五个状态,初始IDLE状态为待机状态

//独热码比较二进制码和格雷码,方便电路设计判断、状态转移,且逻辑更大略

parameter IDLE = 5'b00001;

parameter S1 = 5'b00010;

parameter S2 = 5'b00100;

parameter S3 = 5'b01000;

parameter S4 = 5'b10000;

//定义两个寄存器表示状态机的目前状态和下一状态

reg [4:0] curr_state;

reg [4:0] next_state;

//第一段利用时序逻辑描述状态转移

always@(posedge clk or negedge rst_n) begin

if(!rst_n) begin

curr_state <= IDLE;

end

else begin

curr_state <= next_state;

end

end

//第二段利用组合逻辑判断状态转移条件

always@() begin

if(!rst_n) begin

next_state <= IDLE;

end

else begin

case(curr_state)

IDLE :next_state = seq_in?S1:IDLE;

S1 :next_state = seq_in?S1:S2;

S2 :next_state = seq_in?S1:S3;

S3 :next_state = seq_in?S4:IDLE;

S4 :next_state = seq_in?S1:IDLE;

default:next_state = IDLE; //养成良好代码风格,不能遗漏,防天生latch,也可以通过赋初值避免

endcase

end

end

//第三段描述状态输出(可以利用组合逻辑,也可以用时序逻辑)

//此处采取时序逻辑,同时也供应组合逻辑代码示例

always@(posedge clk or negedge rst_n) begin //时序逻辑描述输出

if(!rst_n) begin

mismatch <= 1'b1;

end

else if(next_state == S4) begin

mismatch <= 1'b0;

end

else begin

mismatch <= 1'b1;

end

end

//assign mismatch = (curr_state ==S4) ? 1'b0 : 1'b1; //组合逻辑描述输出

endmodule

3.23Testbench`timescale 1ns/1ps //仿真韶光单位1ns 仿真韶光精度1ps

module sequence_detect04_tb();

//旗子暗记申明

reg clk;

reg rst_n;

reg seq_in;

wire mismatch;

//复位旗子暗记天生

//输入旗子暗记天生,输入旗子暗记为“1001001001001”

//时钟旗子暗记与复位旗子暗记赋初值

initial begin

clk = 0;

rst_n = 1;

#5 rst_n = 0;

#10 rst_n = 1;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

seq_in = 0;#10;

seq_in = 0;#10;

seq_in = 1;#10;

end

//时钟旗子暗记天生

always #5 clk = ~clk;

//模块实例化(将申明的旗子暗记连接起来即可)

sequence_detect04 u_sequence_detect04(

.clk (clk),

.rst_n (rst_n),

.seq_in (seq_in),

.mismatch (mismatch)

);

endmodule

3.24仿真结果

输入序列1001001001001,根据可不重叠检测理论上可检测两次旗子暗记翻转,从仿真结果可以看到mismatch发生两次翻转,且第二组的1001中的第一个1来自第一组1001中末了一个1,即发生重叠不可检测,以是比较于重叠检测少了第二次翻转(同理第四次翻转同样不可发生)。

四、总结

状态机法序列检测器:一句话概括便是设计繁芜、不易扩展但是检测模式灵巧。
比较利用移位寄存器来说的话,状态机稍稍繁芜些,紧张表示在不易扩展(重新检测不同序列需重新设计状态转移)和状态机的状态转移判断上;但是这样也给状态机带来了优点 ,便是灵巧性好,可以灵巧处理输入和输出,由于状态机具有可编程性。
同时可以处理较为繁芜的序列检测任务,由于状态机可以支持多个状态和转换。

移位寄存器法:一句话概括便是设计大略、易于扩展但是检测模式呆板。
比较于利用状态机来说的话,只能处理大略的序列检测任务,由于它没有状态机的多状态和转换功能。
且输入和输出的灵巧性差,由于寄存器序列移位寄存器是固定的,检测模式固定。
但是上风很明显,便是设计和开拓相对大略,只须要几个寄存器和逻辑门。
且易于扩展,如果要检测另一个序列,只须要修正输入数据。

模式选择:序言部分提到了检测模式包括重叠模式、连续模式、间隔模式等等。
本文着重剖析重叠与非重叠检测模式,结论是重叠检测模式可以用状态机和移位寄存器设计,非重叠检测模式可以用灵巧的状态机设计;本文都是基于默认的连续检测模式设计,如果采取间隔检测模式,处理方法是添加指示旗子暗记使能端,可以用状态机和移位寄存器设计。
由于设计逻辑大略,以是这部分省略,可自行参照第二部分代码设计。

综上所述,状态机序列检测器适用于处理较为繁芜的序列检测任务,而寄存器序列移位寄存器适用于处理大略的序列检测任务。
在实际运用中,应根据详细的需求来选择得当的序列检测方法。

标签:

相关文章

南安IT培训,培育未来科技人才的新引擎

随着我国经济的快速发展,IT产业已成为推动经济增长的重要力量。为了满足社会对IT人才的需求,我国各地纷纷开展IT培训,而南安IT培...

互联网 2024-12-29 阅读0 评论0