为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

VHDL程序设计

2017-10-06 46页 doc 95KB 32阅读

用户头像

is_654168

暂无简介

举报
VHDL程序设计VHDL程序设计 本章提要:本章介绍了数字系统设计中经常用到的计数器,分频器,选择器,译码器,编码 学习要求:在教师讲授这些基本单元电路的设计思想的基础上,通过上机调试熟 练掌握这些基本单元电路的设计。 关键词:计数器(Counter),分频器(Divder),选择器(Multiplexer),译码器 (Decoder),编码器(Encoder),寄存器(Register),存储器(Memory),输入电路( Input Circuit),显示电路(Display Circuit) 6.1 计数器的设计 6.1...
VHDL程序设计
VHDL程序设计 本章提要:本章介绍了数字系统设计中经常用到的计数器,分频器,选择器,译码器,编码 学习要求:在教师讲授这些基本单元电路的设计思想的基础上,通过上机调试熟 练掌握这些基本单元电路的设计。 关键词:计数器(Counter),分频器(Divder),选择器(Multiplexer),译码器 (Decoder),编码器(Encoder),寄存器(Register),存储器(Memory),输入电路( Input Circuit),显示电路(Display Circuit) 6.1 计数器的设计 6.1.1 同步计数器的设计 6.1.2 异步计数器的设计 6.2 分频器的设计 6.3 选择器的设计 6.4 译码器的设计 6.5 编码器的设计 6.5.1 一般编码器的设计 6.5.2 优先级编码器的设计 6.6 寄存器的设计 6.6.1 数码寄存器的设计 6.6.2 移位寄存器的设计 6.6.3 并行加载移位寄存器的设计 6.7 存储器的设计 6.7.1 只读存储器ROM的设计 6.7.2 读写存储器SRAM的设计 6.8 输入电路的设计 6.8.1 键盘扫描电路的设计 6.8.2 键盘接口电路的设计 6.9 显示电路的设计 6.9.1 数码管静态显示电路的设计 6.9.2 数码管动态显示电路的设计 6.9.2 液晶显示控制电路的设计 6.1 计数器的设计 计数器是在数字系统中使用最多的时序电路,它不仅能用于对时钟脉冲计数,还可以用于分频,定时,产生节拍脉冲和脉冲序列以及进行数字运算等。计数器是一个典型的时序电路,计数器就能更好地了解时序电路的特性。计数器分同步计数器和异步计数器两种。 6.1.1 同步计数器的设计 所谓同步计数器,就是在时钟脉冲(计数脉冲)的控制下,构成计数器的各触发器状态同时发生变化的那一类计数器。 1) 六十进制计数器 众所周知,用一个4位二进制计数器可构成1位十进制计数器,而2 位十进制计数器连接起来可以构成一个六十进制的计数器。六十进制计数 器常用于时钟计数。一个六十进制计数器的外部端口示意图如图6.1所示。 在该六十进制计数器的电路中,BCDLWR和BCD10WR 与DATAIN配合,以实现对六十进制计数器的个位和十位值的预置操 作。应注意,在对个位和十位进行预置操作时,DATAIN输入端是公用的, 因而个位和十位的预置操作必定要串行进行。利用VHDL语言描述六十进 制计数器的程序如例6.1所示。 图6.1 六十进制计数器外部端口示意图 【例6.1】 用VHDL设计一个六十进制计数器(方法1)。 --BCD60COUNT.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY BCD60COUNT IS PORT(CLK,BCD1WR,BCD10WR,CIN:STD_LOGIC; CO:OUT STD_LOGIC; DATAIN:IN STD_LOGIC_VECTOR (3 DOWNTO 0); BCD1:OUT STD_LOGIC_VECTOR (3 DOWNTO 0); BCDI0:OUT STD_LOGIC_VECTOR (2 DOWNTO 0)); END BCD60COUNT; ARCHITECTURE RTL OF BCD60COUNT IS SIGNAL BCD1N:STD_LOGIC_VECTOR (3 DOWNTO 0); SIGNAL BCD10N:STD_LOGIC_VECTOR (2 DOWNTO 0); BEGIN BCD1<=BCD1N; BCDI0<=BCD10N; PROCESS (CLK,BCD1WR) –-个位数处理进程 BEGIN IF (BCD1WR='1') THEN BCD1N<=DATAIN; ELSIF (CLK'EVENT AND CLK='1') THEN IF (CIN='1') THEN IF (BCD1N=9) THEN BCD1N<="0000"; ELSE BCD1N<=BCD1N+1; END IF; END IF; END IF; END PROCESS; PROCESS (CLK,BCD10WR) –-十位数处理进程 BEGIN IF (BCD10WR='1') THEN BCD10N<=DATAIN (2 DOWNTO 0); ELSIF (CLK'EVENT AND CLK='1') THEN IF (CIN='1' AND BCD1N=9) THEN IF (BCD10N=5) THEN BCD10N<="000"; ELSE BCD10N<=BCD10N+1; END IF; END IF; END IF; END PROCESS; PROCESS (BCD10N,BCD1N,CIN) –-进位位处理进程 BEGIN IF (CIN='1' AND BCD1N=9 AND BCD10N=5) THEN CO<='1'; ELSE CO<='0'; END IF; END PROCESS; END RTL; 【例6.2】 用VHDL设计一个六十进制计数器(方法2)。 --COUNTER60.vhd LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COUNTER60 IS PORT(CP: IN STD_LOGIC; --时钟脉冲 BIN: OUT STD_LOGIC_VECTOR (5 DOWNTO 0); --二进制 S: IN STD_LOGIC; --输出启动信号 CLR: IN STD_LOGIC; --清除信号 EC: IN STD_LOGIC; --使能计数信号 CY60: OUT STD_LOGIC );--计数60进位信号 END COUNTER60; ARCHITECTURE RTL OF COUNTER60 IS SIGNAL Q : STD_LOGIC_VECTOR (5 DOWNTO 0) ; SIGNAL RST, DLY : STD_LOGIC; BEGIN PROCESS (CP,RST) -- 计数60 BEGIN IF RST = '1' THEN Q <= "000000"; -- 复位计数器 ELSIF CP'EVENT AND CP = '1' THEN DLY <= Q(5); IF EC = '1' THEN Q <= Q+1; -- 计数值加1 END IF; END IF; END PROCESS; CY60 <= NOT Q(5) AND DLY; -- 进位信号微分 RST <= '1' WHEN Q=60 OR CLR='1' ELSE -- 复位信号设定 '0'; BIN <= Q WHEN S = '1' ELSE -- 计数输出 "000000"; END RTL ; 2) 可逆计数器 在时序应用电路中,计数器的应用十分普遍,如加法计数器,减法计数器,可逆计数器等。所谓可逆计数器,就是根据计数控制信号的不同,在时钟脉冲作用下,计数器可以进行加1或者减1操作的一种计数器。可逆计数器有一个特殊的控制端,这就是UPDN端。当UPDN=‘1’时,计数器进行加1操作,当UPDN=‘0’时,计数器就进行减1操作。6.1是一个3位可逆计数器的真值表,它的VHDL语言描述如例6.3所示。 表6.1 可逆计数器真值表 输入端 输出端 DIR CP Q2 Q1 Q0 X X 0 0 0 1 计数器加1操作 0 计数器减1操作 【例6.3】 用VHDL设计一个3位二进制的可逆计数器。 --COUNT3.vhd LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COUNT3 IS PORT (CP,DIR:IN STD_LOGIC; Q: OUT STD_LOGIC_VECTOR(2 DOWNTO 0)); END; ARCHITECTURE RTL OF COUNT3 IS SIGNAL QN:STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN PROCESS(CP) BEGIN IF CP'EVENT AND CP='1' THEN IF DIR='0' THEN QN<=QN +1; ELSE QN<=QN-1; END IF ; END IF; END PROCESS; Q<=QN; END RTL; 编写可逆计数器VHDL程序时,在语法上,就是把加法和减法计数器合并,使用一个控制信号决定计数器作加法或减法的动作。在本例中,利用“控制信号DIR”可以让计数器的计数动作加1或减1。 6.1.2 异步计数器的设计 异步计数器又称行波计数器,它将低/高位计数器的输出做为高/低位计数器的时钟信号,这一级一级串行连接起来就构成了一个异步计数器。异步计数器与同步计数器不同之处就在于时钟脉冲的提供方式,但是,由于异步计数器采用行波计数,从而使计数延迟增加,在要求延迟小的领域受到了很大限制。尽管如此,由于它的电路简单,仍有广泛的应用。图6.2是用VHDL语言描述的一个由8个触发器构成的异步计数器.它的程序如例6.4所示,采用元件例化方式生成。与上述同步计数器不同之处主要表现在对各级时钟脉冲的描述上,这一点请读者在阅读程序时多加注意。 图6.2 8位异步计数器原理图 【例6.4】 用VHDL设计一个由8个触发器构成的8位二进制异步计数器。 --RPLCONT.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DFFR IS PORT(CLK,CLR,D:IN STD_LOGIC; Q,QB:OUT STD_LOGIC); END ENTITY DFFR; ARCHITECTURE ART1 OF DFFR IS SIGNAL Q_IN:STD_LOGIC; BEGIN QB<=NOT Q_IN; Q<=Q_IN; PROCESS(CLK,CLR) IS BEGIN IF (CLR='1') THEN Q_IN<='0'; ELSIF (CLK'EVENT AND CLK='1') THEN Q_IN<=D; END IF ; END PROCESS; END ARCHITECTURE ART1; LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY RPLCONT IS PORT(CLK,CLR:IN STD_LOGIC; COUNT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END ENTITY RPLCONT; ARCHITECTURE ART2 OF RPLCONT IS SIGNAL COUNT_IN_BAR:STD_LOGIC_VECTOR(8 DOWNTO 0); COMPONENT DFFR IS PORT(CLK,CLR,D:IN STD_LOGIC; Q,QB:OUT STD_LOGIC); END COMPONENT; BEGIN COUNT_IN_BAR(0)<=CLK; GEN1:FOR I IN 0 TO 7 GENERATE U:DFFR PORT MAP (CLK=>COUNT_IN_BAR(I),CLR=>CLR, D=>COUNT_IN_BAR(I+1),Q=>COUNT(I),QB=>COUNT_IN_BAR(I+1)); END GENERATE; END ARCHITECTURE ART2; 6.2 分频器的设计 一般来说,可以把加法计数器看成一种分频电路,而且是除2的N的 次方的分频电路。 但是也常常会有除M(M不是2的N次方)的分频电路 需求. 下面就介绍一个除6的加法分频电路。先建立一个计数器,而这个计 数器的大小必须是3位(计数默认范围是0,2^3-1=7),不过将把这样的计 数值为6的瞬间,立即复位改变为0,其VHDL程序如例6.5所示 【例6.5】 用VHDL设计一个除6的加法分频电路。 --COUNT6.vhd LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COUNT6 is PORT(CP: IN STD_LOGIC; Result: OUT STD_LOGIC); END COUNT6; ARCHITECTURE a OF COUNT6 IS SIGNAL RST: STD_LOGIC; SIGNAL QN: STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN PROCESS (CP,RST) -- *** COUNTER BEGIN IF RST = '1' THEN QN <= "000"; --Reset Counter ELSIF CP'event AND CP='1' THEN QN <= QN + 1; --COUNTER + 1 END IF; END PROCESS; RST <= '1' WHEN QN = 6 ELSE -- RESET COUNTER '0'; Result <= QN(2); -- Result Output END a; 以后遇到需要分频是N 的同步计数器,需将上述QN=6改成QN=N,而且计数器X bits数 需调整为符合条件2X>=N才可以。 6.3 选择器的设计 多路选择器可以从多组数据来源中选取一组送入目的地。它的应用范围相当广泛,从组合逻辑的执行,到数据路径的选择,经常可以看到它的踪影。另外在像时钟,计数定时器等的输出显示电路中都可以看到利用多路选择器制作扫描电路来分别驱动输出装置(通常为七段数码显示管,点矩阵或液晶面板),以降低功率的消耗。有时也希望把两组没有必要同时观察的数据,共享一组显示电路,以降低成本。 多路选择器的结构是2N个输入线,会有N个地址选择线及一个输出线配合。现以一个四选一的多路选择器为例,其四选一电路的真值表如表6.2所示,其外部端口示意图如图6.3所示。 表6.2 四选一电路真值表 选择输入 数据输入 数据输出 b a Input(0) Input(1) Input(2) Input(3) y 0 0 0 X X X 0 0 0 1 X X X 1 0 1 X 0 X X 0 0 1 X 1 X X 1 1 0 X X 0 X 0 1 0 X X 1 X 1 1 1 X X X 0 0 1 1 X X X 1 1 图6.3 四选一电路外部端口示意图 描述四选一多路选择器的方法有多种,例如在一个进程中使用if-then-else语句;在一个进程中使用case语句;使用with select构造或使用结构VHDL。现用if-then-else语句对它进行描述,就可以得到如例6.6所示的程序。 【例6.6】设计一个四选一的多路选择器的VHDL程序(使用if-then-else语句)。 --MUX4.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MUX4 IS PORT(DATA0,DATA1,DATA2,DATA3:IN STD_LOGIC_VECTOR(3 DOWNTO 0); A,B:IN STD_LOGIC; Y:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY MUX4; ARCHITECTURE ART OF MUX4 IS SIGNAL SEL:STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN SEL<=B&A; PROCESS(SEL) BEGIN IF (SEL="00") THEN Y<=DATA0; ELSIF(SEL="01") THEN Y<=DATA1; ELSIF(SEL="10") THEN Y<=DATA2; ELSE Y<=DATA3; END IF; END PROCESS; ARCHITECTURE ART; 例6.6中的四选一选择器是用IF语句描述的,程序中的ELSE项作为余下的条件,将选择INPUT (3)从Y端输出,这种描述比较安全。当然,不用ELSE项也可以,这时必须列出SEL的所有可能出现的情况,加以一一确认。在进程中使用CASE语句会更清晰易读。例6.7是用CASE语句描述的四选一选择器。 【例6.7】设计一个四选一的多路选择器的VHDL程序(使用case语 句)。 --MUX4.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MUX4 IS PORT(DATA0,DATA1,DATA2,DATA3:IN STD_LOGIC_VECTOR(3 DOWNTO 0); A,B:IN STD_LOGIC; Y:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY MUX4; ARCHITECTURE ART OF MUX4 IS SIGNAL SEL:STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN SEL<=B&A; PROCESS(SEL) BEGIN CASE SEL IS WHEN "00"=>Y<=DATA0; WHEN "01"=>Y<=DATA1; WHEN "10"=>Y<=DATA2; WHEN "11"=>Y<=DATA3; WHEN OTHERS =>Y<=NULL; END CASE; END PROCESS; END ARCHITECTURE ART; 【例6.8】设计一个四选一的多路选择器的VHDL程序(使用WHEN-ELSE并行条件赋值语句)。 --MUX4.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MUX4 IS PORT(DATA0,DATA1,DATA2,DATA3:IN STD_LOGIC_VECTOR(3 DOWNTO 0); A,B:IN STD_LOGIC; Y:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY MUX4; ARCHITECTURE ART OF MUX4 IS SIGNAL SEL : STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN SEL<=B&A; Y<= DATA0 WHEN SEL="00" ELSE DATA1 WHEN SEL="01" ELSE DATA2 WHEN SEL="10" ELSE DATA3 WHEN SEL="11" ELSE '0' ; END ARCHITECTURE ART ; 6.4 译码器的设计 译码器是把输入的数码解出其对应的数码,如果有N个二进制选择线,则最多可以译码转换成2N个数据。译码器也经常被应用在地址总线或用作电路的控制线。像只读存储器(ROM)中便利用译码器来进行地址选址的工作。 3-8译码器是最常用的种小规模集成电路。3-8译码器外部端口示意图如图6.9所示,它有3个二进制输入端a, b,c和8个译码输出端y0~y7。对输入a,b,c的值进行译码,就可以确定输出端y0~y7的哪一个输出端变为有效(低电平),从而达到译码的目的。另外为方便译码器的控制或便于将来扩充用,在设计时常常会增加一个EN使能输入脚。3-8译码器的真值表如表6.3所示。有了真值表,就可以直接用查表法来设计。 在VHDL 中,“WITH?SELECT”,“CASE?WHEN”及“WHEN?ELSE”这类指令都是执行查表或对应动作的能手。 图6.4 3-8译码器外部端口示意图 表6.3 3-8译码器的真值表使能 二进制输入端 译码输出端 en c b a y0 y1 y2 y3 y4 y5 y6 y7 0 x x x 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 【例6.9】 用VHDL设计一个3-8译码器(用“CASE?WHEN”语句)。 --DECODER38.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DECODER38 IS PORT (A,B,C, EN : IN STD_LOGIC; Y : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END DECODER38 ; ARCHITECTURE RTL OF DECODER38 IS SIGNAL INDATA :STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN INDATA<=C&B&A; PROCESS (INDATA,EN) BEGIN IF (EN='1')THEN CASE INDATA IS WHEN "000" =>Y<="11111110"; WHEN "001" =>Y<="11111101"; WHEN "010" =>Y<="11111011"; WHEN "011" =>Y<="11110111"; WHEN "100" =>Y<="11101111"; WHEN "101" =>Y<="11011111"; WHEN "110" =>Y<="10111111"; WHEN "111" =>Y<="01111111"; WHEN OTHERS=>Y<=NULL; END CASE; ELSE Y<="11111111"; END IF; END PROCESS; END RTL; 【例6.10】 用VHDL设计一个3-8译码器(用“WITH?SELECT”语句)。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.All; ENTITY DECODER38 IS PORT (A,B,C, EN : IN STD_LOGIC; Y : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END DECODER38; ARCHITECTURE RTL OF DECODER38 IS SIGNAL INDATA :STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN INDATA<=EN&C&B&A; --将EN,A,B,C合并成序列的一种写法 WITH INDATA SELECT Y<="11111110" WHEN "1000", "11111101" WHEN "1001", "11111011" WHEN "1010", "11110111" WHEN "1011", "11101111" WHEN "1100", "11011111" WHEN "1101", "10111111" WHEN "1110", "01111111" WHEN "1111", "11111111" WHEN OTHERS; END RTL; 在本节中用到的两种描述语句,“WITH?SELECT”是并行同时性语句,“CASE?WHEN”是与其功能相同的顺序性语句,读者在使用时一定要确定需要的是顺序性语句还是并行性语句,否则程序在编译时会发生错误。 6.5 编码器的设计 编码器是将2^N个分离的信息代码以N个二进制码来表示。它的功能和译码器正好相反。编码器常常运用于影音压缩或通信方面,以达到精简传输量的目的。可以将编码器看成压缩电路,译码起看成解压缩电路。传送数据前先用编码器压缩数据后在传送出去,在接收端则由译码器将数据解压缩,还原其原来的数据。这样,在传送过程中,就可以以N个数码来 代替2^N个数码的数据量,来提升传输效率。 6.5.1 一般编码器的设计 如果没有特别说明,各编码输入端无优先区别。图6.5是8-3编码器的外部端口图,有了外部端口图,就能够做ENTITY的定义,再根据编码器的真值表如表6.4所示.,再使用查表法就可以轻松描述结构体了。 图6.5 8-3编码器外部端口图 表6.4 8-3编码器的真值表 输入 二进制编码输出 A7 A6 A5 A4 A3 A2 A1 A0 Y2 Y1 Y0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 0 0 0 【例6.11】用VHDL设计一个8-3编码器。 --CH_8_3.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY CH_8_3 IS PORT (A :IN STD_LOGIC_VECTOR(7 DOWNTO 0); Y :OUT STD_LOGIC_VECTOR(2 DOWNTO 0)); END CH_8_3; ARCHITECTURE RTL OF CH_8_3 IS BEGIN WITH A SELECT Y<="000" WHEN "11111110", "001" WHEN "11111101", "010" WHEN "11111011", "011" WHEN "11110111", "100" WHEN "11101111", "101" WHEN "11011111", "110" WHEN "10111111", "111" WHEN "01111111", "000" WHEN OTHERS; END RTL; 6.5.2 优先级编码器的设计 优先级编码器长用于中断的优先级控制,例如,74LS148是一个8输入,3位二进制码输出的优先级编码器。当其某一个输入有效时,就可以输出一个对应的3位二进制编码。另外,当同时有几个输入有效时, 将输优先级最高的那个输入所对应的二进制编码。 该优先级编码器的真值表如表6. 5所示。表中的“X”项表示任意项, 它可以是“0”,也可以是“1”。INPUT(0)的优先级最高,INPUT(7)的优先级最低。 表6.5 优先级编码器真值表 输入 二进制编码输出 Input(7) Input(6) Input(5) Input(4) Input(3) Input(2) Input(1) Input(0) Y2 Y1 Y0 X X X X X X X 0 1 1 1 X X X X X X 0 1 1 1 0 X X X X X 0 1 1 1 0 1 X X X X 0 1 1 1 1 0 0 X X X 0 1 1 1 1 0 1 1 X X 0 1 1 1 1 1 0 1 0 X 0 1 1 1 1 1 1 0 0 1 X 1 1 1 1 1 1 1 0 0 0 【例6.12】 用VHDL设计一个8-3优先级编码器。 -- CH8_3.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY CH8_3 IS PORT (INPUT :IN STD_LOGIC_VECTOR(7 DOWNTO 0); Y: OUT STD_LOGIC_VECTOR(2 DOWNTO 0)); END CH8_3; ARCHITECTURE RTL OF CH8_3 IS BEGIN PROCESS(INPUT) BEGIN IF (INPUT(0)='0') THEN Y<="111"; ELSIF (INPUT(1)='0' THEN Y<="110"; ELSIF (INPUT(2)='0' THEN Y<="101"; ELSIF (INPUT(3)='0' THEN Y<="100"; ELSIF (INPUT(4)='0' THEN Y<="011"; ELSIF (INPUT(5)='0' THEN Y<="010"; ELSIF (INPUT(6)='0' THEN Y<="001"; ELSIF Y<="000"; END IF; END PROCESS; END RTL; 6.6 寄存器的设计 寄存(锁存)器是一种重要的数字电路部件,常用来暂时存放指令、参与运算的数据或运算结果等。它是数字测量和数字控制中常用的部件,是计算机的主要部件之一。寄存器的主要组成部分是具有记忆功能的双稳态触发器。一个触发器可以储存一位二进制代码,要储存N位二进制代码,就在有N个触发器。寄存器从功能上说,通常可分为数码寄存器和移位寄存器两种。 6.6.1 数码寄存器的设计 数码寄存器用于寄存一组二进制代码,广泛用于各类数字系统。下面给出—个8位寄存器的VHDL描述。 【例6.13】 用VHDL设计一个8位的数码寄存器。 --REG.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY REG IS PORT(D:IN STD_LOGIC_VECTOR(7 TO 0); CLK:IN STD_LOGIC; Q:OUT STD_LOGIC_VECTOR(7 TO 0)); END ENTITY REG; ARCHITECTURE ART OF REG IS BEGIN PROCESS(CLK) IS BEGIN IF(CLK'EVENT AND CLK='1')THEN Q<=D; END IF; END PROCESS; END ARCHITECTURE ART; 6.6.2 移位寄存器的设计 移位寄存器除了具有存储代码的功能以外,还具有移位功能。所谓移位功能,是指寄存器里存储的代码能在移位脉冲的作用下依次左移或右移。因此,移位寄存器不但可以用来寄存代码,还可用来实现数据的串并转换、数值的运算以及数据处理等。下面给出一个8位的移位寄存器,其具有左移一位或右移一位、并行输入和同步复位的功能。 【例6.14】用VHDL设计一个8位的移位寄存器,其具有左移一位或右移一位、并行输入和同步复位的功能. --SHIFT_REG.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY SHIFT_REG IS PORT(DATA:IN STD_LOGIC_VECTOR(7 DOWNTO 0); CLK:IN STD_LOGIC; SHIFT_LEFT,SHIFT_RIGHT:IN STD_LOGIC; RESET:IN STD_LOGIC; MODE:IN STD_LOGIC_VECTOR(1 DOWNTO 0); QOUT:BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0)); END ENTITY SHIFT_REG; ARCHITECTURE ART OF SHIFT_REG IS BEGIN PROCESS IS BEGIN WAIT UNTIL(RISING_EDGE(CLK)); IF(RESET='1')THEN QOUT<="00000000"; ELSE --同步复位功能的实现 CASE MODE IS WHEN "01"=>QOUT<=SHIFT_RIGHT&QOUT(7 DOWNTO 1);--右移一位 WHEN "10"=>QOUT<=QOUT(6 DOWNTO 0)&SHIFT_LEFT; --左移一位 WHEN "11"=>QOUT<=DATA; --并行输入 WHEN OTHERS=>NULL; END CASE; END IF; END PROCESS; END ARCHITECTURE ART; 6.6.3 并行加载移位寄存器的设计 在TTL手册中的74LS166是一个带清零端的8位并行加载的移位寄存器,其引脚图及逻辑图如图6.6所示。 图6.6 74LS166的引脚图及逻辑图 图中各引脚名称和功能如下: A,B,C,D,E,F,G,H:8位并行数据输入端; SER:串行数据输入端; QH:串行数据输出端; CLK: 时钟信号输入端; CLKINH:时钟信号禁止(FE)端; SH/LD:移位加载控制(SL)端; CLR:清零端。 当清零输入端CLR为‘0’时,8个触发器的输出均为‘0’,从而使输出Q为‘0’。CLKINH是时钟禁止端,当它为‘1’时将禁止时钟,即不管时钟信号如何变化,移位寄存器的状态不发生改变。另外,时钟信号只在上升沿时才有效,且CLKINH 为‘0’。当控制端SH/LD =‘1’时是移位状态,在时钟脉冲上升沿的控制下右移,当SH/LD =‘0’时是加载状态, 在时钟脉冲上升沿的作用下,数据输入端A,H的信号就是装载到移位寄存器的QA,QH。根据上述描述,就可以用VHDL语言编写出描述74166功能的程序。 【例6.15】用VHDL设计的带清零端的8位并行加载的移位寄存器 74LS166。 -- SREG8PARLWCLR.VHD LIBRARY IEEE; USE IEEE. STD _ LOGIC _ 1164. ALL; ENTITY SREG8PARLWCLR IS PORT(CLR, SL, FE, CLK, SER: IN STD_ LOGIC; A, B, C, D, E, F,G, H: IN STD_ LOGIC; Q: OUT STD_ LOGIC); END SREG8PARLWCLR; ARCHITECTURE BEHAV OF SREG8PARLWCLR IS STD _ LOGIC _ VECTOR (7 DOWNTO O); SIGNAL TMPREG8: BEGIN PROCESS (CLK, SL, FE, CLR) IF (CLR= ?0?) THEN TMPREG8< = “00000000”; Q< = TMPREG8 (7); ELSIF (CLK?EVENT) AND (CLK= ?1?) AND (FE = ?0?)THEN IF (SL= ?0?) THEN TMPREG8 (0)< =A; TMPREG8 (1)< =B; TMPREG8 (2)< =C; TMPREG8 (3)< =D; TMPREG8 (4)< =E; TMPREG8 (5)< =F; TMPREG8 (6)< =G; TMPREG8 (7)< =H; Q< = TMPREG8 (7); ELSIF (SL =?1?)THEN FOR I IN TMPREG8?HIGH DOWNTO TMPREG8?LOW+ 1 LOOP TMPREG8 (I)< = TMPREG8(I- 1); END LOOP; TMPREG8 (TMPREG8’LOW) < = SE; Q< = TMPREG8 (7); END IF; END IF; END PROCESS; END BEHAV; 6.7 存储器的设计 半导体存储器的种类很多,从功能上可以分为只读存储器(READ_ONLY MEMORY,简称ROM)和随机存储器(RANDOM ACCESS MEMORY,简称RAM)两大类。 6.7.1 只读存储器ROM的设计 只读存储器在正常工作时从中读取数据,不能快速地修改或重新写入数,适用于存储固定数 据的场合。下面是一个容量为256×4的ROM存储的例子,该ROM有8位地址线ADR(0),ADR(7),4位数据输出线DOUT(0),DOUT(3)及使能EN,如图6. 7所示。 图6. 7 ROM 【例6.16】 用VHDL设计一个一个容量为256×4的ROM存储的例子,该ROM有8位地址线ADR(0),ADR(7),4位数据输出线DOUT(0),DOUT(3)及使能EN。 -- ROM.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE STD.TEXTIO.ALL; ENTITY ROM IS PORT(EN:IN STD_LOGIC; ADR:IN STD_LOGIC_VECTOR(7 DOWNTO 0); DOUT: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY ROM; ARCHITECTURE ART OF ROM IS SUBTYPE WORD IS STD_LOGIC_VECTOR(3 DOWNTO 0); TYPE MEMORY IS ARRAY(0 TO 255) OF WORD; SIGNAL ADR_IN:INTEGER RANGE 0 TO 255; VARIABLE ROM:MEMORY; VARIABLE START_UP:BOOLEAN:=TRUE; VARIABLE L:LINE; VARIABLE J:INTEGER; FILE ROMIN:TEXT IS IN “ROMIN”; BEGIN PROCESS(EN,ADR) IS BEGIN IF START_UP THEN --初始化开始 FOR J IN ROM?RANGE LOOP READLINE(ROMIN,1); READ(1,ROM(J)); END LOOP; START_UP:=FALSE; --初始化结束 END IF; ADR_IN<=CONV_INTEGER(ADR); --将向量转化成整数 IF(EN=?1?)THEN DOUT<=ROM(ADR_IN); ELSE DOUT<=“ZZZZ”; END IF; END PROCESS; END ARCHITECTURE ART; 6.7.2 读写存储器SRAM的设计 RAM和ROM的主要区别在于RAM描述上有读和写两种操作,而且在 读写上对时间有较严格的要求。下面我们给出一个8×8位的双口SRAM的 VHDL描述实例,如图6.8所示。 图6. 8 双口SRAM 【例6.17】 用VHDL设计一个8×8位的双口SRAM。 --DPRAM.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY DPRAM IS GENERIC(WIDTH:INTEGER :=8; DEPTH:INTEGER :=8; ADDER:INTEGER :=3); PORT(DATAIN:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); DATAOUT:OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); CLOCK:IN STD_LOGIC; WE,RE:IN STD_LOGIC; WADD:IN STD_LOGIC_VECTOR(ADDER-1 DOWNTO 0); RADD:IN STD_LOGIC_VECTOR(ADDER-1 DOWNTO 0)); END ENTITY DPRAM; ARCHITECTURE ART OF DPRAM IS TYPE MEM IS ARRAY(DEPTH-1 TO 0) OF STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); SIGNAL RAMTMP:MEM; BEGIN --写进程 PROCESS(CLOCK) IS BEGIN IF (CLOCK'EVENT AND CLOCK='1') THEN IF(WE='1')THEN RAMTMP(CONV_INTEGER(WADD))<=DATAIN; END IF; END IF; END PROCESS; --读进程 PROCESS(CLOCK) IS BEGIN IF(CLOCK'EVENT AND CLOCK='1')THEN IF (RE='1') THEN DATAOUT<=RAMTMP(CONV_INTEGER(RADD)); END IF; END IF; END PROCESS; END ARCHITECTURE ART; 6.8 输入电路的设计 6.8.1 键盘扫描电路的设计 计算机控制系统中,数据和控制信号的输入主要使用键盘。下面给出 —个键盘扫描电路VHDL描述。 【例6.18】 用VHDL设计一个键盘扫描电路。 -- KSCAN.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY KSCAN IS PORT(CLK: IN STD_LOGIC; KIN1,KIN2 : IN STD_LOGIC; LEDA,LEDB,LEDC: OUT STD_LOGIC; LEDD : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END KSCAN; ARCHITECTURE HAV OF KSCAN IS SIGNAL SEG : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL SEL : STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL KNUM : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL COUNT: STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL COUNT0: STD_LOGIC; BEGIN LEDD<=SEG; PROCESS(CLK) BEGIN IF CLK?EVENT AND CLK=?1? THEN COUNT<=COUNT+1; END IF; END PROCESS; COUNT0<=COUNT(0); PROCESS(COUNT0,COUNT,KIN1,KIN2) BEGIN IF COUNT0?EVENT AND COUNT0=?1?THEN IF (KIN2=?0?) AND COUNT(1)=?0?THEN KNUM<=‘1’ & COUNT(4 DOWNTO 2); ELSIF (KIN1=?0?) AND COUNT(1)=?0?THEN KNUM<=‘0’ & COUNT (4 DOWNTO 2); END IF; END IF; END PROCESS; SEL<=COUNT (4 DOWNTO 2); PROCESS(KNUM) BEGIN CASE KNUM IS WHEN “0000” => SEG<=“00111111”; WHEN “0001” => SEG<=“00000110”; WHEN “0010” => SEG<=“01011011”; WHEN “0011” => SEG<=“01001111”; WHEN “0100” => SEG<=“01100110”; WHEN “0101” => SEG<=“01101101”; WHEN “0110” => SEG<=“01111101”; 00000111”; WHEN “0111” => SEG<=“ WHEN “1000” => SEG<=“01111111”; WHEN “1001” => SEG<=“01101111”; WHEN “1010” => SEG<=“01110111”; WHEN “1011” => SEG<=“01111100”; WHEN “1100” => SEG<=“00111001”; WHEN “1101” => SEG<=“01011110”; WHEN “1110” => SEG<=“01111001”; WHEN “1111” => SEG<=“01110001”; WHEN OTHERS => SEG<=“00000000”; END CASE ; END PROCESS; LEDA<=SEL(0); LEDB<=SEL(1); LEDC<=SEL(2); END HAV; 6.8.2 键盘接口电路的设计 PS,2键盘接口通常使用专用芯片实现。由于PS,2键盘或鼠标串行输出信号速度较高,普通单片机无法接收,现利用VHDL在目标器件FPGA,CPLD上实现一个键码接收部分。PS,2接口的键盘每按下一个键,该键的扫描码即以十六进制形式显示在数码管上。以下为接收PS,2键盘信号的VHDL逻辑描述。 用VHDL设计一个接收PS,2键盘信号的接口电路。 【例6.20】 -- KB2PCL.VHD LIBRARY IEEE; USE IEEE.STD_LOG1C_1164.ALL; ENTITY KB2PCL IS PORT (SYSCLK:IN STD_LOGIC;RESET:IN STD_LOGIC; KBCLK: IN STD_LOGIC;KBDATA:IN STD_LOGIC; PDATA: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); PARITY:OUT STD_LOGIC;DTOE:BUFFER STD_LOGIC); END KB2PC1; ARCHITECTURE ONE OF KB2PC1 IS SIGNAL COSTATE:STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL SPDATA:STD_LOGIC_VECTOR(8 DOWNTO 0); SIGNAL START,SWTO02,RECVEN:STD_LOGIC; SIGNAL CNT8:INTEGER RANGE 0 TO 15; BEGIN SLRL:PROCESS(RESET, KBCLK,KBDATA,STAFF,COSTATE ) BEGIN IF RESET = ?1? THEN START <= ‘0’; ELSIF KBCLK?EVENT AND KBCLK = ?0? THEN IF COSTATE = “00” AND KBDATA = ?0? THEN STAFF <= ‘1’; END IF; END IF; END PROCESS; STR2:PROCESS(RESET, KBCLK,KBDATA,STAFF,COSTATE) BEGIN IF RESET =?1? THEN SWTO02 <=‘0’; ELSIF KBCLK?EVENT AND KBCLK =?1? THEN IF COSTATE = “00” AND START = ?1? AND KBDATA = ?0? THEN SWTO02 <=‘1’; END IF; END IF; END PROCESS; CHSTATE:PROCESS(RESET,SYSCLK,COSTATE,SWTO02) BEGIN IF RESET =?1? THEN COSTATE <=“00”; ELSIF SYSCLK?EVENT AND SYSCLK =?1? THEN IF SWTO02 = ?1? THEN COSTATE <= “01”; ELSIF CNT8 = 9 THEN COSTATE <= “10”; END IF; END IF; END PROCESS; RECV:PROCESS(RESET,KBCLK,KBDATA,COSTATE ) BEGIN IF RESET=?1? THEN CNT8 <= 0;SPDATA <= “000000000”; ELSIF KBCLK?EVENT AND KBCLK = ?0? THEN IF COSTATE= “01” THEN IF CNT8/=9 THEN SPDATA(7 DOWNTO 0 )<= SPDATA(8 DOWNTO 1); SPDATA(8)<= KBDATA; CNT8 <= CNT8 + 1; END IF; END IF; END IF; END PROCESS; RECVEND:PROCESS(RESET,KBCLK,RECVEN,COSTATE ) BEGIN IF RESET =?1? THEN DTOE <= ‘0’; ELSIF KBCLK?EVENT AND KBCLK =?1? THEN IF CNT8 = 9 AND COSTATE = “01” THEN DTOE <=‘1’;END IF; END IF; END PROCESS; PARITY <= SPDATA(8);PDATA <= SPDATA(7 DOWNTO 0); END ONE; 6.9 显示电路的设计 常用的显示器件有发光二极管,数码管,液晶显示器等,其中最常用的为数码管。数码管显示数据的方式有静态显示和动态显示之分。所谓静态显示,就是将被显示的数据的BCD码,通过各自的4-7/8显示译码器译码后,分别接到显示译码器的显示驱动段a-g(p),而公共端COM则根据数码管的类型(共阴/共阳)分别接GND/VCC。动态显示,就是将被显示的数据的BCD码,按照一定的变化频率,在不同的时刻周期性地分别送到一个数据总线上,再通过一个公共的4-7/8显示译码器译码后,接到多个显示译码器的公共显示驱动段a-g(p)上,同时,在不同的时刻周期性地 选通对应的数码管的公共端COM。 6.9.1 数码管静态显示电路的设计 七段数码显示器由7根显示码管组成,对每一根码管,用一位二进制表示。若该数码管的为共阴数码管,则该位为1时,表示此码管发光,如为0,表示此码管不发光,对7根码管编号。共阳数码管则正好相反。下面用一个7位二进制数表示一个七段显示器的编码,其VHDL程序段描述如下: CASE CNT4B IS WHEN 0=> DOUT <= “0111111”; WHEN 1=> DOUT <= “0000110”; WHEN 2=> DOUT <= “1011011”; WHEN 3=> DOUT <= “1001111”; WHEN 4=> DOUT <= “1100110”; WHEN 5=> DOUT <= “1101101”; WHEN 6=> DOUT <= “1111101”; WHEN 7=> DOUT <= “0000111”; WHEN 8=> DOUT <= “1111111”; WHEN 9=> DOUT <= “1101111”; WHEN OTHERS=> DOUT <= “0000000”; END CASE; 下面给出一个4位二进制加法计数器静态显示的VHDL程序。 【例6.21】 用VHDL设计一个4位二进制加法计数器,并将计数结果 用7段LED显示数码管进行静态显示。 --CNTDISPLAY.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNTDISPLAY IS PORT (CLK:IN STD_LOGIC; DOUT:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END DECLED; ARCHITECTURE BEHAV OF CNTDISPLAY IS SIGNAL CNT4B:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(CLK) BEGIN IF CLK?EVENT AND CLK =?1? THEN CNT4B <= CNT4B +1; END IF; END PROCESS; PROCESS(CNT4B) BEGIN CASE CNT4B IS WHEN “0000”=> DOUT <= “0111111”; WHEN “0001”=> DOUT <= “0000110”; WHEN “0010”=> DOUT <= “1011011”; WHEN “0011”=> DOUT <= “1001111”; WHEN “0100”=> DOUT <= “1100110”; WHEN “0101”=> DOUT <= “1101101”; WHEN “0110”=> DOUT <= “1111101”; WHEN “0111”=> DOUT <= “0000111”; WHEN “1000”=> DOUT <= “1111111”; WHEN “1001”=> DOUT <= “1101111”; WHEN “1010”=> DOUT <= “1110111”; WHEN “1011”=> DOUT <= “1111100”; WHEN “1100”=> DOUT <= “0111001”; WHEN “1101”=> DOUT <= “1011110”; WHEN “1110”=> DOUT <= “1111001”; WHEN “1111”=> DOUT <= “1110001”; WHEN OTHERS=> DOUT <= “0000000”; END CASE; END PROCESS; END BEHAV; 6.9.2 数码管动态显示电路的设计 下面我们就通过一个例子来说明数据动态扫描的工作原理和VHDL程 序的设计方法。 【例6.22】用VHDL设计一个8位二进制并行半加器,要求将被加数、加数和加法运算和用动态扫描的方式在共阴数码管上同时显示出,该数据动态扫描显示电路的外围器件接线图 如图6.9所示。 图6(9 数据动态扫描显示电路外围器件接线图 --DISPLAY.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --实体说明 ENTITY DISPLAY IS PORT(CLK:IN STD_LOGIC; --动态扫描显示时钟,24HZ以上 AIN: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --8位被加数 BIN: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --8位加数 SUM0,SUM1,SUM2:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--仿真观测输出 COM:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--数码管COM端的选择输出端 SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --数码管8段显示驱动输出端 END ENTITY DISPLAY; ARCHITECTURE ART OF DISPLAY IS SIGNAL AA, BB,SINT: STD_LOGIC_VECTOR(8 DOWNTO 0); SIGNAL CNT:STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL BCD:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN --进行运算前的准备及加法运算 AA<='0'&AIN; BB<='0'&BIN; SINT<=AA+BB; SUM0<=SINT(3 DOWNTO 0); --运算结果的仿真观测输出 SUM1<=SINT(7 DOWNTO 4); --运算结果的仿真观测输出 SUM2<="000"&SINT(8); --运算结果的仿真观测输出 --产生动态扫描显示的控制信号 PROCESS(CLK) BEGIN IF CLK'EVENT AND CLK='1' THEN IF CNT="111" THEN CNT<="000"; ELSE CNT<=CNT+'1'; END IF ; END IF; END PROCESS; PROCESS(CNT) BEGIN --显示数据的选择,对应显示数码管公共端的选通,低电平有效 CASE CNT IS WHEN "000" =>BCD<=AIN(3 DOWNTO 0);COM<="1111110"; WHEN "001" =>BCD<=AIN(7 DOWNTO 4);COM<="1111101"; WHEN "010" =>BCD<=BIN(3 DOWNTO 0);COM<="1111011"; WHEN "011" =>BCD<=BIN(7 DOWNTO 4);COM<="1110111"; WHEN "100" =>BCD<=SINT(3 DOWNTO 0);COM<="1101111"; WHEN "101" =>BCD<=SINT(7 DOWNTO 4);COM<="1011111"; WHEN "110" =>BCD<="000"&SINT(8);COM<="0111111"; WHEN OTHERS=>BCD<="0000";COM<="1111111"; END CASE; --将BCD码转换成数码管的8段驱动信息,高电平有效 CASE BCD IS WHEN "0000" => SEG<="00111111"; WHEN "0001" => SEG<="00000110"; WHEN "0010" => SEG<="01011011"; WHEN "0011" => SEG<="01001111"; WHEN "0100" => SEG<="01100110"; WHEN "0101" => SEG<="01101101"; WHEN "0110" => SEG<="01111101"; WHEN "0111" => SEG<="00000111"; WHEN "1000" => SEG<="01111111"; WHEN "1001" => SEG<="01101111"; WHEN "1010" => SEG<="01110111"; WHEN "1011" => SEG<="01111100"; WHEN "1100" => SEG<="00111001"; WHEN "1101" => SEG<="01011110"; WHEN "1110" => SEG<="01111001"; WHEN "1111" => SEG<="01110001"; WHEN OTHERS => SEG<="00000000"; END CASE ; END PROCESS; END ARCHITECTURE ART; 6.9.2 液晶显示控制电路的设计 液晶显示是一种将液晶显示器件、连接件、集成电路、PCB线路板、 背光源、结构件装配在一起的组件。下面给出—个液晶显示控制电路的 VHDL描述。 【例6.23】 用VHDL设计—个液晶显示控制电路。 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY LCD IS PORT(DP1,DP2,DP3:IN STD_LOGIC; RS,CS1,CS2: OUT STD_LOGIC; LCDE:OUT STD_LOGIC; RW:OUT STD_LOGIC); END LCD; ARCHITECTURE HAV OF LCD IS BEGIN PROCESS(DP1,DP2,DP3) BEGIN IF(DP1=“0” AND DP2=“0” AND DP3=“0”) THEN LCDE<=“1”;RS<=“0”;RW<=“1”;CS1<=“1”;CS2<=“0”; ELSIF(DP1=“0” AND DP2=“0” AND DP3=“1”)THEN LCDE<=“1”;RS<=“0”;RW<=“0”;CS1<=“1”;CS2<=“0”; ELSIF(DP1=“0” AND DP2=“1” AND DP3=“0”)THEN LCDE<=“0”;RS<=“1”;RW<=“1”;CS1<=“1”;CS2<=“0”; ELSIF(DP1=“0” AND DP2=“1” AND DP3=“1”)THEN LCDE<=“1”;RS<=“1”;RW<=“0”;CS1<=“1”;CS2<=“0”; ELSIF(DP1=“1” AND DP2=“0” AND DP3=“0”)THEN LCDE<=“1”;RS<=“0”;RW<=“1”;CS1<=“0”;CS2<=“1”; ELSIF(DP1=“1” AND DP2=“0” AND DP3=“1”)THEN LCDE<=“1”;RS<=“0”;RW<=“0”;CS1<=“0”;CS2<=“1”; ELSIF(DP1=“1” AND DP2=“1” AND DP3=“0”)THEN LCDE<=“0”;RS<=“1”;RW<=“1”;CS1<=“0”;CS2<=“1”; ELSIF(DP1=“1” AND DP2=“1” AND DP3=“1”)THEN LCDE<=“1”;RS<=“1”;RW<=“0”;CS1<=“0”;CS2<=“1”; ELSE LCDE<=“0”;RS<=“1”;RW<=“1”;CS1<=“0”;CS2<=“0”; END IF; END PROCESS; END HAV;
/
本文档为【VHDL程序设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索