<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > EDA/PCB > 設(shè)計應(yīng)用 > 多狀態(tài)機(jī)的協(xié)同設(shè)計

          多狀態(tài)機(jī)的協(xié)同設(shè)計

          作者: 時間:2004-12-08 來源:網(wǎng)絡(luò) 收藏

          作者Email: zlyadvocate@163.com

          隨著微電子技術(shù)的迅速發(fā)展,人們對數(shù)字系統(tǒng)的需求也在提高[ 1 ]。不僅要有完善的功能,而且對速度也提出了很高的要求。對于大部分?jǐn)?shù)字系統(tǒng),都可以劃分為控制單元和數(shù)據(jù)單元兩個組成部分。通常,控制單元的主體是一個有限狀態(tài)機(jī) ,它接收外部信號以及數(shù)據(jù)單元產(chǎn)生的狀態(tài)信息,產(chǎn)生控制信號序列。有限狀態(tài)機(jī)設(shè)計的關(guān)鍵是如何把一個實際的時序邏輯關(guān)系抽象成一個時序邏輯函數(shù),傳統(tǒng)的電路圖輸入法通過直接設(shè)計寄存器組來實現(xiàn)各個狀態(tài)之間的轉(zhuǎn)換, 而用硬件描述語言來描述有限狀態(tài)機(jī), 往往是通過充分發(fā)揮硬件描述語言的抽象建模能力,通過對系統(tǒng)在系統(tǒng)級或寄存器傳輸級進(jìn)行描述來建立有限狀態(tài)機(jī)。EDA 工具的快速發(fā)展,使通過CAD快速設(shè)計有限狀態(tài)機(jī)自動化成為可能。

          傳統(tǒng)上在系統(tǒng)級和寄存器傳輸級完成VHDL 的描述主要分以下幾步:

          (1)分析控制器設(shè)計指標(biāo), 建立系統(tǒng)算法模型圖;
          (2)分析被控對象的時序狀態(tài), 確定控制器有限狀態(tài)機(jī)的各個狀態(tài)及輸入.輸出條件;
          (3)應(yīng)用VHDL 語言完成描述。

          使用XILINX的ISE6.1軟件包的輔助工具STATECAD能加速有限狀態(tài)機(jī)設(shè)計,大大簡化狀態(tài)機(jī)的設(shè)計過程,實現(xiàn)狀態(tài)機(jī)設(shè)計的自動化。使用STATECAD進(jìn)行狀態(tài)機(jī)設(shè)計的流程如下:

          (1)分析控制器設(shè)計指標(biāo), 建立系統(tǒng)算法模型圖;
          (2)分析被控對象的時序狀態(tài), 確定控制器有限狀態(tài)機(jī)的各個狀態(tài)及輸入.輸出條件;
          (3) 在STATECAD中輸入有限狀態(tài)機(jī)狀態(tài)圖,自動產(chǎn)生VHDL模型描述,使用STATEBENCH進(jìn)行狀態(tài)轉(zhuǎn)移分析,分析無誤后使用導(dǎo)出VHDL模型塊到ISE中進(jìn)行仿真后綜合,實現(xiàn)到CPLD或FPGA的映射。

          設(shè)計人員的主要工作在第一步。第二步,第三步基本上可以通過STATECAD完成有限狀態(tài)機(jī)的自動生成和分析,還可以利用分析結(jié)果來對被控對象的邏輯進(jìn)行分析,改進(jìn),完善系統(tǒng)控制邏輯。

          在需要并行處理的場合,往往需要采用多狀態(tài)機(jī)來完成系統(tǒng)的控制任務(wù),這時狀態(tài)機(jī)之間的同步問題往往是設(shè)計者需要仔細(xì)考慮的問題。如果采用完全人工輸入代碼的方法來設(shè)計,往往力不從心。采用STATECAD完成整個控制邏輯的設(shè)計并對設(shè)計結(jié)果進(jìn)行驗證更能體現(xiàn)CAD設(shè)計方法的優(yōu)勢,加速產(chǎn)品開發(fā)進(jìn)度,提高設(shè)計生產(chǎn)率。

          下面以一個雙狀態(tài)機(jī)設(shè)計過程來介紹如何使用STATECAD進(jìn)行多狀態(tài)機(jī)的。

          有二個狀態(tài)機(jī),一個負(fù)責(zé)對M0寫,一個負(fù)責(zé)對M0讀操作,為了簡單起見,系統(tǒng)已經(jīng)盡量簡化了。
          負(fù)責(zé)對M0寫的狀態(tài)機(jī)包括四個狀態(tài):
          STATE0:寫狀態(tài)機(jī)復(fù)位后初始化;
          write0:對M0寫,寫滿4個轉(zhuǎn)到m0full;
          m0full:M0滿狀態(tài);
          m0writewait:等待。M0滿時轉(zhuǎn)入write0狀態(tài)。
          負(fù)責(zé)對M0讀的狀態(tài)機(jī)包括四個狀態(tài):
          STATE1:讀狀態(tài)機(jī)復(fù)位后初始化
          read0:對M0讀,讀4個轉(zhuǎn)到m0empty
          m0empty:M0空狀態(tài)
          m0readwait:等待。M0空時轉(zhuǎn)入read0狀態(tài)

          負(fù)責(zé)對M0寫的狀態(tài)機(jī)必須知道M0是空的,而負(fù)責(zé)對M0讀的狀態(tài)機(jī)必須知道M0是滿的才能讀。讀完了通知負(fù)責(zé)對M0寫的狀態(tài)機(jī)M0是空的,可以寫了。二個狀態(tài)機(jī)同時并行工作。M0寫的狀態(tài)機(jī)在寫操作完了,就等待M0空。M0讀的狀態(tài)機(jī)在讀操作完了,就等待M0滿。在STATECAD中,狀態(tài)本身可以作為其他狀態(tài)機(jī)的轉(zhuǎn)移條件。這也正是在進(jìn)行多狀態(tài)機(jī)的中最需要的功能,能大大方便多狀態(tài)機(jī)的設(shè)計。

          輸入完狀態(tài)圖,就基本完成了狀態(tài)機(jī)的設(shè)計過程。進(jìn)行邏輯優(yōu)化(工具自動進(jìn)行邏輯優(yōu)化)后,使用STATEBENCH進(jìn)行狀態(tài)轉(zhuǎn)移分析。以下是自動狀態(tài)轉(zhuǎn)移模擬波形。

          由以上的波形看到狀態(tài)機(jī)的工作過程符合設(shè)計邏輯。對單獨(dú)的器件操作也許不需要采用多狀態(tài)機(jī)的設(shè)計方法,但在多器件需要并行工作時,多狀態(tài)機(jī)的就顯得必要了。導(dǎo)出VHDL模型塊到ISE中進(jìn)行仿真后綜合,這里就不多講了,以下是產(chǎn)生的代碼:
          -- 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;



          關(guān)鍵詞: 協(xié)同設(shè)計

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();