1. 设计要求

设计5字节的堆栈电路并进行仿真,电路使用8位并行接口,端口包括8位数据端口D、读写信号RD与WR、片选端口CS。当CS、WR产生下降沿时,电路通过8位并行接口将数据写入堆栈;当CS、RD产生下降沿时,电路通过8位并行接口按照“先入后出”的顺序,将堆栈数据依次送至数据总线D。

2. 功能与电路逻辑分析

2.1 功能分析

堆栈是计算机系统中应用非常广泛的一种储存电路,它遵循先入后出的储存原则,常用于计算机控制过程中的一些重要的运行参数与数据的存储恢复。基本堆栈存储区STACK、堆栈指针SP,如图2.1所示。

图2.1 堆栈电路简化模型图

当存入数据时,堆栈电路获取堆栈指针SP,计算对应的存储地址。然后将指定数据传送至相应的存储单元,则堆栈指针加1运算,即称之为“压栈”或“入栈”;读数据操作时,堆栈电路首先获取堆栈指针SP,堆栈指针则进行减1运算,随后计算地址信息,将对应存储单元的数据传送至数据总线,完成栈内数据的“出栈”操作。</br>在堆栈初始化状态时,堆栈指针SP指向图中的栈底。随堆栈操作的进行,根据栈操作的指令,堆栈指针依次加1(上移)或减1(下移),直至到达栈底或栈顶。

2.2 实现原理

堆栈电路设计通过写进程WrProc(压栈)、读进程RdProc(出栈)、指针控制进程PntCon与堆栈储存区DSeg共同实现。为便于电路描述,堆栈设计中特别设置堆栈的读指针pRd与写指针pWr,其中的写指针pWr与堆栈SP取值相同,读指针pRd的取值为pWr减1,与堆栈定义及操作完全一致。</br>
写进程WrProc实现数据的压栈操作,进程响应器件并行接口的写操作,将写入的数据送入堆栈DSeg,完成压栈。同时,WrProc结合电路的读写状况调整写指针pWr;读进程RdProc实现数据的出栈操作,进程响应器件并行接口的读操作,将堆栈内数据送至器件的数据端口D,完成出栈;进程PntCon专门用于读指针的动态调整,进程根据器件读写状况计算堆栈的读指针。

3. VHDL电路描述

根据以上电路原理,设计如下VHDL电路描述,其中分为实体dataStack,依附于实体的结构体StackBody,其中包含三个进程分别为入栈进程WrProc,出栈进程RdProc和动态调整进程PntCon;描述语句为IEEE标准,引用IEEE逻辑器件程序库,使用程序包IEEE.STD_LOGIC_1164IEEE.STD_LOGIC_UNSIGNED,描述代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY dataStack IS
PORT(D:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
CS,RD,WR:IN STD_LOGIC;
Empt,Full:OUT STD_LOGIC);
END dataStack;
ARCHITECTURE StackBody OF dataStack IS
TYPE mMem IS ARRAY(0 TO 7)OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL DSeg:mMem;
SIGNAL EmptF:STD_LOGIC:='1';
SIGNAL FullF:STD_LOGIC:='0';
SIGNAL pWr:INTEGER RANGE 0 TO 8 :=0;
SIGNAL pRd:INTEGER RANGE 0 TO 8 :=0;
BEGIN
WrProc:PROCESS(RD,CS,EmptF,WR,D,pRd)
VARIABLE iWr:INTEGER RANGE 0 TO 8 :=0;
VARIABLE iFull:STD_LOGIC:='0';
VARIABLE iDeta:STD_LOGIC:='0';
BEGIN
IF RD='0' AND CS='0' AND EmptF='0' THEN
iDeta:='1';
iFull:='0';
ELSIF RISING_EDGE(WR) AND CS='0' AND iFull='0' THEN
IF iDeta='1' THEN
iWr:=pRd;
END IF;
DSeg(iWr)<=D;
IF iWr=7 THEN
iFull:='1';
END IF;
iWr:=iWr+1;
iDeta:='0';
END IF;
pWr<=iWr;
FullF<=iFull;
END PROCESS WrProc;
RdProc:PROCESS(CS,RD,EmptF,DSeg,pRd)
BEGIN
IF RD='0' AND CS='0' AND EmptF='0' THEN
D<=DSeg(pRd);
ELSE
D<="ZZZZZZZZ";
END IF;
END PROCESS RdProc;
PntCon:PROCESS(WR,CS,FullF,pWr,RD)
VARIABLE iRd:INTEGER RANGE 0 TO 8 :=0;
VARIABLE iEmpt:STD_LOGIC:='1';
VARIABLE iDeta:STD_LOGIC:='0';
BEGIN
IF WR='0' AND CS='0' AND FullF='0' THEN
iDeta:='1';
iEmpt:='0';
ELSIF FALLING_EDGE(RD) AND CS='0' AND iEmpt='0' THEN
IF iDeta='1' THEN
iRd:=pWr-1;
ELSIF iRd>0 THEN
iRd:=iRd-1;
ELSE
iEmpt:='1';
END IF;
iDeta:='0';
END IF;
pRd<=iRd;
EmptF<=iEmpt;
END PROCESS PntCon;
Empt<=EmptF;
Full<=FullF;
END StackBody;

