多状态机的协同设计

2007-03-09 19:03:27来源: 互联网
作者Email: zlyadvocate@163.com 随着微电子技术的迅速发展,人们对数字系统的需求也在提高[ 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: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;
编辑: 引用地址:http://www.eeworld.com.cn/designarticles/eda/200703/10578.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
论坛活动 E手掌握
微信扫一扫加关注
论坛活动 E手掌握
芯片资讯 锐利解读
微信扫一扫加关注
芯片资讯 锐利解读
推荐阅读
全部

小广播

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 安防电子 医疗电子 工业控制

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2016 EEWORLD.com.cn, Inc. All rights reserved