wmzzddb 2021-05-28 21:37 采纳率: 0%
浏览 53

如何用verilog实现任意序列的检测?

最近在入门verilog语言,在做序列检测的实验时要求该序列检测器可以识别任意输入的序列,即格式、长度不一、即0101、10101、011等字符串,并且有额外的输入端口:目标序列(target)、目标序列长度(length)。但是本人找遍全网只发现了针对特定位数和序列的检测器(;′⌒`)

5bit序列01101的检测器代码如下,如果有需要增添或修改的,还望有大佬指点迷津🙏

module SerialSequenceDetector(
    input d,
	 input rst_n,
    input clk,
    output  reg flag
    );
	 
	reg [4:0] CurrentSequence;
	parameter Sequence=5'd01101;
	
	always @(posedge clk or negedge rst_n)begin
	   if(!rst_n) begin
			CurrentSequence[4:0] <= { CurrentSequence[3:0],d};
				if(CurrentSequence[4:0] == Sequence[4:0])
					flag <= 1'b1;
				else
					flag <= 1'b0;
		  end
		end
endmodule

test.v如下:

`timescale 1ns / 1ns
`define halfperiod 10

module SerialSequenceDetector_tb;

	// Inputs

	reg clk;
	reg [23:0]data;
	reg rst_n;

	// Outputs
	wire d;
	
	// Instantiate the Unit Under Test (UUT)
	SerialSequenceDetector uut (
		.d(d), 
		.rst_n(rst_n),
		.clk(clk), 
		.flag(flag)
	);
	
	always #5 clk = ~clk;
	initial begin

		clk = 1;
		rst_n=0;
		#5 rst_n=1;
		#15 rst_n=0;data=24'b0011_1100_1101_0110_1001_0100;
		#(`halfperiod * 200) $stop;  //执行100个时钟周期
		
	end	
	always@(negedge clk) #10 data = {data[22 : 0], data[23]};
	assign d = data[23]; //将最高位输入到序列检测器中

endmodule
  • 写回答

1条回答 默认 最新

  • 普通网友 2024-04-30 18:19
    关注

    要实现任意序列的检测器,你需要动态地匹配输入序列和目标序列。下面是一个根据目标序列和目标序列长度实现的 Verilog 代码示例:

    module SerialSequenceDetector(
        input wire clk,
        input wire rst_n,
        input wire d,
        input wire [31:0] target_sequence,
        input wire [7:0] target_length,
        output reg flag
    );
    
    reg [31:0] current_sequence;
    reg [7:0] current_length;
    
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            current_sequence <= 0;
            current_length <= 0;
            flag <= 0;
        end
        else begin
            // Shift in the new input bit
            current_sequence <= {current_sequence[30:0], d};
            current_length <= current_length + 1;
            
            // Check if the current sequence matches the target sequence
            if (current_length >= target_length) begin
                if (current_sequence == target_sequence)
                    flag <= 1;
                else
                    flag <= 0;
            end
        end
    end
    
    endmodule
    

    在这个例子中,target_sequence 表示目标序列,target_length 表示目标序列的长度。模块会根据输入的序列动态地进行匹配,并且在检测到目标序列时,将 flag 信号置为 1。

    测试代码也需要相应地进行修改:

    `timescale 1ns / 1ns
    `define halfperiod 10
    
    module SerialSequenceDetector_tb;
    
    // Inputs
    reg clk;
    reg rst_n;
    reg [23:0] data;
    reg [31:0] target_sequence;
    reg [7:0] target_length;
    
    // Outputs
    wire d;
    wire flag;
    
    // Instantiate the Unit Under Test (UUT)
    SerialSequenceDetector uut (
        .clk(clk),
        .rst_n(rst_n),
        .d(d),
        .target_sequence(target_sequence),
        .target_length(target_length),
        .flag(flag)
    );
    
    always #5 clk = ~clk;
    initial begin
        clk = 1;
        rst_n = 0;
        #5 rst_n = 1;
        #15 rst_n = 0;
        data = 24'b0011_1100_1101_0110_1001_0100;
        target_sequence = 32'b01101100_11010010_01001000_10000100;
        target_length = 8;
        #(`halfperiod * 200) $stop;  //执行100个时钟周期
    end
    
    always @(negedge clk) #10 data = {data[22 : 0], data[23]};
    assign d = data[23]; //将最高位输入到序列检测器中
    
    endmodule
    

    在测试代码中,我添加了 target_sequencetarget_length,分别表示目标序列和目标序列的长度。你需要将目标序列和长度按照你的需求进行设置。

    评论

报告相同问题?