qd0090 发表于 2011-3-22 18:17

请教,状态机跑飞和跑死,如何解决?

用的是xilinx的spatan 3a
发现有个状态机工作不正常:
1.当我用ont-hot编码的时候,用chipscope观察,出现全是0的现象,我在状态机的when others中也加了状态的回复,但是还是不行。
2.然后我换了gray编码,这次状态停到了“011”就不走了,而这个状态仅仅起到一个延迟作用,没有任何条件语句。


程序平时是没有问题的,大概运行300次左右就出现一次跑飞。用FPGA1年了,属于初学者,从来没有遇到过这种问题。

请教个位高手,如何解决?
以下是代码
p_reg2:process(S_Lclk,reset)
begin
if (reset='0') then
   state1<=0;
   S_ccs<='Z';
   S_ads_o<='Z';
   S_blast_o<='Z';
   S_wr_o<='Z';
   S_la_o<=(others=>'Z');
   S_command<=(others=>'Z');
   S_command_en<='1';
elsif rising_edge (S_Lclk) then
   case state1 is
         when 0 =>
             if S_PCI_usero='0' then
               S_ads_o<='1';
               state1<=1;
            else
               S_ccs<='Z';
                S_ads_o<='Z';
                S_blast_o<='Z';
                S_wr_o<='Z';
                  S_la_o<=(others=>'Z');
               S_command<=(others=>'Z');
               S_command_en<='1';
            end if;
      when 1 =>
          S_ccs<='0';
         S_ads_o<='0';
         S_wr_o<='0';
         S_la_o<=G_C8;
         state1<=2;
   when 2 =>
      S_ccs<='Z';
      S_ads_o<='1';
      S_blast_o<='0';
      state1<=3;
   when 3 =>
      S_ccs<='Z';   
      state1<=4;
    when 4=>
       if S_ready_i='0' then
         S_command<=pci_ld;
         S_command_en<='0';
         state1<=5;
      else
         null;
       end if;
   when 5=>
       state1<=6;   
   when 6 =>
       if S_PCI_usero='1' then
          S_command_en<='1';
         state1<=0;
      else
      null;
      end if;
      S_blast_o<='Z';
      S_wr_o<='Z';
      S_ads_o<='Z';
    when others =>
      state1<=0;

   end case;
else
null;
end if;
end process p_reg2;

这个进程的时钟是我用40M分频产生的(不是用DCM,就是写了个简单的分频代码,即如果上升沿A<=not A),
它即作为本进程的时钟,又作为外部PCI LOCAL总线的时钟。
其它的进程采用的是40M时钟
状态机编码类型是在ise的综合选项中选的。

[ 本帖最后由 qd0090 于 2011-3-22 20:19 编辑 ]

qd0090 发表于 2011-3-22 18:20

另外,状态机工作在低频情况下,20MHz。

xieqiang 发表于 2011-3-22 19:32

信息量太少了吧?不过其实也很好回答:状态机设计有问题!!!:loveliness:

qd0090 发表于 2011-3-22 20:16

回复 板凳 xieqiang 的帖子

已经贴上代码了,请指教!
摁了半天空格分层,但是好像没有,请讲究这看吧,呵呵

[ 本帖最后由 qd0090 于 2011-3-22 20:20 编辑 ]

夏宇闻 发表于 2011-3-22 20:57

原帖由 qd0090 于 2011-3-22 18:17 发表 https://bbs.eeworld.com.cn/images/common/back.gif
用的是xilinx的spatan 3a
发现有个状态机工作不正常:
1.当我用ont-hot编码的时候,用chipscope观察,出现全是0的现象,我在状态机的when others中也加了状态的回复,但是还是不行。
2.然后我换了gray编码,这次状 ...

两种可能:1)状态机的输入信号与本地时钟不同步,出现了冒险竞争现象,造成状态机死锁。
                   2)状态机综合后没有生成一旦进入非有效状态便立即复位,然后进入某个有效状态的电路。
解决办法:1)把外部引入的异步输入信号,做同步处理,作为本状态机的输入。
                   2)用综合指令或者约束,强行规定综合后必须生成一旦进入非有效状态便立即复位随即进入有效状态的电路。

问题回答者:夏宇闻

[ 本帖最后由 夏宇闻 于 2011-3-22 21:02 编辑 ]

qd0090 发表于 2011-3-22 21:10

回复 5楼 夏宇闻 的帖子

谢谢夏老师的热心帮助!
1)“状态机的输入信号”是指该状态机中所有用到的信号还是指该进程的敏感信号?本进程的敏感信号是用时钟同步产生的。
2)我在状态机中加入when others=> state1<=0; 即出现异常回复到初始。请问这样能行吗?不知您所说的约束在哪里设置?
呵呵,初学者基础不好,请多包涵!
各位高手有相关的资料的话请和我分享一下,多谢!

