信號監測---verilog

信號監測---verilogspa

此模塊用於監測某一信號源是否持續穩定的傳送。code

監測思路:監測信號源高電平或者低電平的寬度是否始終保持一致(必定範圍內容許有偏差)視頻

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: chensimin
// 
// Create Date: 2018/10/12 14:43:57
// Design Name: 
// Module Name: signal_detection
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module signal_detection #(
    parameter WIDTH             = 32 ,
    parameter MAXIMUM_ERROR     = 10 ,
    parameter CNT_CLK_FREQUENCY = 27 ,
    parameter DELAY_SIGNAL_OUT  = 3,
    parameter TOTAL_TIME_HIGH   = 100000,
    parameter TOTAL_TIME_LOW    = 100000
    )
(
    input   wire               clk ,
    input   wire               clk_out_syn ,
    input   wire               rst ,
    input   wire               signal_src ,
    output  wire               lock
);

//----------------------------------------------------------------------

// Signal source synchronization

reg signal_src_delay_1 = 0 ;
reg signal_src_delay_2 = 0 ;

always @(posedge clk or posedge rst)
begin
    if(rst)
    begin
        signal_src_delay_1 <= 1'b0 ;
        signal_src_delay_2 <= 1'b0 ;
    end
    else 
    begin
        signal_src_delay_1 <= signal_src ;
        signal_src_delay_2 <= signal_src_delay_1 ;
    end
end

//----------------------------------------------------------------------

//Rising edge detection

assign rising_edge  =   signal_src_delay_1  && (!signal_src_delay_2) ; 
assign falling_edge = (!signal_src_delay_1) &&   signal_src_delay_2  ; 

//----------------------------------------------------------------------

//count enable 信號上升沿開始計數,降低沿中止計數,此模塊採用的是計算高電平的寬度

reg cnt_en = 0 ;

always @(posedge clk or posedge rst)
begin
    if(rst)
        cnt_en <= 1'b0 ;
    else if(rising_edge)
        cnt_en <= 1'b1 ;
    else if(falling_edge)
        cnt_en <= 1'b0 ;
end

//----------------------------------------------------------------------

//count clock period

reg [15:0] cnt = 0;

always @(posedge clk or posedge rst)
begin
    if(rst)
        cnt <= 16'd0 ;
    else if(cnt_en)
        cnt <= cnt + 1'b1 ;
    else 
        cnt <= 16'd0 ;
end


//----------------------------------------------------------------------

//total 存儲兩個相鄰高電平的寬度

reg [15:0] total_number = 0;
reg [15:0] total_number_delay = 0;
reg [15:0] total_number_delay_1 = 0;
always @(posedge clk or posedge rst)
begin
    if(rst)
    begin
        total_number <= 16'd0 ;
        total_number_delay <= 16'd0 ;
        total_number_delay_1 <= 16'd0 ;
    end
    else if(falling_edge)
    begin
        total_number <= cnt ;
        total_number_delay <= total_number ;
        total_number_delay_1 <= total_number_delay ;
    end
    else if(get_total_time_high || get_total_time_low)
    begin 
        total_number <= 16'd0 ;
        total_number_delay <= 16'd0 ;
        total_number_delay_1 <= 16'd0 ;

    end
end
//此處或得了相鄰三個高電平的寬度值
//----------------------------------------------------------------------

localparam UNLOCK = 1'b0;
localparam LOCK   = 1'b1;

//----------------------------------------------------------------------

wire   lock_state_1 ;
wire   lock_state_2 ; 

//考慮高電平寬度偏差量
assign lock_state_1 = (total_number >= total_number_delay_1) && ((total_number - total_number_delay_1) <= MAXIMUM_ERROR) && (total_number > 16'd100) ; assign lock_state_2 = (total_number < total_number_delay_1) && ((total_number_delay_1 - total_number) <= MAXIMUM_ERROR) && (total_number > 16'd100) ; //用total_number 與 total_number_delay_1 兩個值來參與運算,是考慮到了隔行視頻,相鄰兩個高電平的寬度是不同的,由於一幀有兩場,即一幀中有兩個V信號的有效區間 //---------------------------------------------------------------------- // 1us reg get_time_1us ; reg [WIDTH-1:0] m ; always @ ( posedge clk or posedge rst ) begin if( rst ) begin get_time_1us <= 1'b0; m <= 0; end else if( m == CNT_CLK_FREQUENCY - 1 ) begin get_time_1us <= 1'b1; m <= 0; end else begin get_time_1us <= 1'b0; m <= m + 1'b1; end end //---------------------------------------------------------------------- reg get_total_time_high ; reg get_total_time_low ; reg [WIDTH-1:0] i ; reg [WIDTH-1:0] k ; always @ (posedge clk or posedge rst) begin if(rst) begin get_total_time_high <= 1'b0 ; get_total_time_low <= 1'b0 ; i <= 0 ; k <= 0 ; end else begin get_total_time_high <= 1'b0 ; get_total_time_low <= 1'b0 ; if(signal_src_delay_2 == 1'b0) begin if( i == TOTAL_TIME_LOW -1 ) begin get_total_time_low <= 1'b1 ; i <= 0 ; end else if(get_time_1us) i <= i + 1'b1 ; end else i <= 0; if(signal_src_delay_2 == 1'b1) begin if( k == TOTAL_TIME_HIGH -1 ) begin get_total_time_high <= 1'b1 ; k <= 0; end else if(get_time_1us) k <= k + 1'b1 ; end else k <= 0 ; end end //---------------------------------------------------------------------- reg current_state ; reg next_state ; always @ ( posedge clk or posedge rst ) begin if( rst ) current_state <= UNLOCK; else current_state <= next_state; end //---------------------------------------------------------------------- always @ ( * ) begin case( current_state ) UNLOCK: if( lock_state_1 || lock_state_2 ) next_state = LOCK; else next_state = UNLOCK; LOCK: if( get_total_time_high || get_total_time_low ) next_state = UNLOCK; else next_state = LOCK; endcase end //---------------------------------------------------------------------- //output reg reg lock_r; always @ (posedge clk or posedge rst) begin if(rst) lock_r <= 1'b0 ; else begin case(current_state) UNLOCK: lock_r <= 1'b0; LOCK : lock_r <= 1'b1; endcase end end reg dly_reg[0:DELAY_SIGNAL_OUT-1]; genvar var_i; generate for (var_i=0;var_i<=DELAY_SIGNAL_OUT-1;var_i=var_i+1) begin:delay_generate_block if (var_i==0) begin always @ (posedge clk_out_syn or posedge rst) if (rst) dly_reg[var_i] <= 0; else dly_reg[var_i] <= lock_r; end else begin always @ (posedge clk_out_syn or posedge rst) if (rst) dly_reg[var_i] <= 0; else dly_reg[var_i] <= dly_reg[var_i-1]; end end endgenerate assign lock = dly_reg[DELAY_SIGNAL_OUT-1]; endmodule

仿真結果:blog

相關文章
相關標籤/搜索