外同步信号检测---verilog---状态机
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: chensimin // // Create Date: 2018/02/08 11:39:20 // Design Name: // Module Name: signal_detect // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module signal_detect # ( parameter TOTAL_TIME_CNT = 200, parameter THRESHOLD_VALUE = 36, parameter WIDTH = 32 ) ( input wire clk, input wire rst, input wire signal, output wire signal_existence ); //--------------------------------------------------------------
外部信号边沿检测
reg signal_delay_1; reg signal_delay_2; wire signal_rise; always @(posedge clk or posedge rst) begin if( rst ) begin signal_delay_1 <= 1'b0; signal_delay_2 <= 1'b0; end else begin signal_delay_1 <= signal; signal_delay_2 <= signal_delay_1; end end assign signal_rise = !signal_delay_2 && signal_delay_1; //---------------------------------------------------------------- 计数器1 用来在第一个状态计数 reg [ WIDTH-1 : 0 ] time_cnt_1; always @(posedge clk or posedge rst) begin if( rst ) time_cnt_1 <= 0; else if( time_cnt_1 < TOTAL_TIME_CNT - 1 && current_state == 2'b01) time_cnt_1 <= time_cnt_1 + 1'b1; else time_cnt_1 <= 0; end //---------------------------------------------------------------- 计数器2 用来在第二个状态计数 reg [ WIDTH-1 : 0 ] time_cnt_2; always @(posedge clk or posedge rst) begin if( rst ) time_cnt_2 <= 0; else if( time_cnt_2 < TOTAL_TIME_CNT - 1 && current_state == 2'b10) time_cnt_2 <= time_cnt_2 + 1'b1; else time_cnt_2 <= 0; end //---------------------------------------------------------------- 计算第一个状态下 signal_rise 的脉冲个数 reg [ WIDTH-1 : 0 ] i; always @(posedge clk or posedge rst) begin if( rst ) i <= 0; else if ( time_cnt_1 == 0 ) i <= 0; else if( signal_rise && current_state == 2'b01) i <= i + 1'b1; end //---------------------------------------------------------------- 计算第二个状态下 signal_rise 的脉冲个数 reg [ WIDTH-1 : 0 ] j; always @(posedge clk or posedge rst) begin if( rst ) j <= 0; else if ( time_cnt_2 == 0 ) j <= 0; else if( signal_rise && current_state == 2'b10) j <= j + 1'b1; end //---------------------------------------------------------------- localparam NO_SIGNAL = 2'b01; localparam HAVE_SIGNAL = 2'b10; reg [1:0]current_state; reg [1:0]next_state; always @ (posedge clk or posedge rst) begin if( rst ) current_state <= NO_SIGNAL; else current_state <= next_state; end //-------------------------------------------------------------- 状态机跳变条件:
1.在NO_SIGNAL状态下,先是在一定时间段内,数脉冲的个数,当脉冲的个数大于了某个阈值时,立刻判断为,外同步信号存在。
2.在HAVE_SIGNAL状态下,同样也是数脉冲的个数,当一段时间内,脉冲总数量小于某个阈值时,则判断为外同步信号丢失,状态跳转到NO_SIGNAL状态 always @(*) begin next_state = NO_SIGNAL; case( current_state ) NO_SIGNAL: begin if( i >= THRESHOLD_VALUE ) next_state = HAVE_SIGNAL; else next_state = NO_SIGNAL; end HAVE_SIGNAL: begin if( (time_cnt_2 == TOTAL_TIME_CNT - 1) && j < THRESHOLD_VALUE ) next_state = NO_SIGNAL; else next_state = HAVE_SIGNAL; end endcase end //-------------------------------------------------------------
状态机输出信号驱动
reg signal_existence_r; always @(posedge clk or posedge rst) begin if (rst) begin signal_existence_r <= 1'b0; end else begin case( current_state ) NO_SIGNAL: begin signal_existence_r <= 1'b0; end HAVE_SIGNAL: begin signal_existence_r <= 1'b1; end endcase end end assign signal_existence = signal_existence_r; endmodule /* add_force {/signal_detect/clk} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps add_force {/signal_detect/rst} -radix hex {1 0ns} {0 150ns} add_force {/signal_detect/signal} -radix hex {0 0ns} {1 300ns} {0 400ns} -repeat_every 500ns */
仿真波形:
1.
2.
3.