堆栈电路dataStack在正常工作时,数据的出入栈动作均会影响读写指针pRd与pWr;写进程WrProc响应信号WR的上升沿,CS为低电平有效且堆栈dataStack不为满状态,若上次操作为出栈(iDeta =‘1’)WrProc获取读指针pRd,根据pRd计算当前写指针pWr。当上次操作为入栈(iDeta=‘0’)时,如果pWr到达栈顶,将堆栈满标志iFull置位,调整写指针pWr。然后写进程WrProc获取数据总线D,送入堆栈存储区DSeg中由pWr指定的存储单元DSeg(pWr),同时清除标志iDeta。</br>由于写指针pWr的计算与上次栈操作类型有关,进程WrProc监测读信号RD,若RD发生变化、CS有效且堆栈不为空(EmptF为“0”),进程WrProciDeta置位,供WrProc执行入栈操作时计算pWr使用。</br>进程PntCon计算堆栈电路的读指针pRd,进程响应读信号的下降沿,若CS有效且堆栈不为空(EmptF为“0”),则计算堆栈读指针pRd,执行出栈操作。进程RdProc响应读信号RD,在CS有效且堆栈不为空时,将读指针pRd对应的堆栈存储单元DSeg(pRd)送上数据总线D。

4. 电路的实现

使用QuartusⅡ 13.0版本进行电路搭建以及仿真。首先进行新建项目,将VHDL描述程序加入设计项目并作为顶层实体,实现预定的堆栈功能电路。顶层实体以及项目名称需要保持一致,均命名为dataStack。同时实体的VHDL描述程序文件名称需要与顶层实体名称一一对应,命名为dataStack。本次电路载体选择Cyclone Ⅲ系列的EP3C40Q240C8N来实现预定电路,进行编译之后如图4.1所示。

图4.1 Quartus Ⅱ编译状态图

其中根据编译总结报告可知(图4.2),采用EP3C40Q240C8N器件实现目标堆栈电路dataStack需要占用宏单元(Total logic elements)101个,所占用总数小于器件所提供宏单元的1%;实现目标逻辑占用器件端口(Pins)13个,占器件所提供的I/O端口总数的10%。器件EP3C40Q240C8N采用129脚的TQFP封装,速度等级为Level-9,封装形式及器件大小,速度等级对于实现堆栈电路来说大材小用,但是应学校器材限制,使用EP3C40Q240C8N器件来实现dataStack电路十分合理。

图4.2 编译总结报告图

因此最终指定器件为EP3C40Q240C8N,考虑到后续制板、布局、布线的合理性以及调试的方便性,堆栈电路dataStack的引脚分配与器件指定情况如图4.3所示。图中带阴影引脚为已分配信号的引脚,从引脚18到引脚142,按照逆时针顺序,端口上分配的信号依次为:片选信号CS、双向数据总线的数据端口D、堆栈电路dataStack空标志Empt、堆栈电路dataStack满标志Full、计算机并行接口的读信号RD、计算机并行接口的写信号WR。

图4.3 引脚分配与器件指定情况

表4.4给出了堆栈电路dataStack实现器件EP3C40Q240C8N引脚与I/O信号的详细对应关系。