夏宇闻 发表于 2011-3-22 21:44

<div class='shownolgin' data-isdigest='no'>原帖由 qd0090 于 2011-3-22 21:10 发表 https://bbs.eeworld.com.cn/images/common/back.gif
谢谢夏老师的热心帮助!
1)“状态机的输入信号”是指该状态机中所有用到的信号还是指该进程的敏感信号?本进程的敏感信号是用时钟同步产生的。
2)我在状态机中加入when others=> state1
我所说的输入信号是指除了从当前状态反馈信号以外的信号,即从状态机外部输入的信号。
是否会产生一旦进入非有效状态立即进行强制复位的电路,并不会因为你在状态机中加入when others=> state1 综合后就一定生成这样的电路。若想生成这样的电路,必须在综合时要通过综合指令(约束)命令综合器强制生成,才会生成的。</div><script>showreplylogin();</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

qd0090 发表于 2011-3-23 08:46

<div class='shownolgin' data-isdigest='no'>请教如何才能通过综合指令(约束)命令综合器强制生成复位状态机的电路?</div><script>showreplylogin();</script>

xieqiang 发表于 2011-3-23 09:11

<div class='shownolgin' data-isdigest='no'>vhdl语言写的,我没有发言权。但有个问题也许可以聊一下。
这个进程的时钟是我用40M分频产生的。利用分频时钟去驱动,会引入多时钟域问题,常会有时序不满足的情况。我原来就遇到过。。。处理方法可以用计数器产生一个enable信号,enable有效进行操作!</div><script>showreplylogin();</script>

qd0090 发表于 2011-3-23 09:52

<div class='shownolgin' data-isdigest='no'>问题解决了!十分感谢夏老师!
就像夏老师说的一样,我将状态机中外部的信号和它的时钟进行了一下同步
p_reg2_1: process(S_Lclk)
begin
        if rising_edge(S_Lclk) then
                S_PCI_usero<=PCI_usero;
                S_ready_i<=ready;
        else
                null;
        end if;
问题就解决了!</div><script>showreplylogin();</script>

qd0090 发表于 2011-3-23 10:26

<div class='shownolgin' data-isdigest='no'>小弟刚从事电子技术1年多,刚上来接触的就是fpga;单片机,dsp什么的都没有玩过。
这一年多来学到了不少东西,也对fpga有了浓厚的兴趣,觉得fpga真的很有意思,可以做时序,可以做算法,可以嵌入Microblaze,可以嵌入DSP,而且听说xilinx以及开发了arm内核了。也就是说如果fpga玩好了,你可以做任何事情。
但是我发现fpga真是一个入门简单之极,深入了解需要下大工夫的东西。
FPGA是硬件,VHDL是硬件描述语言,但是我对什么语言对应什么硬件没有什么概念。
随着做东西的深入,这个缺点已经越来越明显了。
比如说今天的问题,我之前曾经在网上的代码中见到过对fpga外部的信号进行同步,但是我并没有重视,或者并不知道这么做的意义。
请教各位高手有没有相关的资料给我学习下?或者书籍也行。
还有,ise中的view/edit routed design(fpga editor)中可以看到语言最终生成的硬件,但是里边的模块我不知道对应什么东西,xilinx有相关的手册么?我认为写个代码,再看看生成的电路,会对我有很大帮助。
真的很想把fpga学好,我认为我也舍得下功夫学它,请各位指点!

[ 本帖最后由 qd0090 于 2011-3-23 10:49 编辑 ]</div><script>showreplylogin();</script>

eeleader 发表于 2011-3-23 11:24

<div class='shownolgin' data-isdigest='no'><P>就是亚稳态问题! 所有进入的信号需要本级时钟两次同步!</P></div><script>showreplylogin();</script>

eeleader 发表于 2011-3-23 11:25

<div class='shownolgin' data-isdigest='no'>受益非浅!夏老师厉害一下看出问题所在了!</div><script>showreplylogin();</script>

夏宇闻 发表于 2011-3-23 17:36

<div class='shownolgin' data-isdigest='no'>原帖由 qd0090 于 2011-3-23 08:46 发表 https://bbs.eeworld.com.cn/images/common/back.gif
请教如何才能通过综合指令(约束)命令综合器强制生成复位状态机的电路?
不同的综合工具所用的综合指令(或者属性 attributes)的写法是不同的。
例如QuartusII 中可在定义状态变量的寄存器之前或之后用
(* syn_encoding = "safe, one-hot " *)reg state ;Verilog 2001支持的 或者
reg state /* syn_encoding = "safe, one-hot " */ ;Verilog 1995也支持
看似注释语句的综合指令,强行命令综合器生成复位逻辑。这时,default分支项的定义才能真的起作用。我写的具体细节不一定对,您可以用Synthesis attributes做关键字在帮助搜寻中查有关细节。综合指令常用的有5-6条,一般情况下用默认的就可以了,只有非常情况下才需要使用。</div><script>showreplylogin();</script>

