作者:chenjieb520
一.设计目的
学习较复杂的数字系统设计方法。
二.设计内容
利用状态机,移位寄存器和数控分频器,在DE2平台上实现字符“HELLO”的从右向左自动循环显示,移动速度可控(字符以每0.1~1秒一次的速度移动),在HEX7~HEX0上循环显示“HELLO”,“HELLO”从左边移出后,再从右边重新开始显示。
三.程序设计原理
(1) 新建一个QuartusⅡ工程。
(2) 建立一个VHDL文件,实现所要求的电路:
将8个7位寄存器按流水线的形式排列,即第一个寄存器的输出作为第二个寄存器的输入,第二个寄存器的输出作为第三个寄存器的输入,依此类推。每个寄存器的输出同时驱动七段数码管显示。请设计一个状态机对寄存器流水线进行以下控制:
(i) 在前8个时钟,FSM将字符“H,E,L,L,O, , , ”分别插入8个7位寄存器。
(ii) 第(i)步完成后,将寄存器流水线配置成循环模式,即最后一个寄存器的输出作为第一个寄存器的输入,使字符可以无限循环显示。
输入的时钟信号由可控分频器控制,频率范围1~10HZ。
(3) 将VHDL文件添加到工程中,编译工程并对电路进行仿真,确定其功能的正确性。
(4) 分配引脚。在HEX7~HEX0上循环显示“HELLO”。
(5) 重新编译工程,将电路下载到DE2平台上并测试其功能。
四.程序流程图
五.源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNTBCD IS
PORT(CLK,RST,EN:IN STD_LOGIC;
COUNT:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LED7SA,LED7SB,LED7SC,LED7SD,LED7SE:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END CNTBCD;
ARCHITECTURE behav OF CNTBCD IS
SIGNAL CLK2,FULL,FOUT:STD_LOGIC;
SIGNAL A,B,C,D,E:INTEGER;
SIGNAL TMP1,TMP2,TMP3,TMP4,TMP5:INTEGER;
BEGIN
CLK0:PROCESS(CLK)
VARIABLE CNT23:STD_LOGIC_VECTOR(23 DOWNTO 0);
BEGIN
IF CLK'EVENT AND CLK='1' THEN
CNT23:=CNT23+1;
END IF;
IF CNT23(10)='1' THEN
CLK2<='1';
ELSE CLK2<='0';
END IF;
END PROCESS CLK0;
P_REG:PROCESS(CLK2)
VARIABLE CNT8:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
IF CLK2'EVENT AND CLK2='1' THEN
IF CNT8="11111111" THEN
CNT8:=COUNT;
FULL<='1';
ELSE CNT8:=CNT8+1;
FULL<='0';
END IF;
END IF;
END PROCESS P_REG;
P_DIV: PROCESS(FULL)
VARIABLE CNT2:STD_LOGIC;
BEGIN
IF FULL'EVENT AND FULL='1' THEN
CNT2:=NOT CNT2;
IF CNT2='1' THEN FOUT<='1';ELSE FOUT<='0';
END IF;
END IF;
END PROCESS P_DIV;
PROCESS(FOUT,RST,EN)
BEGIN
TMP1<=A;
TMP2<=B;
TMP3<=C;
TMP4<=D;
TMP5<=E;
IF RST='1' THEN A<=3;B<=2;C<=2;D<=1;E<=0;
ELSIF FOUT'EVENT AND FOUT='1' THEN
IF EN='1' THEN
A<=TMP2;
B<=TMP3;
C<=TMP4;
D<=TMP5;
E<=TMP1;
TMP1<=A;
TMP2<=B;
TMP3<=C;
TMP4<=D;
TMP5<=E;
END IF;
END IF;
END PROCESS;
PROCESS(A)
BEGIN
CASE A IS
WHEN 0 => LED7SA<="0001001";
WHEN 1 => LED7SA<="0000110";
WHEN 2 => LED7SA<="1000111";
WHEN 3 => LED7SA<="1000000";
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
PROCESS(B)
BEGIN
CASE B IS
WHEN 0 => LED7SB<="0001001";
WHEN 1 => LED7SB<="0000110";
WHEN 2 => LED7SB<="1000111";
WHEN 3 => LED7SB<="1000000";
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
PROCESS(C)
BEGIN
CASE C IS
WHEN 0 => LED7SC<="0001001";
WHEN 1 => LED7SC<="0000110";
WHEN 2 => LED7SC<="1000111";
WHEN 3 => LED7SC<="1000000";
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
PROCESS(D)
BEGIN
CASE D IS
WHEN 0 => LED7SD<="0001001";
WHEN 1 => LED7SD<="0000110";
WHEN 2 => LED7SD<="1000111";
WHEN 3 => LED7SD<="1000000";
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
PROCESS(E)
BEGIN
CASE E IS
WHEN 0 => LED7SE<="0001001";
WHEN 1 => LED7SE<="0000110";
WHEN 2 => LED7SE<="1000111";
WHEN 3 => LED7SE<="1000000";
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
END behav;
六.调试过程
根据上述的代码对引脚进行分配,可以得到和实验要求相吻合的结果。
同时在模拟器上进行波形的模拟可以得到的如下的波形。这里为了得到更能体现出实验的结果,将END TIME 设置为5S,时钟设置为20ns,其他的设置和上一次实验一样,这里不在赘述。得到的波形如下所示:
七.遇到的问题及解决方法
由于本次是基于上一次的实验的基础上进行的,所以没有遇到比较大的问题。就是模拟的时间太长了。将END TIME设置为50MS,模拟的时间也需要12分钟,这也太可怕了。
在模拟器上模拟波形时,所分频和在硬件上的分频是有区别的,在硬件上,应该让用户看到这种变化,一边就是20mS的停留时间以上,而在模拟器上尽量使得时间短一点,这样才不至于要一直等。
八.参考文献
EDA技术与VHDL(第二版) 潘松 黄继业 编著