随着微电子技术的迅速发展,人们对数字系统的需求也在提高[ 1 ]。不仅要有完善的功能,而且对速度也提出了很高的要求。对于大部分数字系统,都可以划分为控制单元和数据单元两个组成部分。通常,控制单元的主体是一个有限状态机 ,它接收外部信号以及数据单元产生的状态信息,产生控制信号序列。有限状态机设计的关键是如何把一个实际的时序逻辑关系抽象成一个时序逻辑函数,传统的电路图输入法通过直接设计寄存器组来实现各个状态之间的转换, 而用硬件描述语言来描述有限状态机, 往往是通过充分发挥硬件描述语言的抽象建模能力,通过对系统在系统级或寄存器传输级进行描述来建立有限状态机。eda 工具的快速发展,使通过cad快速设计有限状态机自动化成为可能。
	 传统上在系统级和寄存器传输级完成vhdl 的描述主要分以下几步:
	 (1)分析控制器设计指标, 建立系统算法模型图;
	 (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:\xilinxtutorial\duoztji.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 
	next_sreg<=m0writewait;
	bp_dcounter 
	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 
	next_sreg<=write0;
	bp_dcounter 
	if ( bp_dcounter0='1' and bp_dcounter1='1' ) then
	next_sreg<=m0full;
	bp_dcounter <= (std_logic_vector'(00));
	else
	 next_sreg<=write0;
	bp_dcounter 
	end case;
	end if;
	if ( reset='1' ) then
	next_sreg1<=state1;
	readcounter 
	next_sreg1<=m0readwait;
	readcounter 
	if ( (sreg=m0full)) then
	 next_sreg1<=read0;
	readcounter <= (( std_logic_vector'(readcounter1, readcounter0)) +
	std_logic_vector'(01));
	 else
	next_sreg1<=m0readwait;
	readcounter 
	if ( readcounter0='1' and readcounter1='1' ) then
	next_sreg1<=m0empty;
	readcounter <= (std_logic_vector'(00));
	else
	next_sreg1<=read0;
	readcounter 
	if ( (sreg=m0full)) then
	next_sreg1<=read0;
	readcounter <= (( std_logic_vector'(readcounter1, readcounter0)) +std_logic_vector'(01));
	else
	next_sreg1<=state1;
	readcounter 
	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 clk,reset=>reset,dcounter0=>
	dcounter(0),dcounter1=>dcounter(1));
	end behavior;
			
			
       	 	
    	智能设备工艺的标准化对产品质量有着至关重要的影响
         	 	
    	人工智能给安防带来革命性的改变不可逆转,中小型安防企业前路迷茫!
         	 	
    	简单叙述WiFi测试 复杂的协议使测试更麻烦
         	 	
    	如何解决共振引起的EMC问题?
         	 	
    	异构众核系统高性能计算架构
         	 	
    	多状态机的协同设计
         	 	
    	传音旗下品牌TECNO发布全球首款伸缩微距镜头概念机
         	 	
    	可穿戴设备为何容易被破解?安全保障在数据不在硬件!
         	 	
    	MediaTek推出了天玑系列最新5G SoC——天玑800U
         	 	
    	电解液中硫酸钠加多少比例最合适
         
       	 	
    	交换机的端口配置
         	 	
    	库克承诺下一代iOS将内置CPU限速保护功能开关 用户可自行关闭
         	 	
    	直连通信应用于自动驾驶场景的频谱需求研究
         	 	
    	运算放大器制作移相电路的设计方案
         	 	
    	薄膜表面瑕疵在线检测系统拥有强大的缺陷识别功能
         	 	
    	静脉可视化“神器”,让护士们轻松搞定抽血输液
         	 	
    	齐纳二极管稳压电路_齐纳二极管为什么能够稳压
         	 	
    	java程序编译后会产生什么
         	 	
    	机械结构件的结构要素和设计方法
         	 	
    	PCB需求旺盛:产业链集体受益