夏宇闻 发表于 2011-3-23 17:42

<div class='shownolgin' data-isdigest='no'>原帖由 qd0090 于 2011-3-23 10:26 发表 https://bbs.eeworld.com.cn/images/common/back.gif
小弟刚从事电子技术1年多,刚上来接触的就是fpga;单片机,dsp什么的都没有玩过。
这一年多来学到了不少东西,也对fpga有了浓厚的兴趣,觉得fpga真的很有意思,可以做时序,可以做算法,可以嵌入Microblaze,可以嵌 ...

您最好认真读一遍我编写的《Verilog数字系统设计教程》从VHDL转到 Verilog 和SystemVerilog, 这样我们之间的共同语言就更多了。如果您C语言比较熟悉的话,只需要两周就能改过来。</div><script>showreplylogin();</script>

qd0090 发表于 2011-3-23 20:54

回复 15楼 夏宇闻 的帖子

<div class='shownolgin' data-isdigest='no'>谢谢夏老师!
称呼“你”就行了,“您”不敢当啊!哈哈
我之前的工程有5000多行,另外我的工作环境基本都是vhdl,如果现在转的话可能有一些麻烦。
我之前用过一次vhdl和verilog混编,虽然没什么大的影响,但ise将我分的模块打乱了。
而且我确实有点喜欢vhdl的风格。
不过没有关系,这两种语言一定是相通的,说不定看完您的书,我就成为verilog的拥护者了,哈哈。
我只是想学好fpga,语言类型什么的,都无所谓,我不怕麻烦。
明天去当当买本您的书回来细细读读,而且我也一定会给我周围的初学者推荐您的书的!
另外夏老师觉得那本vhdl的书不错,能从硬件出发讲解语言的,能给小子推荐一本么?毕竟之前的工程以后还是需要维护的。</div><script>showreplylogin();</script>

夏宇闻 发表于 2011-3-24 18:52

<div class='shownolgin' data-isdigest='no'>原帖由 qd0090 于 2011-3-23 20:54 发表 https://bbs.eeworld.com.cn/images/common/back.gif
谢谢夏老师!
称呼“你”就行了,“您”不敢当啊!哈哈
我之前的工程有5000多行,另外我的工作环境基本都是vhdl,如果现在转的话可能有一些麻烦。
我之前用过一次vhdl和verilog混编,虽然没什么大的影响,但ise将 ...

看来您是一位勇敢的实践者,实践确实重要,但读书看资料也十分重要,两者不可偏废。VHDL熟悉了,手头的模块很多,自然可以继续下去,如果一旦熟悉了Verilog后, VHDL很快就会淡忘,毕竟Verilog语法比较简单,与C语言有许多类似处。无论用什么语言设计思想最重要,语言并不重要。伟大的作家,无论用哪国语言,只要有伟大的人道主义精神, 有人类的大爱,都可以写出伟大传世的作品,得到诺贝尔文学奖金。</div><script>showreplylogin();</script>

eeleader 发表于 2011-3-26 15:33

<div class='shownolgin' data-isdigest='no'><P>其实, 状态机跑飞,不是天灾,是人祸;&nbsp; 用状态机进行代码描述电路的时候需要注意几点:</P>
<P>&nbsp;</P>
<P>1.&nbsp; 状态机编码要用ONE-HOT 或格雷编码, 避免冒险和竞争;</P>
<P>2.&nbsp; 状态机要用FSM, 有限状态机, 不用状态需要复位;</P>
<P>3.&nbsp; 要采用三段式描述风格, 不要采用一段式描述.</P>
<P>&nbsp;</P>
<P>我想考虑上面的问题, 你的程序应该不会出问题了</P></div><script>showreplylogin();</script>

Grayz 发表于 2023-4-1 18:20

<div class='shownolgin' data-isdigest='no'><p>夏老师,各位大佬好!</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 初学CPLD的小白,有个问题困扰了好久不明所以,就是注释掉一些代码,或者添加一行代,下载到 CPLD 之后,时序就跑乱了,但代码逻辑是完全正确的,感觉像跑飞了,这种情况可能是哪里有问题</p>
</div><script>showreplylogin();</script>
页: [1]
查看完整版本: 请教,状态机跑飞和跑死,如何解决?