对复位信号,使能信号的一种滤波方法

在进行FPGA开发时,常有复位信号或使能信号,这种信号的特点是在一个特定时刻改变状态后,信号状态不会突变,而是要持续一段时间。为避免因外部因素引起的复位、使能信号的改变,可采用如下方法对其滤波:

将信号打三拍,若信号在三拍内没有变化,则信号可以接收状态改变,否则信号保持原状态。

代码及其仿真结果(采用HDLBits网站的在线仿真)如下:

module top_module ();  //testbench
	reg clk=0;
    reg rst_process_stream = 0;
    wire data_stream_en_reg;
    wire data_stream_en_reg0;
    wire data_stream_en_reg1;
    wire data_stream_en_reg2;
	always #5 clk = ~clk;  // Create clock with period=10
	initial `probe_start;   // Start the timing diagram

    `probe(clk);        // Probe signal "clk"
    `probe(in); 
	`probe(rst_process_stream); 
    `probe(data_stream_en_reg);
    `probe(data_stream_en_reg0);
    `probe(data_stream_en_reg1);
    `probe(data_stream_en_reg2);
    
	// A testbench
	reg in=0;
    
	initial begin
        #0 rst_process_stream <= 1;
        #5 rst_process_stream <= 0;
		#10 in <= 0;
		#40 in <= 1;
		#10 in <= 0; //意外的状态转变
        #10 in <= 1;
        #40 in <= 1;
		$display ("Hello world! The current time is (%0d ps)", $time);
		#1000 $finish;            // Quit the simulation
	end

    mytest dut ( .data_stream_en(in) ,
                .clk_process(clk),
                .rst_process_stream(rst_process_stream),
                .data_stream_en_reg(data_stream_en_reg),
                .data_stream_en_reg0(data_stream_en_reg0),
                .data_stream_en_reg1(data_stream_en_reg1),
                .data_stream_en_reg2(data_stream_en_reg2)
               );   // Sub-modules work too.

endmodule

module mytest(input data_stream_en, input clk_process,input rst_process_stream,output reg data_stream_en_reg,
             output reg data_stream_en_reg0,
             output reg data_stream_en_reg1,
             output reg data_stream_en_reg2);
    
    //reg data_stream_en_reg0,data_stream_en_reg1,data_stream_en_reg2;
    
	always @ (posedge clk_process or posedge rst_process_stream)
    begin
        if(rst_process_stream == 1'b1)
        begin
            data_stream_en_reg0 <= 1'b0     ;
            data_stream_en_reg1 <= 1'b0     ;
            data_stream_en_reg2 <= 1'b0     ;
        end
        else
        begin
            data_stream_en_reg0 <= data_stream_en ; //原信号打三拍
            data_stream_en_reg1 <= data_stream_en_reg0 ;
            data_stream_en_reg2 <= data_stream_en_reg1 ;
        end
    end

    always @ (posedge clk_process or posedge rst_process_stream)
    begin
        if(rst_process_stream == 1'b1)
        begin
            data_stream_en_reg <= 1'b0 ;
        end
        else if((data_stream_en_reg0 == data_stream_en_reg1) && (data_stream_en_reg1 == data_stream_en_reg2))  //三个时钟周期内,信号状态不变
        begin
            data_stream_en_reg <= data_stream_en_reg2 ; //可以接受信号状态改变
        end
        else
        begin
            data_stream_en_reg <= data_stream_en_reg ; //输出信号保持不变
        end
    end
endmodule