關於三段式狀態機(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!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM