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

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

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date:    13:38:11 11/09/2017
  7. // Design Name:
  8. // Module Name:    auto_lock
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module auto_lock(

  22.                         input clk,                                //系统时钟
  23.                         input rst_n,                        //系统复位
  24.                         input lock_signal,        //失锁锁定输入
  25.                                                
  26.                         output reg analog_switch_1,        //模拟开关1输出
  27.                         output reg analog_switch_2,        //模拟开关2输出
  28.                         output reg [13:0] dac_ch1,                //温度dac
  29.                        
  30. //                        input sawtooth_frequence,                //锯齿波频率
  31.                         output reg sawtooth_control,        //锯齿波控制
  32.        
  33.                         input signed [15:0]adc_ch1_data,        //adc ch1电压值

  34.                         //按键输入
  35.                         input key1_in,
  36.                         input key2_in,
  37.                         input key3_in,
  38.                         input key4_in,

  39.                         //系统状态指示
  40.                         output lock_status_led,        //led
  41.                        
  42.                         //DEBUG数据
  43.                         output [23:0]debug_state_value,
  44.                         output [23:0]debug_pdh_ok_count_value
  45.     );
  46.          
  47.         parameter ON = 1'b1,OFF = 1'b0;
  48.         parameter LOCK = 1'b1,UNLOCK = 1'b0;
  49.         parameter START = 1'b1,END = 1'b0;
  50.          
  51. //        parameter T100MS = 32'd49_999_99;
  52. //        parameter T1S = 32'd49_999_999;

  53.         parameter T100MS = 32'd49;
  54.         parameter T1S = 32'd49_9;
  55.         parameter T2S = 8'd2;
  56.         parameter T5S = 8'd5;       
  57.         parameter T10S = 8'd10;
  58.         parameter T20S = 8'd20;       
  59.        
  60.         //temperture search zero point
  61.         //parameter EXPERIENCE = 14'd8540;        //经验值
  62.        
  63.         assign debug_state_value = auto_lock_state;
  64.         assign debug_pdh_ok_count_value = pdh_ok_count;

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

  70.                         //按键输入
  71.                         .key1_in  (key1_in),
  72.                         .key2_in  (key2_in),
  73.                         .key3_in  (key3_in),
  74.                         .key4_in  (key4_in),
  75.                        
  76.                         //按键输出
  77.                         .key1_scan  (key1_scan),
  78.                         .key2_scan  (key2_scan),
  79.                         .key3_scan  (key3_scan),
  80.                         .key4_scan  (key4_scan)               
  81.          );


  82.         /***********************锁定信号触发边沿检测*************************/
  83.         lock_signal_edge_check lock_signal_edge_check_model(

  84.                         .clk        (clk),                                //系统时钟
  85.                         .rst_n        (rst_n),                        //系统复位
  86.                
  87.                         .lock_signal(lock_signal),
  88.                         .locked        (locked),
  89.                         .pdh_ok        (pdh_ok),
  90.                         .lock_status_led        (lock_status_led)
  91.     );
  92.        
  93.         /***********************系统运行*************************/
  94.         reg[7:0] pdh_ok_count;
  95.         parameter pdh_ok_count_N_INIT = 8'd3;
  96.         reg[7:0] pdh_ok_count_N;
  97.         reg[31:0] pdh_time_count;
  98.         parameter pdh_time_INIT = 32'd999_999;
  99.         reg[31:0] pdh_time;        //在锯齿波为1Hz延时为20ms 频率越高锁定时间越短
  100.         reg pdh_ok_delay_flag;        //pdh延时标志
  101.        
  102.         reg [7:0]locked_fail_count;        //锁定失败计数
  103.        
  104.         reg [13:0]dac_to_temperature_i;
  105.         reg [13:0]dac_to_temperature_spare;//备份值
  106.        
  107.        
  108.         parameter init_N = 14'd8;        // N 的初始范围
  109.         reg [13:0]N;
  110.         parameter init_K = 14'd2;        //K 的初始值
  111.         reg [13:0]K;
  112.        
  113.         parameter init_DIR = 4'd1;        //扫描方向初始为正
  114.         reg [3:0]DIR;        //扫描方向
  115.        
  116.        
  117.        
  118.         reg [31:0]time_count;
  119.         reg [7:0]time_ones;       
  120.        
  121.         reg [7:0]auto_lock_state;
  122.         reg [7:0]system_run_task_state;
  123.        
  124.         reg key1buf,key2buf,key3buf,key4buf;

  125.        
  126.         always@(posedge clk)
  127.         begin
  128.                
  129.                 if(!rst_n)        //低电平复位
  130.                         begin
  131.                                 auto_lock_state<= 8'd0;
  132.                                
  133.                         end
  134.                 else
  135.                         begin
  136.                        
  137.                                   case (auto_lock_state)       
  138.                                                        
  139.                                                 8'd0:                        //初始化
  140.                                                         begin               
  141.        
  142.                                                                 dac_to_temperature_spare <= 14'd8192;        //0V
  143.                                                                 dac_to_temperature_i <= 14'd8192;        //0V
  144.                                                                 dac_ch1 <= dac_to_temperature_i;
  145.                                                                
  146.                                                                 analog_switch_1 <= OFF;
  147.                                                                 analog_switch_2 <= OFF;
  148.                                                                 sawtooth_control <= OFF;
  149.                                                                
  150.                                                                 time_count <= 0;
  151.                                                                 time_ones <= 0;
  152.                                                                
  153.                                                                 key1buf <= 2'd0;        
  154.                                                                 key2buf <= 2'd0;
  155.                                                                
  156.                                                                 auto_lock_state <= 8'd1;
  157.                                                         end
  158.                                   
  159.                                                 8'd1:                        //运行
  160.                                                         begin
  161.                                                                
  162.                                                                 dac_ch1 <= dac_to_temperature_i;       
  163.                
  164.                                                                 //系统预热20s
  165.                                                                 if(time_count == T1S)        //1s
  166.                                                                         begin
  167.                                                                                 time_ones <= time_ones + 1'b1;
  168.                                                                                
  169.                                                                                 if(time_ones == T20S)        //20s
  170.                                                                                         begin       
  171.                                                                                                 //进入正常运行模式
  172.                                                                                                 dac_to_temperature_spare <= dac_to_temperature_i;
  173.                                                                                                 time_ones <= 0;
  174.                                                                                                 time_count <= 0;
  175.                                                                                                 system_run_task_state <= 8'd0;
  176.                                                                                                 auto_lock_state <= 8'd3;
  177.                                                                                         end
  178.                                                                                 else
  179.                                                                                         time_count <= 0;
  180.                                                                         end
  181.                                                                 else
  182.                                                                         begin
  183.                                                                                 time_count <= time_count + 1'b1;
  184.                                                                                
  185.                                                                                 //按键按下进行快速搜索
  186.                                                                                 key3buf <= key3_scan;                               
  187.                                                                                 if({key3buf,key3_scan} == 2'b10)
  188.                                                                                         begin
  189.                                                                                                 time_ones <= 0;
  190.                                                                                                 time_count <= 0;
  191.                                                                                                 auto_lock_state <= 8'd2;
  192.                                                                                         end
  193.                                                                         end       
  194.                                                                                
  195.                                                         end
  196.                                                
  197.                                                 8'd2:                        //快速搜索
  198.                                                         begin
  199.                                                        
  200.                                                                 fast_search_task();

  201.                                                         end
  202.                                                        
  203.                                                 8'd3:
  204.                                                         begin                //模块运行
  205.                                                                        
  206.                                                                 system_run_task();
  207.                                                                        
  208.                                                         end
  209.                                                
  210.                                                 default:
  211.                                                                 auto_lock_state <= 8'd0;                                               
  212.                                        
  213.                                         endcase
  214.                                 end
  215.         end         
  216.        
  217.        
  218.                                
  219.         //快速搜索模块的任务
  220.         task fast_search_task();
  221.        
  222.                 begin
  223.                
  224.                         key1buf <= key1_scan;                               
  225.                         if({key1buf,key1_scan} == 2'b10 && dac_to_temperature_i < 14'd16373)        //下降沿
  226.                                 begin
  227.                                         dac_to_temperature_i <= dac_to_temperature_i + 10;       
  228.                                         dac_ch1 <= dac_to_temperature_i;       
  229.                                 end

  230.                         key2buf <= key2_scan;                               
  231.                         if({key2buf,key2_scan} == 2'b10 && dac_to_temperature_i > 14'd10)        //下降沿
  232.                                 begin
  233.                                         dac_to_temperature_i <= dac_to_temperature_i - 10;       
  234.                                         dac_ch1 <= dac_to_temperature_i;       
  235.                                 end
  236.                        
  237.                         //模块运行
  238.                         key4buf <= key4_scan;                               
  239.                         if({key4buf,key4_scan} == 2'b10)
  240.                                 begin
  241.                                         dac_to_temperature_spare <= dac_to_temperature_i;
  242.                                         system_run_task_state <= 8'd0;
  243.                                         auto_lock_state <= 8'd3;
  244.                                 end                       
  245.                        
  246.                 end
  247.                
  248.         endtask

  249.         //系统运行任务
  250.         task system_run_task();
  251.                 begin
  252.                                 case(system_run_task_state)
  253.                                
  254.                                         8'd0:                        //初始化
  255.                                                 begin

  256.                                                                 time_count <= 0;
  257.                                                                 time_ones <= 0;
  258.                                                                
  259.                                                                 pdh_ok_count <= 8'd0;
  260.                                                                 pdh_ok_count_N <= 8'd3;
  261.                                                                
  262.                                                                 pdh_time <= pdh_time_INIT;

  263.                                                                 pdh_ok_delay_flag <= END;
  264.                                                                
  265.                                                                 locked_fail_count <= 8'd0;        //锁定失败计数
  266.                                                                
  267.                                                                 analog_switch_1 <= OFF;
  268.                                                                 analog_switch_2 <= OFF;
  269.                                                                 sawtooth_control <= OFF;       
  270.                                                                
  271.                                                                 system_run_task_state <= 8'd1;

  272.                                                 end
  273.        
  274.                                         8'd1:
  275.                                                 begin
  276.                                                         //init i = 0
  277.                                                         dac_to_temperature_i <= dac_to_temperature_spare;
  278.                                                         N <= init_N;
  279.                                                         K        <= init_K;               
  280.                                                         DIR <= init_DIR;        //init 扫描方向                                                       
  281.                                                        
  282.                                                         system_run_task_state <= 8'd2;
  283.                                                        
  284.                                                 end
  285.                                                
  286.                                         8'd2:
  287.                                                 begin
  288.                                                         //start pzt scanning
  289.                                                         analog_switch_1 <= OFF;
  290.                                                         analog_switch_2 <= ON;
  291.                                                        
  292.                                                         //开启锯齿波扫描
  293.                                                         sawtooth_control <= ON;       
  294.                                                        
  295.                                                         //T(i) = V * step * i;
  296.                                                         dac_ch1 <= dac_to_temperature_i;
  297.                                                         time_count <= 0;
  298.                                                         time_ones <= 0;
  299.                                                         system_run_task_state <= 8'd3;
  300.                                                 end
  301.                                        
  302.                                         8'd3:
  303.                                                 begin
  304.                                                         //wait 4 - 10s
  305.                                                         if(time_count == T1S)        //1s
  306.                                                                 begin
  307.                                                                         time_ones <= time_ones + 1'b1;
  308.                                                                        
  309.                                                                         if(time_ones == T2S)                //2s
  310.                                                                                 begin
  311.                                                                                         search_mode();        //扫描模式
  312.                                                                                         dac_ch1 <= dac_to_temperature_i;        //更新数据
  313.                                                                                         time_ones <= 0;
  314.                                                                                 end       
  315.                                                                                
  316.                                                                         time_count <= 0;
  317.                                                                 end
  318.                                                         else
  319.                                                                 begin
  320.                                                                         time_count <= time_count + 1'b1;
  321.                                                                        
  322.                                                                         //PDH OK?                        //判断是否找到信号
  323.                                                                         if(pdh_ok == LOCK)
  324.                                                                                         begin
  325.                                                                                                 pdh_ok_count <= pdh_ok_count + 1'b1;
  326.                                                                                                 pdh_ok_delay_flag <= START;        //开始延时
  327.                                                                                                 time_count <= 0;
  328.                                                                                                 time_ones <= 0;
  329.                                                                                                 pdh_time_count <= 0;
  330.                                                                                                 system_run_task_state <= 8'd4;
  331.                                                                                         end
  332.                                                                 end
  333.                                                 end
  334.                                                

  335.                                         8'd4:        //PDH OK Yes
  336.                                                 begin
  337.                                                
  338.                                                         //锯齿波扫描延长2S
  339.                                                         if(time_count == T1S)        //1s
  340.                                                                 begin
  341.                                                                         time_ones <= time_ones + 1'b1;
  342.                                                                        
  343.                                                                                 if(time_ones == T2S)        //2s
  344.                                                                                         begin
  345.                                                                                                
  346.                                                                                                 if(pdh_ok_count >= pdh_ok_count_N )        //真信号
  347.                                                                                                                 begin
  348.                                                                                                                         //pdh_ok_count <= 8'd0;
  349.                                                                                                                         pdh_time_count <= 0;
  350.                                                                                                                         system_run_task_state <= 8'd5;        //搜索到pdh
  351.                                                                                                                 end
  352.                                                                                                 else
  353.                                                                                                                 begin
  354.                                                                                                                         system_run_task_state <= 8'd3;        //重新扫描
  355.                                                                                                                         pdh_ok_count <= 8'd0;
  356.                                                                                                                 end
  357.                                                                                                                
  358.                                                                                                 time_ones <= 0;
  359.                                                                                         end       
  360.                                                                        
  361.                                                                         time_count <= 32'd0;
  362.                                                                 end
  363.                                                         else
  364.                                                                 begin
  365.                                                                         time_count <= time_count + 1'b1;
  366.                                                                        
  367.                                                                         //pdh误触发处理
  368.                                                                         //开始延时
  369.                                                                         if(pdh_ok_delay_flag == START)
  370.                                                                                 begin
  371.                                                                                         if(pdh_time_count == pdh_time )        //ms
  372.                                                                                                 begin
  373.                                                                                                         pdh_time_count <= 32'd0;       
  374.                                                                                                         pdh_ok_delay_flag <= END;
  375.                                                                                                 end
  376.                                                                                         else
  377.                                                                                                         pdh_time_count <= pdh_time_count + 1'b1;
  378.                                                                                 end
  379.                                                                         else
  380.                                                                                 begin
  381.                                                                                         if(pdh_ok == LOCK)
  382.                                                                                                 begin
  383.                                                                                                         pdh_ok_count <= pdh_ok_count + 1'b1;
  384.                                                                                                         pdh_ok_delay_flag <= START;                                                                       
  385.                                                                                                 end
  386.                                                                                 end
  387.                                                                         end
  388.                                                 end
  389.                                        
  390.                                         8'd5://search pdh ok
  391.                                                 begin
  392.                                                

  393.                                                         //stop pzt scanning
  394.                                                         analog_switch_2 <= OFF;
  395.                                                         //analog_switch_1 <= ON;
  396.                                                         sawtooth_control <= OFF;
  397.                                                        
  398.                                                         /*
  399.                                                         //100MS等待
  400.                                                         if(time_count == T100MS)        //1s
  401.                                                                 begin
  402.                                                                         system_run_task_state <= 8'd8;
  403.                                                                         time_count <= 32'd0;
  404.                                                                 end
  405.                                                         else
  406.                                                                         time_count <= time_count + 1'b1;
  407.                                                        
  408.                                                         */                                                       
  409.                                                 end
  410.                                        
  411.                                         /*
  412.                                         8'd8:
  413.                                                 begin
  414.                                                
  415.                                                         //锁入过程
  416.                                                         //analog_switch_2 <= OFF;
  417.                                                         analog_switch_1 <= ON;
  418.                                                
  419.                                                         //2S判断一次
  420.                                                         if(time_count == T1S)        //1s
  421.                                                                 begin
  422.                                                                         time_ones <= time_ones + 1'b1;
  423.                                                                         time_count <= 32'd0;
  424.                                                                 end
  425.                                                         else
  426.                                                                         time_count <= time_count + 1'b1;
  427.                                                                        
  428.                                                         if(time_ones == T2S)        //2s
  429.                                                                 begin
  430.                                                                
  431.                                                                                 if(locked == LOCK)                                                       
  432.                                                                                                 system_run_task_state <= 8'd11; //已锁定
  433.                                                                                 else
  434.                                                                                                 system_run_task_state <= 8'd9;        //未锁定
  435.                                                                                        
  436.                                                                         time_ones <= 0;
  437.                                                                 end

  438.                                                 end
  439.                                        

  440.                                         8'd9:        //锁入失败
  441.                                                 begin
  442.                                                        
  443.                                                                 //锁定失败计数
  444.                                                                 locked_fail_count <= locked_fail_count + 1'b1;
  445.                                                                
  446.                                                                 if(locked_fail_count < 8'd5)       
  447.                                                                         begin
  448.                                                                                 system_run_task_state <= 10;
  449.                                                                         end
  450.                                                                 else
  451.                                                                         begin
  452.                                                                                 if(dac_to_temperature_i > 14'd0)
  453.                                                                                         dac_to_temperature_i <= dac_to_temperature_i - 1'b1;
  454.                                                                        
  455.                                                                                 analog_switch_1 <= OFF;
  456.                                                                                 analog_switch_2 <= ON;       
  457.                                                                                
  458.                                                                                 locked_fail_count <= 8'd0;
  459.                                                                                
  460.                                                                                 system_run_task_state <= 3;

  461.                                                                         end

  462.                                                 end

  463.                                         8'd10:
  464.                                                 begin
  465.                                                
  466.                                                         analog_switch_1 <= OFF;
  467.                                                
  468.                                                         //2S判断一次
  469.                                                         if(time_count == T1S)        //1s
  470.                                                                 begin
  471.                                                                         time_ones <= time_ones + 1'b1;
  472.                                                                         time_count <= 32'd0;
  473.                                                                 end
  474.                                                         else
  475.                                                                         time_count <= time_count + 1'b1;
  476.                                                                        
  477.                                                         if(time_ones == T2S)        //2s
  478.                                                                 begin
  479.                                                                         system_run_task_state <= 8;
  480.                                                                         time_ones <= 0;
  481.                                                                 end
  482.                                                                
  483.                                                 end
  484.                                        

  485.                                                
  486.                                         //锁定状态下的运行
  487.                                         8'd11:
  488.                                                 begin

  489.                                                         //5S判断一次
  490.                                                         if(time_count == T1S)        //1s
  491.                                                                 begin
  492.                                                                         time_ones <= time_ones + 1'b1;
  493.                                                                         time_count <= 32'd0;
  494.                                                                 end
  495.                                                         else
  496.                                                                         time_count <= time_count + 1'b1;
  497.                                                                        
  498.                                                         if(time_ones == T5S)        //5s
  499.                                                                 begin
  500.                                                                
  501.                                                                         //电压 > 1 并且 处于锁定状态
  502.                                                                         if(adc_ch1_data > 16'sd6553 && dac_to_temperature_i < 14'd16383 && locked == LOCK)
  503.                                                                                 begin
  504.                                                                                         dac_to_temperature_i <= dac_to_temperature_i - 1;
  505.                                                                                 end               
  506.                                                                         else if(adc_ch1_data < -16'sd6553 && dac_to_temperature_i > 14'd0 && locked == LOCK)
  507.                                                                                 begin
  508.                                                                                         dac_to_temperature_i <= dac_to_temperature_i + 1;
  509.                                                                                 end               
  510.                                                                                
  511.                                                                         //T(i) = V * step * i;
  512.                                                                         dac_ch1 <= dac_to_temperature_i;       
  513.                
  514.                                                                         time_ones <= 0;
  515.                                                                        
  516.                                                                 end
  517.                                                        
  518.                                                        
  519.                                                         if(locked == UNLOCK)        //unlock
  520.                                                                 begin
  521.                                                                        
  522.                                                                        
  523.                                                                         dac_to_temperature_spare <= dac_to_temperature_i;        //记录失锁值 从新扫描时从此值开始
  524.                                                                         time_count <= 0;
  525.                                                                         time_ones  <= 0;
  526.                                                                         system_run_task_state <= 8'd2;  //重新进入扫描模式
  527.                                                                        
  528.                                                                 end
  529.                                                 end
  530.                                                 */
  531.                                                
  532.                                                 default:
  533.                                                                 system_run_task_state <= 8'd0;
  534.                                 endcase
  535.                 end       
  536.                
  537.         endtask
  538.        


  539. // 扫描模式
  540. task search_mode;
  541.                 begin
  542.                                 //切换扫描方向
  543.                                 if(DIR == 4'd1)
  544.                                                 begin
  545.                                                
  546.                                                         if(dac_to_temperature_i <  (dac_to_temperature_spare + N))       
  547.                                                                         begin
  548.                                                                                 dac_to_temperature_i <= dac_to_temperature_i + 1'b1;
  549.                                                                         end
  550.                                                         else
  551.                                                                         begin
  552.                                                                                 DIR <= DIR + 1'b1;
  553.                                                                         end
  554.                                                
  555.                                                 end
  556.                                 else if(DIR == 4'd2)
  557.                                                 begin
  558.                                                
  559.                                                         if(dac_to_temperature_i >  (dac_to_temperature_spare - N))       
  560.                                                                         begin
  561.                                                                                 dac_to_temperature_i <= dac_to_temperature_i - 1'b1;
  562.                                                                         end
  563.                                                         else
  564.                                                                         begin
  565.                                                                                 DIR <= DIR + 1'b1;
  566.                                                                         end
  567.                                                                        
  568.                                                 end
  569.                                 else if(DIR >= 4'd3)
  570.                                                 begin
  571.                                                
  572.                                                         //扩大扫描范围
  573.                                                         if(((dac_to_temperature_spare + (K * N)) < 14'd16383) && ((dac_to_temperature_spare - (K * N)) > 14'd0))
  574.                                                                 begin
  575.                                                                         N <= (K * N);
  576.                                                                         DIR <= init_DIR;
  577.                                                                 end
  578.                                                         else
  579.                                                                 begin
  580.                                                                         dac_to_temperature_spare <= 14'd8192;        //0V
  581.                                                                         system_run_task_state <= 8'd2;        //超出范围重新扫描
  582.                                                                
  583.                                                                 end
  584.                                                 end

  585.                         end
  586. endtask

  587. endmodule


您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

49

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部