zoukankan      html  css  js  c++  java
  • 信号监测---verilog

    信号监测---verilog

    此模块用于监测某一信号源是否持续稳定的传送。

    监测思路:监测信号源高电平或者低电平的宽度是否始终保持一致(一定范围内允许有误差)

    `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

    仿真结果:

  • 相关阅读:
    一个多列组合框
    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
    图结构练习——BFS——从起始点到目标点的最短步数
    图结构练习——BFS——从起始点到目标点的最短步数
    广度优先搜索介绍
    广度优先搜索介绍
    数据结构实验之二叉树一:树的同构
    数据结构实验之二叉树一:树的同构
    对代码不满足,是任何真正有天才的程序员的根本特征。
  • 原文地址:https://www.cnblogs.com/chensimin1990/p/9798925.html
Copyright © 2011-2022 走看看