- module auto_lock(
- input clk, //系统时钟
- input rst_n, //系统复位
- input lock_signal, //失锁锁定输入
-
- output reg analog_switch_1, //模拟开关1输出
- output reg analog_switch_2, //模拟开关2输出
- output reg [13:0] dac_ch1, //温度dac
- output reg sawtooth_control, //锯齿波控制
-
- input signed [15:0]adc_ch1_data, //adc ch1电压值
- /* //按键输入
- input key1_in,
- input key2_in,
- input key3_in,
- input key4_in,
- */
- //系统状态指示
- output lock_status_led //led
-
- //DEBUG数据
- // output [23:0]debug_state_value,
- // output [23:0]debug_pdh_ok_count_value
- );
-
- parameter ON = 1'b1,OFF = 1'b0;
- parameter LOCK = 1'b1,UNLOCK = 1'b0;
- parameter START = 1'b1,END = 1'b0;
-
- parameter DIR_UP = 2'd0,DIR_DOWN = 2'd1,DIR_EXPAND_SCOPE = 2'd2;
-
- parameter DAC_TO_TEMPERATURE_INIT = 14'd8192; //0
-
- parameter T10MS = 32'd49_999_9;
- parameter T100MS = 32'd49_999_99;
- parameter T1S = 32'd49_999_999;
- /*
- parameter T10MS = 32'd4;
- parameter T100MS = 32'd49;
- parameter T1S = 32'd49_9;
- */
-
- parameter T2S = 8'd2;
- parameter T5S = 8'd5;
- parameter T10S = 8'd10;
- parameter T20S = 8'd20;
-
- // assign debug_pdh_ok_count_value = pdh_ok_count;
-
- /***********************锁定信号触发边沿检测*************************/
- lock_signal_edge_check lock_signal_edge_check_model(
- .clk (clk), //系统时钟
- .rst_n (rst_n), //系统复位
-
- .lock_signal(lock_signal),
- .locked (locked),
- .pdh_ok (pdh_ok),
- .lock_status_led (lock_status_led)
- );
-
- /***********************系统运行*************************/
- parameter PDH_OK_COUNT_N = 8'd2;
- parameter INIT_N = 14'd8; // N 的初始范围
- parameter K = 14'd2; //K
-
-
- //运行状态
- parameter INIT = 8'd0; //初始化
- parameter RUN_INIT_I = 8'd1; //运行
- parameter START_PZT_SCANNING = 8'd2; //开始锯齿波扫描
- parameter WAIT = 8'd3;
- parameter IF_PDH_OK = 8'd4;
- parameter SEARCH_PDH_OK = 8'd5;
- parameter LOCK_IN_PROCESS = 8'd6;
- parameter UNLOCK_IN = 8'd7;
- parameter UNLOCK_IN_RETRY = 8'd8;
- parameter LOCK_IN = 8'd9;
-
- reg[7:0] pdh_ok_count;
- reg[18:0] pdh_time_count;//在锯齿波为1Hz延时为20ms 频率越高锁定时间越短
- reg pdh_ok_delay_flag; //pdh延时标志
- reg [7:0]locked_fail_count; //锁定失败计数
-
- reg [13:0]dac_to_temperature_i; //温度输出
- reg [13:0]dac_to_temperature_top; //上限
- reg [13:0]dac_to_temperature_bottom; //下限
-
- reg [13:0]N;
- reg [3:0]DIR; //扫描方向
-
- //计时器
- reg [25:0]time_count;
- reg [7:0]time_ones;
- //三段式状态机
- reg[7:0]cstate; //当前状态
- reg[7:0]nstate; //下一个状态
- //第一部分说明初始状态,和current_state<=next_state
- //每一个时钟沿产生一次可能的状态变化
- always@(posedge clk or negedge rst_n)
- if(!rst_n)
- cstate <= INIT; //复位态
- else
- cstate <= nstate;
-
- //第二部分,状态转移,产生下一状态的整合逻辑
- //状态的跳转
- always@(cstate or time_ones or pdh_ok or locked)
- begin
-
- case (cstate)
-
- INIT: //初始化
- begin
- if(time_ones == T20S) //20s
- nstate <= RUN_INIT_I;
- else
- nstate <= INIT;
- end
-
- RUN_INIT_I: //运行 //初始化温度输出
- begin
- nstate <= START_PZT_SCANNING;
- end
-
- START_PZT_SCANNING: //开始锯齿波扫描
- begin
- nstate <= WAIT;
- end
-
- WAIT: //等待锯齿波扫描 4 - 10s
- begin
- //PDH OK? //判断是否找到信号
- if(pdh_ok == LOCK)
- nstate <= IF_PDH_OK;
- else
- nstate <= WAIT;
- end
-
- IF_PDH_OK: //PDH OK判断
- begin
-
- if(time_ones == T2S) //2s
- begin
-
- if(pdh_ok_count >= PDH_OK_COUNT_N) //真信号
- nstate <= SEARCH_PDH_OK; //搜索到pdh
- else
- nstate <= WAIT; //重新扫描
-
- end
- else
- nstate <= IF_PDH_OK;
-
- end
-
- SEARCH_PDH_OK: //扫描到PDH
- begin
-
- //100MS等待
- if(time_count == T100MS) //100ms
- begin
- nstate <= LOCK_IN_PROCESS;
- end
-
- end
-
- LOCK_IN_PROCESS: //锁入过程
- begin
-
- if(time_ones == T2S) //2s
- begin
- if(locked == LOCK)
- nstate <= LOCK_IN; //已锁定
- else
- nstate <= UNLOCK_IN; //未锁定
-
- end
-
- end
-
- UNLOCK_IN: //未锁定
- begin
-
- //锁定失败次数小于5次
- if(locked_fail_count < 8'd5)
- begin
- nstate <= UNLOCK_IN_RETRY;
- end
- else
- begin
- nstate <= WAIT;
- end
-
- end
-
- UNLOCK_IN_RETRY: //重试锁定
- begin
-
- //2S判断一次
- if(time_ones == T2S) //2s
- begin
- nstate <= LOCK_IN_PROCESS;
- end
-
- end
- LOCK_IN: //已锁定
- begin
-
- if(locked == UNLOCK) //unlock
- begin
- nstate <= START_PZT_SCANNING; //重新进入扫描模式
- end
-
- end
-
-
- default:nstate <= INIT;
- endcase
- end
-
-
-
- //第三段,产生输出
- always@(posedge clk or negedge rst_n)
- if(!rst_n)
- begin
-
- dac_ch1 <= 14'd8192; //0
-
- analog_switch_1 <= OFF;
- analog_switch_2 <= OFF;
- sawtooth_control <= OFF;
-
-
- dac_to_temperature_i <= 14'd8192; //0V
- pdh_time_count <= 0;
- pdh_ok_count <= 8'd0;
- pdh_ok_delay_flag <= END;
- // locked_fail_count <= 8'd0; //锁定失败计数
-
- N <= INIT_N;
- DIR <= DIR_UP; //init 扫描方向
- time_count <= 0;
- time_ones <= 0;
-
- dac_to_temperature_top <= 14'd8192 + INIT_N; //上限
- dac_to_temperature_bottom <= 14'd8192 - INIT_N; //下限
-
- end
- else
- begin
- case(nstate)
-
- INIT:
- begin
-
- //系统预热20s
- if(time_count == T1S) //1s
- begin
- time_ones <= time_ones + 1'b1;
- time_count <= 0;
- end
- else
- time_count <= time_count + 1'b1;
-
- end
-
- RUN_INIT_I: //运行 //初始化温度输出
- begin
- //init i = 0
- time_ones <= 8'd0;
- dac_to_temperature_i <= 14'd8192;
-
- end
-
- START_PZT_SCANNING: //开始锯齿波扫描
- begin
- //start pzt scanning
- analog_switch_1 <= OFF;
- analog_switch_2 <= ON;
-
- //开启锯齿波扫描
- sawtooth_control <= ON;
-
- //T(i) = V * step * i;
- dac_ch1 <= dac_to_temperature_i;
- end
-
- WAIT: //等待锯齿波扫描 4 - 10s
- begin
-
- //wait 4 - 10s
- if(time_count == T1S) //1s
- begin
- time_ones <= time_ones + 1'b1;
- time_count <= 0;
- end
- else
- time_count <= time_count + 1'b1;
-
- if(time_ones == T2S) //2s
- begin
- search_mode(); //扫描模式
- time_ones <= 0;
- end
-
- dac_ch1 <= dac_to_temperature_i; //更新数据
-
- pdh_ok_delay_flag <= START; //开始延时
- pdh_time_count <= 0;
- pdh_ok_count <= 8'd0;
-
- end
- IF_PDH_OK: //PDH OK判断
- begin
-
-
- //锯齿波扫描延长2S
- if(time_count == T1S) //1s
- begin
- time_ones <= time_ones + 1'b1;
- time_count <= 32'd0;
- end
- else
- time_count <= time_count + 1'b1;
-
-
- //pdh误触发处理
- //开始延时
- if(pdh_ok_delay_flag == START)
- begin
- if(pdh_time_count == T10MS) //ms
- begin
- pdh_ok_delay_flag <= END;
- pdh_time_count <= 32'd0;
- end
- else
- pdh_time_count <= pdh_time_count + 1'b1;
- end
- else
- begin
- if(pdh_ok == LOCK)
- begin
- pdh_ok_count <= pdh_ok_count + 1'b1;
- pdh_ok_delay_flag <= START;
- end
- end
-
- end
-
- SEARCH_PDH_OK: //扫描到PDH
- begin
-
- time_ones <= 8'd0;
-
- //stop pzt scanning
- analog_switch_2 <= OFF;
- //analog_switch_1 <= ON;
- sawtooth_control <= OFF;
-
- if(time_count == T100MS) //1s
- begin
-
- end
- else
- time_count <= time_count + 1'b1;
-
-
- end
-
- LOCK_IN_PROCESS: //锁入过程
- begin
- //锁入过程
- //analog_switch_2 <= OFF;
- analog_switch_1 <= ON;
-
- //2S判断一次
- if(time_count == T1S) //1s
- begin
- time_ones <= time_ones + 1'b1;
- time_count <= 32'd0;
- end
- else
- time_count <= time_count + 1'b1;
-
- end
-
-
- UNLOCK_IN: //未锁定
- begin
-
- //锁定失败计数
- locked_fail_count <= locked_fail_count + 1'b1;
-
- time_ones <= 0;
- time_count <= 0;
-
-
- if(locked_fail_count < 8'd5)
- begin
-
- end
- else
- begin
- if(dac_to_temperature_i > 14'd0)
- dac_to_temperature_i <= dac_to_temperature_i - 1'b1;
-
- analog_switch_1 <= OFF;
- analog_switch_2 <= ON;
-
- locked_fail_count <= 8'd0;
- end
-
- end
-
- UNLOCK_IN_RETRY: //重试锁定
- begin
-
- analog_switch_1 <= OFF;
-
- if(time_count == T1S) //1s
- begin
- time_ones <= time_ones + 1'b1;
- time_count <= 32'd0;
- end
- else
- time_count <= time_count + 1'b1;
-
-
- end
-
- LOCK_IN: //已锁定
- begin
-
- //5S判断一次
- if(time_count == T1S) //1s
- begin
- time_ones <= time_ones + 1'b1;
- time_count <= 32'd0;
- end
- else
- time_count <= time_count + 1'b1;
-
- if(time_ones == T5S) //5s
- begin
-
- //电压 > 1 并且 处于锁定状态
- if(adc_ch1_data > 16'sd6553 && dac_to_temperature_i < 14'd16383 && locked == LOCK)
- begin
- dac_to_temperature_i <= dac_to_temperature_i - 1;
- end
- else if(adc_ch1_data < -16'sd6553 && dac_to_temperature_i > 14'd0 && locked == LOCK)
- begin
- dac_to_temperature_i <= dac_to_temperature_i + 1;
- end
-
- //T(i) = V * step * i;
- dac_ch1 <= dac_to_temperature_i;
-
- time_ones <= 0;
-
- end
-
- end
-
- default:;
- endcase
- end
在我上面的三段式状态机中很多地方有涉及到,根据时间来进行状态跳转,我在产生第三段进行计时,第二段里面进行状态跳转,但跳转时如何清零time_count和time_ones呢,我现在是在下一个状态里面清,能在跳转的同时进行清零吗?
在状态机里面涉及到定时一般是怎么做的啊?