September 21, 2016
作者:dengshuai_super
出處:http://blog.csdn.net/dengshuai_super/article/details/52571372
聲明:轉載請註明作者及出處。
同步有限狀態機的設計
1. 什麼是有限狀態機(FSM)
在FPGA裏面做有限狀態機的原因:因爲FPGA都是並行處理的,想要做一些有前後順序的事件處理的時候,我們就引入這種狀態的機制。因此狀態機在FPGA裏面應用這麼廣。
在軟件裏面也是有狀態機的思想,但是軟件它是一個順序執行的方法,所以狀態機的存在顯得不是那麼重要了。
有限狀態機是由寄存器組和組合邏輯構成的硬件時序電路;
其狀態(即由寄存器組的1和0的組合狀態所構成的有限個狀態)只能在同一時鐘跳變沿的情況下才能從一個狀態轉向另一個狀態;
究竟轉向哪一狀態不但取決於各個輸入值,還取決於當前狀態。
狀態機可用於產生在時鐘跳變沿時刻開關的複雜的控制邏輯,是數字邏輯的控制核心。
2. FSM的種類和不同點
Mealy狀態機:
帶流水線輸出的Mealy狀態機:
有限狀態機框圖如下:
3. 設計舉例
根據上圖代碼實現:
//ex_fsm.v
module ex_fsm(
input wire sclk,
input wire rst_n,
output reg k1,//輸出的時候可以作爲寄存器,它相當於把輸出寄存器的
output reg k2,//Q端直接連接到輸出口了,就把中間那根線給省略了
input wire A//狀態
);
parameter IDLE = 4'b0001;//4'h1十六進制,狀態少的時候最好顯示的寫出狀態表達式
parameter START = 4'b0010;
parameter STOP = 4'b0100;
parameter CLEAR = 4'b1000;
//reg [1:0] state;
//2'b00 2'b01 2'b10 2'b11,二進制編碼的時候用的寄存器數量少,但是用的組合邏輯資源較多
//if(state == 2'b11)比較器是2比特的
reg [3:0] state;
//4'b0001 4'b0010 4'b0100 4'b1000 獨熱碼佔用寄存器數量多,但是組合邏輯資源消耗較少
//if(state == 4'b0001)---->if(state[0]==1'b1)綜合後把4比特的比較器優化成1比特的比較器,所以佔用的組合邏輯資源較少
//對於二進制編碼(多個比特表示一個狀態),比特線有可能不一樣長,導致延遲,出現中間狀態,本來應該是111,可能中間狀態是110等,(兩邊交錯不穩定,使得數據存在不穩定區)因此在跑高速的時候可能出現數據採樣窗變小,使得建立時間、保持時間的餘量減少
//而獨熱碼就不會出現這個問題,因爲它用一個比特表示一個狀態,從出發到結束就是一根線,不會出現中間狀態,可以跑高速。
//兩段式描述狀態機
//第一段描述狀態機,(狀態機是時序邏輯)
always @(posedge sclk or negedge rst_n)//只對狀態進行處理,不會寫入其他變量賦值
if(rst_n == 1'b0)
state<=IDLE;//非阻塞賦值
else
case(state)
IDLE:if(A==1'b1)
state <=START;//時序電路,不加else自動保持原狀態,因此可以不寫
//else
//state <=state;
START:if(A==1'b0)
state <= STOP;//復位的時候回到IDLE,最上邊的if那有相關代碼
STOP:if(A==1'b1)
state <= CLEAR;
CLEAR:if(A==1'b0)
state <= IDLE;
default:state <= IDLE;
endcase
//控制變量輸出
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
k1 <= 1'b0;
else if(state == IDLE && A == 1'b1)
k1 <= 1'b0;
else if(state == CLEAR && A == 1'b0)
k1 <= 1'b1;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
k2 <= 1'b0;
else if(state ==STOP && A == 1'b1)
k2 <= 1'b1;
else if(state ==CLEAR && A == 1'b0)
k2 <= 1'b0;
endmodule
//tb_ex3_fsm.v
`timescale 1ns/1ns
module tb_ex3_fsm;
reg sclk,rst_n;
reg in_A;
wire k1,k2;
initial begin
sclk <= 0;
rst_n <= 0;
#100;
rst_n <=1;
end
initial begin
#200;
in_data();
end
always #10 sclk <=~sclk;
ex_fsm ex_fsm_inst(
.sclk (sclk),
.rst_n (rst_n),
.k1 (k1),//k1我上邊沒聲明,但是綜合的時候自動聲明一個wire變量,不推薦
.k2 (k2),//k1,k2是輸出,芯片畫PCB時,輸出的管腳都用線連
.A (in_A)//狀態
);
task in_data();
integer i;
begin
for(i=0;i<1024;i=i+1)
begin
@(posedge sclk);
if(i<50)
in_A<=0;
else if(i<200)
in_A<=1;
else if(i<700)
in_A<=0;
else if(i<800)
in_A<=1;
else if(i<900)
in_A<=0;
end
end
endtask
endmodule
在Quartus II裏面進行仿真設置後,點擊EDA Netlist Writer後
在ex3/quartus_prj 裏面多了一個Simulation文件夾,文件夾下有modelsim文件夾
該文件夾下有:
ex_fsm.sft
ex_fsm.vo//標準網標
ex_fsm_7_1200mv_125c_slow.vo//”125”指的是125度,分析建立時間,因爲只有在信號傳輸地太慢了
ex_fsm_7_1200mv_125c_slow.sdo//,路徑延時太大了的時候,纔會建立時間的違例
ex_fsm_min_1200mv_-40c_fast.vo//用於建立時間的檢查,數據傳輸的太快,使得數據太快的到達
ex_fsm_min_1200mv_-40c_v_fast.sdo//當上升沿之後,數據很快的結束了,沒有辦法保持住,因此用它來檢查保持時間
ex_fsm_modelsim.xrf
ex_fsm_v.sdo//標準延時文件
//ex_fsm.vo裏面調用了ex_fsm_v.sdo文件(initial $sdf_annotate(“ex_fsm_sdo”);)
//將ex_fsm_v.sdo放到ex_3/sim下(.sdo文件一定放到根目錄,要不然找不到,就沒有延時信息)
//將ex_fsm.vo放到ex_3/design下
//仿真的時候,ex_fsm.vo裏面調用了Altera FPGA裏面的東西。因此需要加進來一些庫文件。
//庫文件在哪裏找:打開Quartus II安裝目錄下:QuartusII13.1/quartus/eda/sim_lib下把alter_mf.v拷貝到ex_3/sim目錄下的新建的文件夾altera_lib下。
打開modelsim,在Project標籤頁下把ex_fsm.v移除,加入ex_3/design/ex_fsm.vo文件
再加一個庫文件ex_3/sim/altera_lib/altera_mf.v
共三個文件:altera_mf.v,ex_fsm.vo,tb_ex_fsm.v
修改編譯順序:compile—>compile order—>altera_mf.v(調到第一個)
出現錯誤是因爲剛纔把ex_3/sim/work(庫) 刪了
因此新建一個庫,在最下方輸入命令:
vilb work
在Library 標籤頁下,找到tb_ex_fsm—>右鍵Simulate without Optimization啓動
有錯誤,需要加其它組件(cycloneive_io_obuf … not found…)
在QuartusII13.1/quartus/eda/sim_lib把cycloneive_atoms.v加到ex_3/sim/altera_lib下,
然後在modelsim的Project標籤頁下,加入cycloneive_atoms.v
編譯
在Library標籤頁下,右鍵tb_ex_fsm啓動仿真
出現錯誤:“dffeas …not found…”
然後在QuartusII13.1/quartus/eda/sim_lib把altera_primitives.v(原語)按同樣方式加入到ex_3/sim/altera_lib下,然後在modelsim的Project標籤頁下,加入altera_primitives.v
編譯,成功。
發現寄存的信號和時鐘不同不了,事件都有延時了。(後仿裏面的東西)
練習:檢測10010這個序列作爲練習,畫出狀態遷移圖。
來源:
https://ke.qq.com/user/index/index.html#cid=66019&term_id=100056181