表4.4 堆栈电路dataStack的引脚信号详细分配状况
To Direction Location I/O Bank VREF Group Fitter Location
CS Input PIN_18 1 B1_N2 PIN_18
D(7) Bidir PIN_21 1 B1_N3 PIN_21
D(6) Bidir PIN_38 2 B2_N0 PIN_38
D(5) Bidir PIN_80 3 B3_N1 PIN_80
D(4) Bidir PIN_78 3 B3_N1 PIN_78
D(3) Bidir PIN_76 3 B3_N1 PIN_76
D(2) Bidir PIN_73 3 B3_N2 PIN_73
D(1) Bidir PIN_70 3 B3_N2 PIN_70
D(0) Bidir PIN_69 3 B3_N2 PIN_69
Empt Output PIN_139 5 B3_N2 PIN_139
Full Output PIN_142 5 B5_N1 PIN_142
RD Input PIN_37 2 B2_N0 PIN_37
WR Input PIN_39 2 B2_N0 PIN_39

5. 电路分析与仿真测试

QuartusⅡ中新建一个名为dataStack的vwf逻辑功能仿真波形文件,将图中的仿真栅格(Grid Size)大小设置为20ns,仿真总时长(Set End Time)设置为3us。导入信号并设置波形输入信号(如图5.1)。

图5.1

其中信号\PntCon:iRd为堆栈电路dataStack的读指针,与其相对应,信号\WrProc:iWr为堆栈电路dataStack的写指针;信号D为计算机并行接口8位双向数据端口的设定值,信号DATA为堆栈电路dataStack工作时8位双向数据端口D的信号变化情况。</br>在上述仿真激励中的时间段30-450ns内,并行接口写信号WR连续产生下降沿,向堆栈电路dataStack持续写入10个数据。此时,堆栈电路dataStack的工作时序仿真如图5.2所示。

图5.2

从时刻30ns开始并行接口向堆栈电路dataStack持续送入数据01-10,写指针iWr依次增加,当写至数据8时,满标志Full变为高电平,堆栈满。在时间段520-580ns内,RD连续发出读脉冲,DATA送出最后的压栈数据8、7。在时间段660-720ns内,将数据10、11压栈,Full重新变为高电平。图5.3所示为dataStack持续出栈情况。

图5.3

从840ns时刻开始,RD连续发出读脉冲,数据总线DATA端连续送出数据12、11、6、5、4、3、2、1,与前文的压栈数据顺序一一对应。在840ns时刻,RD变为低电平,堆栈dataStack开始送出数据,满标志Full迅速变为低电平;送出8个数据后,空标志Empt置位,堆栈清空。</br>当堆栈满后,数据随机出栈时的堆栈电路工作时序仿真结果如图5.4所示。

图5.4

从时刻1.30us开始,CS有效,WR连续发出写脉冲,DATA端数据13-20依次被压入堆栈dataStack。压栈开始,空标志Empt迅速变为低电平。当8当个数据完成压栈后,堆栈满标志Full置位。在时刻1.76us处,RD连续发出4个随机的读信号,栈顶的4个数据20、19、18、17被送上dataStack电路的数据总线DATA,此时,堆栈内顺序保留数据16、15、14、13。

图5.5

图5.5所示为随机压栈至满栈后,持续出栈时电路的工作时序仿真结果。从时刻1.32us开始,端口WR上连续出现写脉冲,数据23-26被压入堆栈,堆栈满标志Full被置为高电平,堆栈dataStack进入满状态。从时刻2.30us开始,端口RD持续发出读脉冲,堆栈内的数据被依次送至DATA端口,数据序列为26、25、24、23、16、15、14与13,数据顺序符合压栈顺序。</br>以上,结合电路的预定功能,通过4种状况对堆栈电路dataStack进行了初步的测试以及逻辑仿真校验,电路动作与原定功能和工作时序一致。堆栈电路dataStack的其他工作时序分析与以上分析基本类似,电路达到设计要求。

6. 设计总结

电子设计自动化(EDA)是二十一世纪最重要的应用科学之一,在计算机、数控机床、机器人、互联网、数字媒体、人工智能等方面举足轻重。