牛客网有关序列检测换题型总结

文章介绍了如何使用Verilog进行循环左移和右移操作,并提供了示例代码。此外,还详细讲解了如何设计一个序列检测模块,检测输入信号是否符合特定序列,包括两种实现方法:一种是基于移位寄存器,另一种是通过状态机。给出了相应的Verilog代码实现和测试bench验证。
摘要由CSDN通过智能技术生成

1.verilog循环左移和右移

https://blog.csdn.net/ciscomonkey/category_8301642.html   引用

ciscomonkey博主文章

下面举一个例子说明一下怎么样进行移位

                            1         0           0         1          0
                            0         1           0          0          1
                            1         0                   0          0
                            0         1            0          1         0
                            0         0            1          0           1

循环向右边移动 

left_shifter <= { a[0] , a[4 : 1 ] } ;

循环向左边移动

                           1         0         0          1           
                            0        0          1          0           1 
                           0         1          0          1          0
                           1                 1           0         0 
                           0           1        0           0         1 
left_shifter <=  { a[3 : 0 ] , a[4] } ; 

循环向右边移动相当于把最低位提到最高位然后进行移动

循环向左边移动相当于把最高位提到最低位然后进行移动

2. 输入序列连续的序列检测

描述

请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。

模块的接口信号图如下:

      

模块的时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能

输入描述:

clk:系统时钟信号

rst_n:异步复位信号,低电平有效

a:单比特信号,待检测的数据

输出描述:

match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0

题解思路本题可以用移位寄存器的思路进行解答,当match信号刚好匹配到传输序列的时候进行输出匹配

module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
);
  	reg[7:0] a_r;
	always@(posedge clk or negedge rst_n) begin
        if(~rst_n) begin
        	a_r<='b0;
    	end
    	else begin
        	a_r<={a_r[6:0],a}; //循环向左边移动
    	end
	end
  
	always@(posedge clk or negedge rst_n) begin
      if(~rst_n) begin
    	   match <= 1'b0;
  	    end
        else begin
           match <= a_r==8'b01110001;
        end
	end
endmodule

方法二同时也可以写一个状态机利用状态机来进行实现

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 define 
reg    [3: 0 ]  cur_state ;  //定义状态
reg    [3 : 0 ]  next ;  //定义次态

//first step 
always @ (posedge clk or negedge  rst_n) begin 
	if (!rst_n) begin
		cur_state <= idle ; 
	end
	else begin 
		 cur_state <= next ;
	end
end

//second step 
always @ (*) begin 
	 case (cur_state) 
	idle :  next =   (a == 0 ) ?  s1 :  idle ; 
    s1   :  next =   (a == 0 ) ?  s1 :  s2 ; 
    s2 :  next =   (a == 0 ) ?  s1 :  s3 ;  
    s3 :  next =   (a == 0 ) ?  s1 :  s4 ;  
    s4 :  next =   (a == 0 ) ?  s5 :  idle ; 
    s5 :  next =   (a == 0 ) ?  s6 :  s2 ; 
	s6 :  next =   (a == 0 ) ?  s7 :  s2 ; 
	s7 :  next =   (a == 0 ) ?  s1 :  s8 ;
	s8 :  next =   (a == 0 ) ?  s1 :  s3 ; 
	default  : next =  idle ;
	 endcase 
end

//third step 
always @ (posedge clk or negedge rst_n) begin
	if (!rst_n) begin
	    match <= 1'b0 ;
    end
	else  case (cur_state)
	      s8 : match <= 1'b1 ;
		  default : match <= 1'b0 ;
	endcase
	

end
endmodule

注意状态机的话不要引入锁存器,进行锁存结构 if else语句必须配套,采用三段式状态机来进行书写

状态转移图

 用状态转移图这种方法相对来讲有点复杂,状态机解题三段式不过框架更好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值