[FPGA]

新手求助,我写的程序复位有时出错,但在仿真里看是正...

[复制链接]
653|0
手机看帖
扫描二维码
随时随地手机跟帖
whyil|  楼主 | 2017-12-24 09:14 | 显示全部楼层 |阅读模式
我使用的是黑金AX309开发板,写的一个程序,烧程序在板子里跑的时候,按下复位有时程序直接跳过预热部分进入运行,有时就直接停在预热这里,有时就正常运行。我在Modelsim里面仿真的没有问题,在仿真里,复位后都是正常执行的,求助

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    13:38:11 11/09/2017
// Design Name:
// Module Name:    auto_lock
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
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
                       
//                        input sawtooth_frequence,                //锯齿波频率
                        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 T100MS = 32'd49_999_99;
//        parameter T1S = 32'd49_999_999;

        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;       
       
        //temperture search zero point
        //parameter EXPERIENCE = 14'd8540;        //经验值
       
        assign debug_state_value = auto_lock_state;
        assign debug_pdh_ok_count_value = pdh_ok_count;

        /**********************按键模块*************************/
        keys keys_model(
       
                        .clk        (clk),                                //系统时钟
                        .rst_n        (rst_n),                        //系统复位

                        //按键输入
                        .key1_in  (key1_in),
                        .key2_in  (key2_in),
                        .key3_in  (key3_in),
                        .key4_in  (key4_in),
                       
                        //按键输出
                        .key1_scan  (key1_scan),
                        .key2_scan  (key2_scan),
                        .key3_scan  (key3_scan),
                        .key4_scan  (key4_scan)               
         );


        /***********************锁定信号触发边沿检测*************************/
        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)
    );
       
        /***********************系统运行*************************/
        reg[7:0] pdh_ok_count;
        parameter pdh_ok_count_N_INIT = 8'd3;
        reg[7:0] pdh_ok_count_N;
        reg[31:0] pdh_time_count;
        parameter pdh_time_INIT = 32'd999_999;
        reg[31:0] pdh_time;        //在锯齿波为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_spare;//备份值
       
       
        parameter init_N = 14'd8;        // N 的初始范围
        reg [13:0]N;
        parameter init_K = 14'd2;        //K 的初始值
        reg [13:0]K;
       
        parameter init_DIR = 4'd1;        //扫描方向初始为正
        reg [3:0]DIR;        //扫描方向
       
       
       
        reg [31:0]time_count;
        reg [7:0]time_ones;       
       
        reg [7:0]auto_lock_state;
        reg [7:0]system_run_task_state;
       
        reg key1buf,key2buf,key3buf,key4buf;

       
        always@(posedge clk)
        begin
               
                if(!rst_n)        //低电平复位
                        begin
                                auto_lock_state<= 8'd0;
                               
                        end
                else
                        begin
                       
                                  case (auto_lock_state)       
                                                       
                                                8'd0:                        //初始化
                                                        begin               
       
                                                                dac_to_temperature_spare <= 14'd8192;        //0V
                                                                dac_to_temperature_i <= 14'd8192;        //0V
                                                                dac_ch1 <= dac_to_temperature_i;
                                                               
                                                                analog_switch_1 <= OFF;
                                                                analog_switch_2 <= OFF;
                                                                sawtooth_control <= OFF;
                                                               
                                                                time_count <= 0;
                                                                time_ones <= 0;
                                                               
                                                                key1buf <= 2'd0;        
                                                                key2buf <= 2'd0;
                                                               
                                                                auto_lock_state <= 8'd1;
                                                        end
                                  
                                                8'd1:                        //运行
                                                        begin
                                                               
                                                                dac_ch1 <= dac_to_temperature_i;       
               
                                                                //系统预热20s
                                                                if(time_count == T1S)        //1s
                                                                        begin
                                                                                time_ones <= time_ones + 1'b1;
                                                                               
                                                                                if(time_ones == T20S)        //20s
                                                                                        begin       
                                                                                                //进入正常运行模式
                                                                                                dac_to_temperature_spare <= dac_to_temperature_i;
                                                                                                time_ones <= 0;
                                                                                                time_count <= 0;
                                                                                                system_run_task_state <= 8'd0;
                                                                                                auto_lock_state <= 8'd3;
                                                                                        end
                                                                                else
                                                                                        time_count <= 0;
                                                                        end
                                                                else
                                                                        begin
                                                                                time_count <= time_count + 1'b1;
                                                                               
                                                                                //按键按下进行快速搜索
                                                                                key3buf <= key3_scan;                               
                                                                                if({key3buf,key3_scan} == 2'b10)
                                                                                        begin
                                                                                                time_ones <= 0;
                                                                                                time_count <= 0;
                                                                                                auto_lock_state <= 8'd2;
                                                                                        end
                                                                        end       
                                                                               
                                                        end
                                               
                                                8'd2:                        //快速搜索
                                                        begin
                                                       
                                                                fast_search_task();

                                                        end
                                                       
                                                8'd3:
                                                        begin                //模块运行
                                                                       
                                                                system_run_task();
                                                                       
                                                        end
                                               
                                                default:
                                                                auto_lock_state <= 8'd0;                                               
                                       
                                        endcase
                                end
        end         
       
       
                               
        //快速搜索模块的任务
        task fast_search_task();
       
                begin
               
                        key1buf <= key1_scan;                               
                        if({key1buf,key1_scan} == 2'b10 && dac_to_temperature_i < 14'd16373)        //下降沿
                                begin
                                        dac_to_temperature_i <= dac_to_temperature_i + 10;       
                                        dac_ch1 <= dac_to_temperature_i;       
                                end

                        key2buf <= key2_scan;                               
                        if({key2buf,key2_scan} == 2'b10 && dac_to_temperature_i > 14'd10)        //下降沿
                                begin
                                        dac_to_temperature_i <= dac_to_temperature_i - 10;       
                                        dac_ch1 <= dac_to_temperature_i;       
                                end
                       
                        //模块运行
                        key4buf <= key4_scan;                               
                        if({key4buf,key4_scan} == 2'b10)
                                begin
                                        dac_to_temperature_spare <= dac_to_temperature_i;
                                        system_run_task_state <= 8'd0;
                                        auto_lock_state <= 8'd3;
                                end                       
                       
                end
               
        endtask

        //系统运行任务
        task system_run_task();
                begin
                                case(system_run_task_state)
                               
                                        8'd0:                        //初始化
                                                begin

                                                                time_count <= 0;
                                                                time_ones <= 0;
                                                               
                                                                pdh_ok_count <= 8'd0;
                                                                pdh_ok_count_N <= 8'd3;
                                                               
                                                                pdh_time <= pdh_time_INIT;

                                                                pdh_ok_delay_flag <= END;
                                                               
                                                                locked_fail_count <= 8'd0;        //锁定失败计数
                                                               
                                                                analog_switch_1 <= OFF;
                                                                analog_switch_2 <= OFF;
                                                                sawtooth_control <= OFF;       
                                                               
                                                                system_run_task_state <= 8'd1;

                                                end
       
                                        8'd1:
                                                begin
                                                        //init i = 0
                                                        dac_to_temperature_i <= dac_to_temperature_spare;
                                                        N <= init_N;
                                                        K        <= init_K;               
                                                        DIR <= init_DIR;        //init 扫描方向                                                       
                                                       
                                                        system_run_task_state <= 8'd2;
                                                       
                                                end
                                               
                                        8'd2:
                                                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;
                                                        time_count <= 0;
                                                        time_ones <= 0;
                                                        system_run_task_state <= 8'd3;
                                                end
                                       
                                        8'd3:
                                                begin
                                                        //wait 4 - 10s
                                                        if(time_count == T1S)        //1s
                                                                begin
                                                                        time_ones <= time_ones + 1'b1;
                                                                       
                                                                        if(time_ones == T2S)                //2s
                                                                                begin
                                                                                        search_mode();        //扫描模式
                                                                                        dac_ch1 <= dac_to_temperature_i;        //更新数据
                                                                                        time_ones <= 0;
                                                                                end       
                                                                               
                                                                        time_count <= 0;
                                                                end
                                                        else
                                                                begin
                                                                        time_count <= time_count + 1'b1;
                                                                       
                                                                        //PDH OK?                        //判断是否找到信号
                                                                        if(pdh_ok == LOCK)
                                                                                        begin
                                                                                                pdh_ok_count <= pdh_ok_count + 1'b1;
                                                                                                pdh_ok_delay_flag <= START;        //开始延时
                                                                                                time_count <= 0;
                                                                                                time_ones <= 0;
                                                                                                pdh_time_count <= 0;
                                                                                                system_run_task_state <= 8'd4;
                                                                                        end
                                                                end
                                                end
                                               

                                        8'd4:        //PDH OK Yes
                                                begin
                                               
                                                        //锯齿波扫描延长2S
                                                        if(time_count == T1S)        //1s
                                                                begin
                                                                        time_ones <= time_ones + 1'b1;
                                                                       
                                                                                if(time_ones == T2S)        //2s
                                                                                        begin
                                                                                               
                                                                                                if(pdh_ok_count >= pdh_ok_count_N )        //真信号
                                                                                                                begin
                                                                                                                        //pdh_ok_count <= 8'd0;
                                                                                                                        pdh_time_count <= 0;
                                                                                                                        system_run_task_state <= 8'd5;        //搜索到pdh
                                                                                                                end
                                                                                                else
                                                                                                                begin
                                                                                                                        system_run_task_state <= 8'd3;        //重新扫描
                                                                                                                        pdh_ok_count <= 8'd0;
                                                                                                                end
                                                                                                               
                                                                                                time_ones <= 0;
                                                                                        end       
                                                                       
                                                                        time_count <= 32'd0;
                                                                end
                                                        else
                                                                begin
                                                                        time_count <= time_count + 1'b1;
                                                                       
                                                                        //pdh误触发处理
                                                                        //开始延时
                                                                        if(pdh_ok_delay_flag == START)
                                                                                begin
                                                                                        if(pdh_time_count == pdh_time )        //ms
                                                                                                begin
                                                                                                        pdh_time_count <= 32'd0;       
                                                                                                        pdh_ok_delay_flag <= END;
                                                                                                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
                                                end
                                       
                                        8'd5://search pdh ok
                                                begin
                                               

                                                        //stop pzt scanning
                                                        analog_switch_2 <= OFF;
                                                        //analog_switch_1 <= ON;
                                                        sawtooth_control <= OFF;
                                                       
                                                        /*
                                                        //100MS等待
                                                        if(time_count == T100MS)        //1s
                                                                begin
                                                                        system_run_task_state <= 8'd8;
                                                                        time_count <= 32'd0;
                                                                end
                                                        else
                                                                        time_count <= time_count + 1'b1;
                                                       
                                                        */                                                       
                                                end
                                       
                                        /*
                                        8'd8:
                                                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;
                                                                       
                                                        if(time_ones == T2S)        //2s
                                                                begin
                                                               
                                                                                if(locked == LOCK)                                                       
                                                                                                system_run_task_state <= 8'd11; //已锁定
                                                                                else
                                                                                                system_run_task_state <= 8'd9;        //未锁定
                                                                                       
                                                                        time_ones <= 0;
                                                                end

                                                end
                                       

                                        8'd9:        //锁入失败
                                                begin
                                                       
                                                                //锁定失败计数
                                                                locked_fail_count <= locked_fail_count + 1'b1;
                                                               
                                                                if(locked_fail_count < 8'd5)       
                                                                        begin
                                                                                system_run_task_state <= 10;
                                                                        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;
                                                                               
                                                                                system_run_task_state <= 3;

                                                                        end

                                                end

                                        8'd10:
                                                begin
                                               
                                                        analog_switch_1 <= OFF;
                                               
                                                        //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;
                                                                       
                                                        if(time_ones == T2S)        //2s
                                                                begin
                                                                        system_run_task_state <= 8;
                                                                        time_ones <= 0;
                                                                end
                                                               
                                                end
                                       

                                               
                                        //锁定状态下的运行
                                        8'd11:
                                                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
                                                       
                                                       
                                                        if(locked == UNLOCK)        //unlock
                                                                begin
                                                                       
                                                                       
                                                                        dac_to_temperature_spare <= dac_to_temperature_i;        //记录失锁值 从新扫描时从此值开始
                                                                        time_count <= 0;
                                                                        time_ones  <= 0;
                                                                        system_run_task_state <= 8'd2;  //重新进入扫描模式
                                                                       
                                                                end
                                                end
                                                */
                                               
                                                default:
                                                                system_run_task_state <= 8'd0;
                                endcase
                end       
               
        endtask
       


// 扫描模式
task search_mode;
                begin
                                //切换扫描方向
                                if(DIR == 4'd1)
                                                begin
                                               
                                                        if(dac_to_temperature_i <  (dac_to_temperature_spare + N))       
                                                                        begin
                                                                                dac_to_temperature_i <= dac_to_temperature_i + 1'b1;
                                                                        end
                                                        else
                                                                        begin
                                                                                DIR <= DIR + 1'b1;
                                                                        end
                                               
                                                end
                                else if(DIR == 4'd2)
                                                begin
                                               
                                                        if(dac_to_temperature_i >  (dac_to_temperature_spare - N))       
                                                                        begin
                                                                                dac_to_temperature_i <= dac_to_temperature_i - 1'b1;
                                                                        end
                                                        else
                                                                        begin
                                                                                DIR <= DIR + 1'b1;
                                                                        end
                                                                       
                                                end
                                else if(DIR >= 4'd3)
                                                begin
                                               
                                                        //扩大扫描范围
                                                        if(((dac_to_temperature_spare + (K * N)) < 14'd16383) && ((dac_to_temperature_spare - (K * N)) > 14'd0))
                                                                begin
                                                                        N <= (K * N);
                                                                        DIR <= init_DIR;
                                                                end
                                                        else
                                                                begin
                                                                        dac_to_temperature_spare <= 14'd8192;        //0V
                                                                        system_run_task_state <= 8'd2;        //超出范围重新扫描
                                                               
                                                                end
                                                end

                        end
endtask

endmodule


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

49

帖子

0

粉丝