Jul 18

Notes: FSM Coding Style without latch

RickySu , 19:30 , 技术经验 , 评论(0) , 引用(0) , 阅读(657) , Via 本站原创 | |
[UPDATE@2009.03.18]
谢谢HJU的留言,让我再记起这篇文章。
由于这是很早的时候写的,重新看一遍感觉我原来的理解应该还是有些问题的。
原始出错的工程已经找不到了,暂时没办法再去探究原来出错的原因到底是什么。
最近写的《有限状态机编写》一文有更多的理解,我也会再根据各位同学的留言来更新那篇文章。
这篇文章就不要参考了,下月会将它下架:)


背景:在做Blackjack Project时,做到FSM模块,由于涉及到的usersum和robotsum两个(时序的状态转换,组合的状态译码和组合的输出译码)时, usersum和robotsum形成Latch。并且map report中也显示生成门控时钟。宏观上,整个设计下载到试验板上状态机运行不正确。


分析:通过FPGA Editor查看生成门控时钟的模块,发现这种情况是由于生成了Latch,而驱动Latch的状态信号形成了门控时钟。产生这种状态的主要原因是输出译码模块是组合逻辑,没有保持功能,当需要保持一个值时,系统就自动产生了latch。由于门控时钟容易引起glitch,门控时钟控制的latch导致了usersum的不正常。

解决方法:将输出译码电路转换为时序逻辑,由时钟控制。将原来控制latch的信号转接到FF的CE端口。具体方法见示例代码。

原始代码结构:(按照ISE中的Language Templates)
   type state_type is (st1_<name_state>, st2_<name_state>, ...);
   signal state, next_state : state_type;
   --Declare internal signals for all outputs of the state machine
   signal <output>_i : std_logic;  -- example output signal
   --other outputs

--Insert the following in the architecture after the begin keyword
   SYNC_PROC: process (<clock>)
   begin
      if (<clock>'event and <clock> = '1') then
         if (<reset> = '1') then
            state <= st1_<name_state>;
            <output> <= '0';
         else
            state <= next_state;
            <output> <= <output>_i;
         -- assign other outputs to internal signals
         end if;        
      end if;
   end process;

   --MOORE State Machine - Outputs based on state only
   OUTPUT_DECODE: process (state)
   begin
      --insert statements to decode internal output signals
      --below is simple example
      if state = st3_<name> then
         <output>_i <= '1';
      else
         <output>_i <= '0';
      end if;
   end process;

   NEXT_STATE_DECODE: process (state, <input1>, <input2>, ...)
   begin
      --declare default state for next_state to avoid latches
      next_state <= state;  --default is to stay in current state
      --insert statements to decode next_state
      --below is a simple example
      case (state) is
         when st1_<name> =>
            if <input_1> = '1' then
               next_state <= st2_<name>;
            end if;
         when st2_<name> =>
            if <input_2> = '1' then
               next_state <= st3_<name>;
            end if;
         when st3_<name> =>
            next_state <= st1_<name>;
         when others =>
            next_state <= st1_<name>;
      end case;      
   end process;


修改后代码:
   SYNC_PROC: process (<clock>)
   begin
      if (<clock>'event and <clock> = '1') then
         if (<reset> = '1') then
            state <= st1_<name_state>;
            -- <output> <= '0';
            -- 第一个同步模块中去掉输出部分
         else
            state <= next_state;
            -- <output> <= <output>_i;
            -- 第一个同步模块中去掉输出部分
         end if;        
      end if;
   end process;


   OUTPUT_DECODE: process (<clock>)-- output 模块添加时序同步
   begin
      -- output 模块添加时序同步
      if rising_edge(clk) then[/color]
         --insert statements to decode internal output signals
         --below is simple example
         if state = st3_<name> then
            <output>_i <= '1';
         else
            <output>_i <= '0';
         end if;
      end if; --结束上面添加的if
   end process;
Tags: ,
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]