1何小艇《电子系统设计》浙江大学出版社2008.1潘松黄继业《EDA技术实用教程》科学出版社2006.10齐晶晶《现代电子系统设计》实验指导书电工电子实验教学中心2009.8摘要堆栈处理器是具有两个功能,首先它与数据总线的数据交换符合堆栈的要求(即先进后出);能对存储的数据进行算术运算。本次设计就是基于FPGA用VHDL语言实现的一个堆栈处理器,拥有一个RAM进行堆栈的数据存储操作,同时有两个寄存器存放运算器的输入和运算结果。堆栈处理器的主要组成部分如下:1、堆栈存储器:进行数据的存储是堆栈处理器的基本功能,这里的堆栈存储器就是一个可以用来存储和读取数据的RAM,它的存储和读取符合堆栈先进后出的要求,具体的实现方法将在后面的方案论证中详细论述。2、运算器:运算器的功能就是对处于栈顶的两个数据进行算术运算(加、减、乘、除),并将运算结果送至控制部分,进行下一步的操作。3、控制模块:控制堆栈处理器的各项操作(入栈、出栈、算术运算)、状态转移、设置各种状态标志和RAM地址的产生。4、显示模块:用来显示A、B寄存器中的数据、数据总线数据和输入数据的实时显示。一、任务解析……………………………………………………………………3二、系统方案论证………………………………………………………………42.1总体方案比较论证……………………………………………………42.2系统结构与原理………………………………………………………4三、数据子系统的设计…………………………………………………………43.1堆栈存储器的设计……………………………………………………43.2运算器的设计…………………………………………………………53.3数据路径………………………………………………………………6四、控制子系统…………………………………………………………………64.1方案论证………………………………………………………………64.2控制部分的实现………………………………………………………7五、总结…………………………………………………………………………85.1仿真结果………………………………………………………………85.2系统缺陷分析…………………………………………………………11六、心得体会……………………………………………………………………112一、任务解析(1)根据任务要求,堆栈处理器与总线的数据交换要符合先进后出的原则,它是一个具有数据存储和读取功能的RAM,为了便于测试,这里我们设定了一个8*8的RAM,它的字数为8,每个字为8位,满足了数据位数为8的要求。在堆栈中定义一个堆栈指针SP,用来表征存储字在RAM中的位置,当进行入栈操作PUSH时,数据存入地址为SP的单元后,SP←SP-1;而进行出栈操作POP时,将SP单元的数据读出后,SP←SP+1。当指针处于栈顶,对应满栈,应有满栈信号FULL=1,此时不能进行入栈PUSH。当SP=8时,指针处于栈底,对应栈空,应有栈空信号EMPTY=1,此时不可以进行出栈POP。(2)堆栈处理器的第二个功能是算术运算操作,首先应有四个算术运算的指示信号,即输入信号ADD、SUB、MUL、DIV。算术运算的过程就是把地址分别为SP和SP+1的两个数据分别送入运算器进行运算,运算后将结果送入地址为SP+1的字中。当栈中只有一个字时不能进行算术运算,因此应有一个ONE指示信号,当指针为7时,栈内只有一个字,指示信号ONE=1。(3)控制器主要用来设置各个标志位的状态,数据的具体流向、存储路径,控制显示模块的显示。(4)对于显示的部分,只需将数据总线的数据送至数码管显示电路即可。(5)系统框图的确定由以上分析可以得到堆栈处理器的功能框图和系统原理框图如下所示:堆栈存储器数据输入DIN地址(SP)产生器数据输出DOUT运算器控制器标志寄存器标志信号输出FULL、EMPTY、ONE、READ、FA、FB操作信号输入PUSH、POP、算术操作显示模块(显示A、B寄存器,数据总线和输入数据内容)图一、系统原理框图3图二、功能框图二、系统方案论证2.1总体方案比较论证方案一:采用数字逻辑电路,根据堆栈处理器的各种状态转移和逻辑关系画出卡诺图,分析其逻辑关系,使用触发器、门电路等一系列芯片来连接电路实现堆栈处理器的功能。但是由于堆栈处理器的状态转移较多,逻辑关系分析起来比较复杂,而且会需要大量的芯片,电路连接复杂,不易实现,不是理想方案。方案二:采用FPGA实现,用语言描述或者微程序法实现各种状态转移和逻辑关系。这种方案较之于第一种方案比较容易实现,省去了复杂的电路连接,而且堆栈处理器的RAM,以及加法器,减法器,乘法器,除法器都可以定制,相对来说,省去了构建运算器的工作量。因此我们选择了方案二作为我们的设计方案。2.2系统结构与原理本方案的系统原理图见图一,它主要包括数据子系统和控制子系统两大模块,下面我们来讨论具体功能的实现。三、数据子系统的设计数据子系统包括对数据的存储、运算、传输以及控制子系统之间的条件和控制信号交换部分,下面就从这几个方面来分析数据子系统的设计和实现放法。3.1堆栈存储器的设计方案一:定制RAM,然后根据各种操作对RAM的访问不同,编写一个RAM的读写控制器,它产生读写控制信号和相应的RAM地址。方案二:用语言编写,这里我们采用了语言编写了一个RAM,将各种的控制操作和RAM整合在了一起,作为一个堆栈存储器的模块。为了便于测试,我们这里定义一个8*8的RAM作为堆栈存储器,地址产生器产生的地址即为指针SP,由于RAM的速度问题,因此我们用两个高速的寄存器A、B来数据总线进行数据交换,而RAM作为后备不直接和数据总线通信,这样就解决了RAM的读写速度较慢的问题。图示即为堆栈存储器的结构框图。堆栈存储器的工作有三个方面:入栈、出栈和算术运算。由于添加了两个寄4存器,因此数据的流向不再是简单的将数据存储到RAM中,下面来分别讨论在这三方面的数据流向问题:寄存器ARAM8*8寄存器BDATA_BUS图三、堆栈存储器的结构(1)入栈(PUSH)操作:A,B均空时:B←DIN。A空B满时:A←DIN。A、B均满时:RAM←B,B←A,A←DIN。(2)出栈(POP)操作A,B均满:DOUT←A。A空B满:DOUT←B。A,B均空:B←RAM,DOUT←B。(3)算术运算(OP)操作:A,B均满:B←[A(OP)B]。A空B满:A←B,B←RAM,B←[A(OP)B]。A,B均空:B←RAM,A←B,B←RAM,B←[A(OP)B]。由以上分析可以看出堆栈处理器的工作特点:a.只有A,B寄存器和外部总线进行数据交换,RAM只和B寄存器进行数据交换。b.必须设置两个标志位FA,FB来指示A,B寄存器是否已满。c.应设置一个READY信号,指示操作是否完成,只有当处理器输出READY信号时才可以进行下一步的操作。d.关于堆栈指针SP,为了实现堆栈的要求(先进后出),因此在系统的起始状态,SP应指向栈底(RAM的最后一个单元,SP=8),而且应注意到,入栈时,数据不直接进入RAM之中,必须是A、B均满的时候才进行写RAM的操作,这时RAM(SP)←B,SP←SP-1;同样的对于出栈,应该在A、B均空以后才可以读RAM,SP←SP+1,B←RAM(SP),DOUT←B。e.栈满信号FULL应该是在SP=0,并且FA=1,FB=1时才指示栈满,输出栈空信号EMPTY的条件是FA=0,FB=0,且SP=8。3.2运算器的设计由上面的分析我们知道运算器的输入是A,B两个寄存器的数据,运算器进行相关的运算以后将运算结果送至B寄存器存储起来。加法器和减法器的设计比较简单,直接进行加减运算就可以了,可以用语言5描述的方法将他们直接的整合到堆栈存储器的模块之中去,不必再去定制相应的模块,节省了部分资源;乘法器和除法器我们采用定制的方法,将A,B的数据送至乘法器、除法器的输入端,然后将结果送回堆栈处理器进行处理,下图即为定制的乘法器和除法器。Unsignedmultiplicationdataa[7..0]datab[7..0]result[15..0]MULinst2DenomisUNSIGNEDNumerisUNSIGNEDnumer[7..0]denom[7..0]quotient[7..0]remain[7..0]DIVinst1图四、乘法器和除法器当栈内只有一个数时不能进行算术运算,因此必须设置一个ONE信号指示栈内数据为一的状态,提醒此时不可以经行算术运算。与堆栈存储器一样,运算器同样需要一个READY信号,来指示操作是否完成。3.3数据路径根据以上的分析,明确了数据系统应有的模块及其操作规则。按照分析的结果我们可以总结出其数据路径如下:寄存器A的数据来源有两个,分别是数据总线和B寄存器,只有在入栈和算术运算时才有数据进入。寄存器B的数据来自四个方面:寄存器A、数据总线、RAM和运算器的运算结果。RAM的数据仅来自寄存器B,不和其它设备进行数据的交换。输出的数据来自寄存器A和寄存器B,任何输出都要经过这两个寄存器才能输出。运算器的数据来自寄存器A和寄存器B,运算结果输出到寄存器B。至此,我们已经分析了堆栈存储器的设计思路,设计方案,以及实现的方法,根据上面得出的逻辑关系和数据流向就可以写出数据子系统的VHDL语言代码。四、控制子系统设计4.1方案论证方案一:采用微程序法实现控制子系统的微程序设计适用于系统很复杂,系统的MDS图的状态数目很多,输入输出变量很多的情况,而且它具有设计规范、易于模块化、便于二次集成、便于修改的有点。其基本结构如下图所示。ROMD触发器输入输出6图五、微程序设计基本结构本系统的状态转移变量较多,系统较复杂,因而使用微程序设计的方法比较适合于这个系统。方案二:语言描述比之于微程序设计的方法来说,语言描述的方法相对来说比较繁琐,因为转移变量较多,写程序的时候比较复杂,需要仔细的分析系统,否则会导致数据混乱等一系列的后果,但是如前所述,在设计数据子系统的时候,已经涉及到了各项操作的数据流向及状态标志的问题,这里再进行一次相关描述会有些重复,因此在这里我们继续的使用语言描述的方案,将控制子系统和数据子系统相结合,利用数据子系统的资源来进行控制子系统的设计。虽然这种方案没有前者那样看起来模块清晰,但是由于和数据子系统结合在一起,在阅读程序时比较容易了解整个系统的工作流程,需要修改时也不必对各个模块逐一的修改。4.2控制部分的实现在数据子系统中我们讨论了在各种操作中的数据流向的问题,但并没有明确的指出数据的存储路径以及各种标志信号的变化,根据在上面分析的数据流向的基础上,我们加上各种标志位进行详细的论述:(1)入栈PUSH若FA=0,FB=0:B←DIN,FB←1;若FA=0,FB=1:A←DIN,FA←1;若FA=1,FB=1:RAM(SP)←B,SP←SP-1,B←A,A←DIN,FA←1,FB←1;(2)出栈POP若FA=1,FB=1:DOUT←A,FA←0;若FA=0,FB=1:DOUT←B,FB←0,;若FA=0,FB=0:SP←SP+1,B←RAM(SP),DOUT←B,FA←0,FB←0;(3)算术运算OP若FA=1,FB=1:B←[A(OP)B],FA=0,FB=1;若FA=0,FB=1:A←B,SP←SP+1,B←RAM(SP),B←[A(OP)B],FA=0,FB=1;若FA=0,FB=0:SP←SP+1,B←RAM(SP),A←B,SP←SP+1,B←RAM(SP),B←[A(OP)B],FA=0,FB=1;(4)READY信号READY信号用来指示是否可以进行操作,因此当有操作输入(PUSH,POP,OP)时,READY←0,此时封锁操作信号的输入,而当当前操作结束后,应立即给READY恢复为1,允许其他操作的进行。可以用下面的方法来实现READY的赋值:IF(PUSH·POP·OP)∥READY←0∕READY←1;(5)ONE信号ONE信号指示栈内只有一个数据的情况,指示