三段式状态机,看着很繁琐,但是用起来条理清晰,自己总结一下
第一段:状态改变
这里需要特别注意的是,第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!