三段式狀態機,看着很繁瑣,但是用起來條理清晰,自己總結一下
第一段:狀態改變
這里需要特別注意的是,第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!