?
隨著微電子技術的迅速發展,人們對數字系統的需求也在提高。不僅要有完善的功能,而且對速度也提出了很高的要求。對于大部分數字系統,都可以劃分為控制單元和數據單元兩個組成部分。通常,控制單元的主體是一個有限狀態機 ,它接收外部信號以及數據單元產生的狀態信息,產生控制信號序列。有限狀態機設計的關鍵是如何把一個實際的時序邏輯關系抽象成一個時序邏輯函數,傳統的電路圖輸入法通過直接設計寄存器組來實現各個狀態之間的轉換, 而用硬件描述語言來描述有限狀態機, 往往是通過充分發揮硬件描述語言的抽象建模能力,通過對系統在系統級或寄存器傳輸級進行描述來建立有限狀態機。EDA 工具的快速發展,使通過CAD快速設計有限狀態機自動化成為可能。
傳統上在系統級和寄存器傳輸級完成VHDL 的描述主要分以下幾步:
(2) 分析被控對象的時序狀態, 確定控制器有限狀態機的各個狀態及輸入.輸出條件;
(3) 應用VHDL 語言完成描述。
使用XILINX的ISE6.1軟件包的輔助工具STATECAD能加速有限狀態機設計,大大簡化狀態機的設計過程,實現狀態機設計的自動化。使用STATECAD進行狀態機設計的流程如下:
(1) 分析控制器設計指標, 建立系統算法模型圖;
(2) 分析被控對象的時序狀態, 確定控制器有限狀態機的各個狀態及輸入.輸出條件;
(3) 在STATECAD中輸入有限狀態機狀態圖,自動產生VHDL模型描述,使用STATEBENCH進行狀態轉移分析,分析無誤后使用導出VHDL模型塊到ISE中進行仿真后綜合,實現到CPLD或FPGA的映射。
設計人員的主要工作在第一步。第二步,第三步基本上可以通過STATECAD完成有限狀態機的自動生成和分析,還可以利用分析結果來對被控對象的邏輯進行分析,改進,完善系統控制邏輯。
在需要并行處理的場合,往往需要采用多狀態機來完成系統的控制任務,這時狀態機之間的同步問題往往是設計者需要仔細考慮的問題。如果采用完全人工輸入代碼的方法來設計,往往力不從心。采用STATECAD完成整個控制邏輯的設計并對設計結果進行驗證更能體現CAD設計方法的優勢,加速產品開發進度,提高設計生產率。
下面以一個雙狀態機設計過程來介紹如何使用STATECAD進行多狀態機的協同設計。
有二個狀態機,一個負責對M0寫,一個負責對M0讀操作,為了簡單起見,系統已經盡量簡化了。
負責對M0寫的狀態機包括四個狀態:
STATE0:寫狀態機復位后初始化;
Write0:對M0寫,寫滿4個轉到M0full;
M0full:M0滿狀態;
M0writewait:等待。M0滿時轉入Write0狀態。
負責對M0讀的狀態機包括四個狀態:
STATE1:讀狀態機復位后初始化
Read0:對M0讀,讀4個轉到M0empty
M0empty:M0空狀態
M0readwait:等待。M0空時轉入Read0狀態
負責對M0寫的狀態機必須知道M0是空的,而負責對M0讀的狀態機必須知道M0是滿的才能讀。讀完了通知負責對M0寫的狀態機M0是空的,可以寫了。二個狀態機同時并行工作。M0寫的狀態機在寫操作完了,就等待M0空。M0讀的狀態機在讀操作完了,就等待M0滿。在STATECAD中,狀態本身可以作為其他狀態機的轉移條件。這也正是在進行多狀態機的協同設計中最需要的功能,能大大方便多狀態機的設計。
?
輸入完狀態圖,就基本完成了狀態機的設計過程。進行邏輯優化(工具自動進行邏輯優化)后,使用STATEBENCH進行狀態轉移分析。以下是自動狀態轉移模擬波形。
?
由以上的波形看到狀態機的工作過程符合設計邏輯。對單獨的器件操作也許不需要采用多狀態機的設計方法,但在多器件需要并行工作時,多狀態機的協同設計就顯得必要了。導出VHDL模型塊到ISE中進行仿真后綜合,這里就不多講了,以下是產生的代碼:
-- D:XILINXTUTORIALDUOZTJI.Vhd
LIBRARY Ieee;
USE Ieee.Std_logic_1164.All;
LIBRARY Ieee;
USE Ieee.Std_logic_unsigned.All;
ENTITY SHELL_DUOZTJI IS
PORT (CLK,RESET: IN Std_logic;
Dcounter0,Dcounter1 : OUT Std_logic);
SIGNAL BP_dcounter0,BP_dcounter1,Readcounter0,Readcounter1: Std_logic;
END;
ARCHITECTURE BEHAVIOR OF SHELL_DUOZTJI IS
SIGNAL Sreg : Std_logic_vector (1 DOWNTO 0);
SIGNAL Next_sreg : Std_logic_vector (1 DOWNTO 0);
CONSTANT M0full : Std_logic_vector (1 DOWNTO 0) :="00";
CONSTANT M0writewait : Std_logic_vector (1 DOWNTO 0) :="01";
CONSTANT STATE0 : Std_logic_vector (1 DOWNTO 0) :="10";
CONSTANT Write0 : Std_logic_vector (1 DOWNTO 0) :="11";
SIGNAL Sreg1 : Std_logic_vector (1 DOWNTO 0);
SIGNAL Next_sreg1 : Std_logic_vector (1 DOWNTO 0);
CONSTANT M0empty : Std_logic_vector (1 DOWNTO 0) :="00";
CONSTANT M0readwait : Std_logic_vector (1 DOWNTO 0) :="01";
CONSTANT Read0 : Std_logic_vector (1 DOWNTO 0) :="10";
CONSTANT STATE1 : Std_logic_vector (1 DOWNTO 0) :="11";
SIGNAL Next_BP_dcounter0,Next_BP_dcounter1,Next_readcounter0,
Next_readcounter1 : Std_logic;
SIGNAL BP_dcounter : Std_logic_vector (1 DOWNTO 0);
SIGNAL Dcounter : Std_logic_vector (1 DOWNTO 0);
SIGNAL Readcounter : Std_logic_vector (1 DOWNTO 0);
BEGIN
PROCESS (CLK, Next_sreg, Next_BP_dcounter1, Next_BP_dcounter0)
BEGIN
IF CLK=''1'' AND CLK''Event THEN
Sreg <= Next_sreg;
BP_dcounter1 <= Next_BP_dcounter1;
BP_dcounter0 <= Next_BP_dcounter0;
END IF;
END PROCESS;
PROCESS (CLK, Next_sreg1, Next_readcounter1, Next_readcounter0)
BEGIN
IF CLK=''1'' AND CLK''Event THEN
Sreg1 <= Next_sreg1;
Readcounter1 <= Next_readcounter1;
Readcounter0 <= Next_readcounter0;
END IF;
END PROCESS;
PROCESS (Sreg,Sreg1,BP_dcounter0,BP_dcounter1,Readcounter0,Readcounter1,
RESET,BP_dcounter,Readcounter)
BEGIN
Next_BP_dcounter0 <= BP_dcounter0;Next_BP_dcounter1 <= BP_dcounter1;
Next_readcounter0 <= Readcounter0;Next_readcounter1 <= Readcounter1;
BP_dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)));
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)));
Next_sreg<=M0full;
Next_sreg1<=M0empty;
IF ( RESET=''1'' ) THEN
Next_sreg<=STATE0;
BP_dcounter <= (Std_logic_vector''("00"));
ELSE
CASE Sreg IS
WHEN M0full =>
Next_sreg<=M0writewait;
BP_dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)));
WHEN M0writewait =>
IF ( (Sreg1=M0empty)) THEN
Next_sreg<=Write0;
BP_dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)) + Std_logic_vector''("01"));
ELSE
Next_sreg<=M0writewait;
BP_dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)));
END IF;
WHEN STATE0 =>
Next_sreg<=Write0;
BP_dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)) +
Std_logic_vector''("01"));
WHEN Write0 =>
IF ( BP_dcounter0=''1'' AND BP_dcounter1=''1'' ) THEN
Next_sreg<=M0full;
BP_dcounter <= (Std_logic_vector''("00"));
ELSE
Next_sreg<=Write0;
BP_dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)) +
Std_logic_vector''("01"));
END IF;
WHEN OTHERS =>
END CASE;
END IF;
IF ( RESET=''1'' ) THEN
Next_sreg1<=STATE1;
Readcounter <= (Std_logic_vector''("00"));
ELSE
CASE Sreg1 IS
WHEN M0empty =>
Next_sreg1<=M0readwait;
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)));
WHEN M0readwait =>
IF ( (Sreg=M0full)) THEN
Next_sreg1<=Read0;
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)) +
Std_logic_vector''("01"));
ELSE
Next_sreg1<=M0readwait;
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)));
END IF;
WHEN Read0 =>
IF ( Readcounter0=''1'' AND Readcounter1=''1'' ) THEN
Next_sreg1<=M0empty;
Readcounter <= (Std_logic_vector''("00"));
ELSE
Next_sreg1<=Read0;
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)) +
Std_logic_vector''("01"));
END IF;
WHEN STATE1 =>
IF ( (Sreg=M0full)) THEN
Next_sreg1<=Read0;
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)) + Std_logic_vector''("01"));
ELSE
Next_sreg1<=STATE1;
Readcounter <= (( Std_logic_vector''(Readcounter1, Readcounter0)));
END IF;
WHEN OTHERS =>
END CASE;
END IF;
Next_BP_dcounter1 <= BP_dcounter(1);
Next_BP_dcounter0 <= BP_dcounter(0);
Next_readcounter1 <= Readcounter(1);
Next_readcounter0 <= Readcounter(0);
END PROCESS;
PROCESS (BP_dcounter0,BP_dcounter1,Dcounter)
BEGIN
Dcounter <= (( Std_logic_vector''(BP_dcounter1, BP_dcounter0)));
Dcounter0 <= Dcounter(0);
Dcounter1 <= Dcounter(1);
END PROCESS;
END BEHAVIOR;
LIBRARY Ieee;
USE Ieee.Std_logic_1164.All;
LIBRARY Ieee;
USE Ieee.Std_logic_unsigned.All;
ENTITY DUOZTJI IS
PORT (Dcounter : OUT Std_logic_vector (1 DOWNTO 0);
CLK,RESET: IN Std_logic);
END;
ARCHITECTURE BEHAVIOR OF DUOZTJI IS
COMPONENT SHELL_DUOZTJI
PORT (CLK,RESET: IN Std_logic;
Dcounter0,Dcounter1 : OUT Std_logic);
END COMPONENT;
BEGIN
SHELL1_DUOZTJI : SHELL_DUOZTJI PORT MAP (CLK=>CLK,RESET=>RESET,Dcounter0=>
Dcounter(0),Dcounter1=>Dcounter(1));
END BEHAVIOR;
評論
查看更多