当前位置:首页 > EDA > 电子设计自动化
[导读]多状态机的协同设计


作者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;

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