自己写的三段式状态机程序,有点问题,请教

[复制链接]
3379|16
 楼主| jlgcumt 发表于 2013-3-12 23:49 | 显示全部楼层 |阅读模式
本帖最后由 jlgcumt 于 2013-3-12 23:56 编辑
  1. //////////////////////////////////FSM///////////////////////////////////////
  2. // 状态转换
  3. always @ (posedge sys_clk or negedge rst_n)
  4. begin
  5.         if(!rst_n)
  6.                 cstate_ad <= 0;
  7.         else
  8.                 cstate_ad <= nstate_ad;        
  9. end

  10. // 下一状态生成
  11. always @ (*)
  12. begin
  13.         if(!rst_n)
  14.                 begin
  15.                 nstate_ad = 0;               
  16.                 end
  17.         else
  18.                 begin
  19.                 case(cstate_ad)
  20.                 4'd0:                                // 判断当前ad是否使能,使能的话进入下一状态开始启动采集
  21.                         begin
  22.                         if(ADEn)
  23.                                 nstate_ad = 4'd1;
  24.                         else
  25.                                 nstate_ad = 4'd0;                        
  26.                         end
  27.                 4'd1:           // 此状态和下一状态用于AD7606采集的转换启动信号
  28.                         begin
  29.                         nstate_ad = 4'd2;                        
  30.                         end
  31.                 4'd2:                                
  32.                         begin
  33.                         nstate_ad = 4'd3;                                
  34.                         end
  35.                 4'd3:                                 // 等待125ns,在启动信号和Busy信号有效之间延时最大为40ns(手册要求)
  36.                         begin
  37.                         nstate_ad = 4'd4;                        
  38.                         end
  39.                 4'd4:
  40.                         begin
  41.                         nstate_ad = 4'd5;                        
  42.                         end
  43.                 4'd5:
  44.                         if(ad_busy)  // 转换正在进行中  
  45.                                 begin
  46.                                         nstate_ad = 4'd5;
  47.                                 end                        
  48.                         else                         // 转换完成
  49.                                 begin
  50.                                         nstate_ad = 4'd6;
  51.                                 end
  52.                 4'd6:           // 开始采集
  53.                         begin
  54.                         if(ADSampNum < 4 )   // 当前8个通道采集值都已经读出来,进行下一次的采集
  55.                                 begin                                       
  56.                                 nstate_ad = 4'd7;        
  57.                                 end
  58.                         else              // 当前正在读取采集结果
  59.                                 begin                                       
  60.                                 nstate_ad = 4'd0;                                
  61.                                 end                        
  62.                         end
  63.                 4'd7:                                                        // 启动SPI读取时钟
  64.                         begin
  65.                         nstate_ad = 4'd8;                                
  66.                         end
  67.                 4'd8:
  68.                         begin
  69.                         nstate_ad = 4'd9;        
  70.                         end
  71.                 4'd9:                                                        // 多延时一次确保延时计数器已经开始工作
  72.                         begin
  73.                         nstate_ad = 4'd10;
  74.                         end
  75.                 4'd10:
  76.                         begin
  77.                         if(ADDelay_Cnt > 10)    //  延时时间到
  78.                                 begin
  79.                                 nstate_ad = 4'd11;
  80.                                 end
  81.                         else                                                        //  延时时间还没到,等待中
  82.                                 begin
  83.                                 nstate_ad = 4'd10;
  84.                                 end                        
  85.                         end
  86.                 4'd11:
  87.                         begin
  88.                         if(AD_FSM_State)        //
  89.                                 begin
  90.                                 nstate_ad = 4'd11;   
  91.                                 end                        
  92.                         else
  93.                                 begin
  94.                                 nstate_ad = 4'd12;   //
  95.                                 end
  96.                         end
  97.                 4'd12:                                                        // 将读到的数据记录下来
  98.                         begin
  99.                         nstate_ad = 4'd13;
  100.                         end
  101.                 4'd13:                     // 读取通道索引值加1,读取下一通道值
  102.                         begin
  103.                         nstate_ad = 4'd6;
  104.                         end
  105. //                default:nstate_ad = 4'd0;
  106.                 default: nstate_ad = 4'd0;
  107.                 endcase        
  108.                
  109.                 end
  110. end


  111. // 输出值实现
  112. always @(posedge sys_clk or negedge rst_n)
  113. begin
  114.         if(!rst_n)
  115.                 begin               
  116.                 ADStart <= 0;
  117.                 ad_convsta <= 1;
  118.                 ADSampNum <= 0;
  119.                 ad_samp_value[0][15:0] <= 0;
  120.                 ad_samp_value[1][15:0] <= 0;
  121.                 ad_samp_value[2][15:0] <= 0;
  122.                 ad_samp_value[3][15:0] <= 0;
  123.                 ad_samp_value[4][15:0] <= 0;
  124.                 ad_samp_value[5][15:0] <= 0;
  125.                 ad_samp_value[6][15:0] <= 0;
  126.                 ad_samp_value[7][15:0] <= 0;               
  127.                 end
  128.         else
  129.                 begin
  130.                 case(cstate_ad)
  131.                 4'd0:
  132.                         begin
  133.                         ad_convsta <= 1;
  134.                         ADSampNum <= 0;
  135.                         end
  136.                 4'd1:                   // ad_convsta拉低62.5ns,大于手册要求的最小25ns的要求
  137.                         begin
  138.                         ad_convsta <= 0;
  139.                         end
  140.                 4'd2:
  141.                         begin
  142.                         ad_convsta <= 1;
  143.                         end
  144.                 4'd3:
  145.                         begin
  146.                         ;
  147.                         end
  148.                 4'd4:
  149.                         begin                        
  150.                         ;
  151.                         end
  152.                 4'd5:
  153.                         begin
  154.                         ;
  155.                         end
  156.                 4'd6:
  157.                         begin
  158.                         ;
  159.                         end
  160.                 4'd7:                   //  启动SPI时钟
  161.                         begin
  162.                         ADStart <= 1;
  163.                         end
  164.                 4'd8:
  165.                         begin
  166.                         ADStart <= 0;
  167.                         end               
  168.                 4'd9:
  169.                         begin
  170.                         ;
  171.                         end               
  172.                 4'd10:
  173.                         begin
  174.                         ;
  175.                         end
  176.                 4'd11:
  177.                         begin
  178.                         ;
  179.                         end
  180.                 4'd12:
  181.                         begin
  182.                         ad_samp_value[ADSampNum][15:0] <= ad_samp_value_current_a[15:0];
  183.                         ad_samp_value[ADSampNum+4][15:0] <= ad_samp_value_current_b[15:0];
  184.                         
  185.                         end
  186.                 4'd13:
  187.                         begin
  188.                         ADSampNum <= ADSampNum +1;
  189.                         end
  190.                 default:  ;               
  191.                
  192.                
  193.                 endcase
  194.                 end
  195. end


  196. // 延时计数器
  197. reg [4:0] ADDelay_Cnt;
  198. always @(posedge sys_clk or negedge rst_n)
  199. begin
  200.         if(!rst_n)
  201.                 begin               
  202.                 ADDelay_Cnt <= 0;
  203.                 end
  204.         else
  205.                 begin               
  206.                 if(ADStart)
  207.                         ADDelay_Cnt <= 0;
  208.                 else
  209.                         begin                        
  210.                         if( ADDelay_Cnt < 5'd21)
  211.                                 ADDelay_Cnt <= ADDelay_Cnt + 1;
  212.                         else
  213.                                 ADDelay_Cnt <= ADDelay_Cnt;                        
  214.                         end                        
  215.                 end

  216. end

  217. //读取采样结果例化
  218. ADSPI_RX ADRX(.clk_div(clk_div),.rst_n(rst_n),.spi_clk(ad_sclk),.ad_start(ADStart),.spi_en(ADEn),.spi_miso_a(ad_miso_a),.spi_miso_b(ad_miso_b),.spi_ncs(ad_cs_n),
  219.                                   .rx_value_a(ad_samp_value_current_a[15:0]),.rx_value_b(ad_samp_value_current_b[15:0]),.spi_state(AD_FSM_State));
 楼主| jlgcumt 发表于 2013-3-12 23:54 | 显示全部楼层
程序比较简单,是一个AD的采集控制程序,现在有个问题是,在状态6的时候跳变不对,本来跑到6的时候,判断ADSampNum这个值进行状态切换,当把程序烧到板子上时发现ADSampNum值倒是增加了,就是在6的时候老跑到0,虽然我写的是ADSampNum<4要跑到7,请问是怎么回事?
 楼主| jlgcumt 发表于 2013-3-13 10:12 | 显示全部楼层
今天早上一醒来,发现问题的原因,解决,结贴了!
zhangxq4633 发表于 2013-3-13 11:13 | 显示全部楼层
接分啦...
duoduo1989 发表于 2013-3-13 11:24 | 显示全部楼层
楼主这是睡一觉就豁然开朗了咩
 楼主| jlgcumt 发表于 2013-3-13 14:25 | 显示全部楼层
等人多了散分!
mmhhkk 发表于 2013-3-13 14:34 | 显示全部楼层
怎么解决的分享一下啊
magic_yuan 发表于 2013-3-13 14:37 | 显示全部楼层
楼主牛X啊,这么长的程序。。。。
GoldSunMonkey 发表于 2013-3-13 15:50 | 显示全部楼层
magic_yuan 发表于 2013-3-13 14:37
楼主牛X啊,这么长的程序。。。。

必须的
 楼主| jlgcumt 发表于 2013-3-13 21:01 | 显示全部楼层
mmhhkk 发表于 2013-3-13 14:34
怎么解决的分享一下啊

是跟下面例化的模块有一个信号没配合好(子模块没捕捉到这个信号),两个用不同的时钟在工作,刚开始没注意到!
 楼主| jlgcumt 发表于 2013-3-13 21:03 | 显示全部楼层
magic_yuan 发表于 2013-3-13 14:37
楼主牛X啊,这么长的程序。。。。

我也是初学者,三段式状态机还是第一次写,哈哈,modelsim还没学会呢,要不然仿真一下估计就能找出问题了,现在全是我自己的脑子在做仿真!
qin552011373 发表于 2013-3-13 21:51 | 显示全部楼层
好牛啊
GoldSunMonkey 发表于 2013-3-13 22:32 | 显示全部楼层
qin552011373 发表于 2013-3-13 21:51
好牛啊

你更牛啊
lark100 发表于 2013-3-14 00:29 | 显示全部楼层
有软件天赋!!!
magic_yuan 发表于 2013-3-14 10:28 | 显示全部楼层
jlgcumt 发表于 2013-3-13 21:03
我也是初学者,三段式状态机还是第一次写,哈哈,modelsim还没学会呢,要不然仿真一下估计就能找出问题了 ...

我在搞modelsim。简单仿真。呵呵,多像你学习了。
GoldSunMonkey 发表于 2013-3-14 19:36 | 显示全部楼层
magic_yuan 发表于 2013-3-14 10:28
我在搞modelsim。简单仿真。呵呵,多像你学习了。

欢迎常来啊
xjsxjtu 发表于 2013-3-14 20:01 | 显示全部楼层
嗯,不错啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:善攻者,动于九天之上,善守者,藏于九地之下!

183

主题

733

帖子

4

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