关于三段式状态机(VHDL)的写法心得和问题

三段式状态机,看着很繁琐,但是用起来条理清晰,自己总结一下

第一段:状态改变

这里需要特别注意的是,第5行,状态变化的时候,必须要使用时钟沿,上升或下降,不能在两个沿都变化,虽然这样仿真正确,但是下载到硬件中无效,状态不会变化

 

 

 

   1: process(clk,rst_n)
   2: begin
   3:     if(rst_n = '0') then
   4:         current_state <= s_wait;
   5:     elsif rising_edge(clk) then
   6:         current_state <= next_state;
   7:     end if;
   8: end process state_change;

 

 

 

第二段:状态转化

这一段注意:

敏感列表是current_state和process中涉及到变化的所有信号

在case xxx is 前面初始化 next_state <= s_wait; 这样就不用在下面状态中关心这个状态了

最后要写 when others => 空,据说是避免综合出锁存器,现在还不理解

   1: process(current_state,Rxd_ready,Small_fifo_full,Small_fifo_empty,Txd_busy,Larger_fifo_empty)
   2: begin
   3:     next_state <= s_wait; --初始化
   4:     
   5:     case current_state is
   6:     when s_wait =>
   7:         if(receive_mode = '1') then 
   8:             if (Small_fifo_full = '1') then next_state <= lff_pop1;
   9:             elsif (Rxd_ready = '1') then next_state <= lff_save1;end if;
  10:             ....
  11:  
  12:     -------------------------------------------------
  13:     when lff_save1 =>    next_state <= lff_save2;
  14:     when lff_save2 =>    next_state <= lff_save3;
  15:     when lff_save3 =>    
  16:         if(Rxd_ready = '1') then next_state <= lff_save3;
  17:         else next_state <= s_wait; end if;
  18:     when lff_pop1         => next_state <= lff_pop2;
  19:     when lff_pop2         => next_state <= lff_pop3;
  20:     when lff_pop3         => next_state <= lff_pop4;    
  21:     when lff_pop4         => 
  22:         if(Small_fifo_empty = '1') then     next_state <= lff_pop5;
  23:         else next_state <= lff_pop3; end if;
  24:     when lff_pop5         => next_state <= s_wait;
  25:     --------------------------------------------------
  26:     when sd_s1 =>    next_state <= sd_s2;
  27:     when sd_s2 =>    next_state <= sd_s3;
  28:     ....
  29:     when others => next_state <= s_wait;
  30:     
  31:     end case;
  32: end process;

 

第三段:信号变化

这段注意:

敏感信号只有clk,而且必须是clk的沿来另状态信号改变

一样的,在case之前,将所涉及到变化的信号都初始化了,在下面每个状态,将变化的信号写在每个状态里,要不然仿真会通过,但是实际在signalTAP中观察到的,有些信号在状态变化的时候,如果不固定了他的值,会有可能变化,很奇怪.

   1: process(clk)
   2: begin
   3: if rising_edge(clk) then
   4:     --信号初始化
   5:     ce_n <= '1';
   6:     cle  <= '0';
   7:     ale  <= '0';
   8:     we_n <= '1';
   9:     re_n <= '1';        
  10:     write_ready <= '0';
  11:     read_ready  <= '0';
  12:     f_io <= (others => 'Z');
  13:     
  14:     case(next_state) is
  15:     when f_wait =>
  16:             
  17:     when f_cmd_start_1 =>
  18:         ce_n <= '0';
  19:         cle  <= '1';
  20:         we_n <= '0';
  21:     ....
  22:  
  23:     when others =>
  24:     end case;
  25: end.......

over!

posted @ 2013-05-19 10:05  Freezing_  阅读(12330)  评论(0编辑  收藏  举报