介紹了數(shù)字系統(tǒng)設(shè)計(jì)中經(jīng)常用到的計(jì)數(shù)器,分頻器,選擇器,譯碼器,編碼器,寄存器,存儲(chǔ)器,輸入電路,顯示電路等基本單元電路的VHDL程序設(shè)計(jì)。
學(xué)習(xí)要求:在教師講授這些基本單元電路的設(shè)計(jì)思想的基礎(chǔ)上,通過(guò)上機(jī)調(diào)試熟練掌握這些基本單元電路的設(shè)計(jì)。
關(guān)鍵詞:計(jì)數(shù)器(Counter),分頻器(Divder),選擇器(Multiplexer),譯碼器(Decoder),編碼器(Encoder),寄存器(Register),存儲(chǔ)器(Memory),輸入電路(Input Circuit),顯示電路(Display Circuit)
6.1 計(jì)數(shù)器的設(shè)計(jì)
6.1.1 同步計(jì)數(shù)器的設(shè)計(jì)
6.1.2 異步計(jì)數(shù)器的設(shè)計(jì)
6.2 分頻器的設(shè)計(jì)
6.3 選擇器的設(shè)計(jì)
6.4 譯碼器的設(shè)計(jì)
6.5 編碼器的設(shè)計(jì)
6.5.1 一般編碼器的設(shè)計(jì)
6.5.2 優(yōu)先級(jí)編碼器的設(shè)計(jì)
6.6 寄存器的設(shè)計(jì)
6.6.1 數(shù)碼寄存器的設(shè)計(jì)
6.6.2 移位寄存器的設(shè)計(jì)
6.6.3 并行加載移位寄存器的設(shè)計(jì)
6.7 存儲(chǔ)器的設(shè)計(jì)
6.7.1 只讀存儲(chǔ)器ROM的設(shè)計(jì)
6.7.2 讀寫存儲(chǔ)器SRAM的設(shè)計(jì)
6.8 輸入電路的設(shè)計(jì)
6.8.1 鍵盤掃描電路的設(shè)計(jì)
6.8.2 鍵盤接口電路的設(shè)計(jì)
6.9 顯示電路的設(shè)計(jì)
6.9.1 數(shù)碼管靜態(tài)顯示電路的設(shè)計(jì)
6.9.2 數(shù)碼管動(dòng)態(tài)顯示電路的設(shè)計(jì)
6.9.2 液晶顯示控制電路的設(shè)計(jì)
6.1 計(jì)數(shù)器的設(shè)計(jì)
計(jì)數(shù)器是在數(shù)字系統(tǒng)中使用最多的時(shí)序電路,它不僅能用于對(duì)時(shí)鐘脈沖計(jì)數(shù),還可以用于分頻,定時(shí),產(chǎn)生節(jié)拍脈沖和脈沖序列以及進(jìn)行數(shù)字運(yùn)算等。計(jì)數(shù)器是一個(gè)典型的時(shí)序電路,分析計(jì)數(shù)器就能更好地了解時(shí)序電路的特性。計(jì)數(shù)器分同步計(jì)數(shù)器和異步計(jì)數(shù)器兩種。
6.1.1 同步計(jì)數(shù)器的設(shè)計(jì)
所謂同步計(jì)數(shù)器,就是在時(shí)鐘脈沖(計(jì)數(shù)脈沖)的控制下,構(gòu)成計(jì)數(shù)器的各觸發(fā)器狀態(tài)同時(shí)發(fā)生變化的那一類計(jì)數(shù)器。
1) 六十進(jìn)制計(jì)數(shù)器
眾所周知,用一個(gè)4位二進(jìn)制計(jì)數(shù)器可構(gòu)成1位十進(jìn)制計(jì)數(shù)器,而2位十進(jìn)制計(jì)數(shù)器連接起來(lái)可以構(gòu)成一個(gè)六十進(jìn)制的計(jì)數(shù)器。六十進(jìn)制計(jì)數(shù)器常用于時(shí)鐘計(jì)數(shù)。一個(gè)六十進(jìn)制計(jì)數(shù)器的外部端口示意圖如圖6.1所示。在該六十進(jìn)制計(jì)數(shù)器的電路中,BCDLWR和BCD10WR與DATAIN配合,以實(shí)現(xiàn)對(duì)六十進(jìn)制計(jì)數(shù)器的個(gè)位和十位值的預(yù)置操作。應(yīng)注意,在對(duì)個(gè)位和十位進(jìn)行預(yù)置操作時(shí),DATAIN輸入端是公用的,因而個(gè)位和十位的預(yù)置操作必定要串行進(jìn)行。利用VHDL語(yǔ)言描述六十進(jìn)制計(jì)數(shù)器的程序如例6.1所示。
圖6.1 六十進(jìn)制計(jì)數(shù)器外部端口示意圖
【例6.1】 用VHDL設(shè)計(jì)一個(gè)六十進(jìn)制計(jì)數(shù)器(方法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;
COUT 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) –-個(gè)位數(shù)處理進(jìn)程
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) –-十位數(shù)處理進(jìn)程
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) –-進(jìn)位位處理進(jìn)程
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設(shè)計(jì)一個(gè)六十進(jìn)制計(jì)數(shù)器(方法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; --時(shí)鐘脈沖
BIN: OUT STD_LOGIC_VECTOR (5 DOWNTO 0); --二進(jìn)制
S: IN STD_LOGIC; --輸出啟動(dòng)信號(hào)
CLR: IN STD_LOGIC; --清除信號(hào)
EC: IN STD_LOGIC; --使能計(jì)數(shù)信號(hào)
CY60: OUT STD_LOGIC );--計(jì)數(shù)60進(jìn)位信號(hào)
END COUNTER60;
ARCHITECTURE RTL OF COUNTER60 IS
SIGNAL Q : STD_LOGIC_VECTOR (5 DOWNTO 0) ;
SIGNAL RST, DLY : STD_LOGIC;
BEGIN
PROCESS (CP,RST) -- 計(jì)數(shù)60
BEGIN
IF RST = '1' THEN
Q <= "000000"; -- 復(fù)位計(jì)數(shù)器
ELSIF CP'EVENT AND CP = '1' THEN
DLY <= Q(5);
IF EC = '1' THEN
Q <= Q+1; -- 計(jì)數(shù)值加1
END IF;
END IF;
END PROCESS;
CY60 <= NOT Q(5) AND DLY; -- 進(jìn)位信號(hào)微分
RST <= '1' WHEN Q=60 OR CLR='1' ELSE -- 復(fù)位信號(hào)設(shè)定
'0';
BIN <= Q WHEN S = '1' ELSE -- 計(jì)數(shù)輸出
"000000";
END RTL ;
2) 可逆計(jì)數(shù)器
在時(shí)序應(yīng)用電路中,計(jì)數(shù)器的應(yīng)用十分普遍,如加法計(jì)數(shù)器,減法計(jì)數(shù)器,可逆計(jì)數(shù)器等。所謂可逆計(jì)數(shù)器,就是根據(jù)計(jì)數(shù)控制信號(hào)的不同,在時(shí)鐘脈沖作用下,計(jì)數(shù)器可以進(jìn)行加1或者減1操作的一種計(jì)數(shù)器??赡嬗?jì)數(shù)器有一個(gè)特殊的控制端,這就是UPDN端。當(dāng)UPDN=‘1’時(shí),計(jì)數(shù)器進(jìn)行加1操作,當(dāng)UPDN=‘0’時(shí),計(jì)數(shù)器就進(jìn)行減1操作。表6.1是一個(gè)3位可逆計(jì)數(shù)器的真值表,它的VHDL語(yǔ)言描述如例6.3所示。
表6.1 可逆計(jì)數(shù)器真值表
輸入端 輸出端
DIR CP Q2 Q1 Q0
X X 0 0 0
1 計(jì)數(shù)器加1操作
0 計(jì)數(shù)器減1操作
【例6.3】 用VHDL設(shè)計(jì)一個(gè)3位二進(jìn)制的可逆計(jì)數(shù)器。
--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;
編寫可逆計(jì)數(shù)器VHDL程序時(shí),在語(yǔ)法上,就是把加法和減法計(jì)數(shù)器合并,使用一個(gè)控制信號(hào)決定計(jì)數(shù)器作加法或減法的動(dòng)作。在本例中,利用“控制信號(hào)DIR”可以讓計(jì)數(shù)器的計(jì)數(shù)動(dòng)作加1或減1。
6.1.2 異步計(jì)數(shù)器的設(shè)計(jì)
異步計(jì)數(shù)器又稱行波計(jì)數(shù)器,它將低/高位計(jì)數(shù)器的輸出做為高/低位計(jì)數(shù)器的時(shí)鐘信號(hào),這一級(jí)一級(jí)串行連接起來(lái)就構(gòu)成了一個(gè)異步計(jì)數(shù)器。異步計(jì)數(shù)器與同步計(jì)數(shù)器不同之處就在于時(shí)鐘脈沖的提供方式,但是,由于異步計(jì)數(shù)器采用行波計(jì)數(shù),從而使計(jì)數(shù)延遲增加,在要求延遲小的領(lǐng)域受到了很大限制。盡管如此,由于它的電路簡(jiǎn)單,仍有廣泛的應(yīng)用。
圖6.2是用VHDL語(yǔ)言描述的一個(gè)由8個(gè)觸發(fā)器構(gòu)成的異步計(jì)數(shù)器.它的程序如例6.4所示,采用元件例化方式生成。與上述同步計(jì)數(shù)器不同之處主要表現(xiàn)在對(duì)各級(jí)時(shí)鐘脈沖的描述上,這一點(diǎn)請(qǐng)讀者在閱讀程序時(shí)多加注意。
圖6.2 8位異步計(jì)數(shù)器原理圖
【例6.4】 用VHDL設(shè)計(jì)一個(gè)由8個(gè)觸發(fā)器構(gòu)成的8位二進(jìn)制異步計(jì)數(shù)器。
--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 分頻器的設(shè)計(jì)
一般來(lái)說(shuō),可以把加法計(jì)數(shù)器看成一種分頻電路,而且是除2的N的次方的分頻電路。
但是也常常會(huì)有除M(M不是2的N次方)的分頻電路需求.
下面就介紹一個(gè)除6的加法分頻電路。先建立一個(gè)計(jì)數(shù)器,而這個(gè)計(jì)數(shù)器的大小必須是3位(計(jì)數(shù)默認(rèn)范圍是0~2^3-1=7),不過(guò)將把這樣的計(jì)數(shù)值為6的瞬間,立即復(fù)位改變?yōu)?,其VHDL程序如例6.5所示
【例6.5】 用VHDL設(shè)計(jì)一個(gè)除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 的同步計(jì)數(shù)器,需將上述QN=6改成QN=N,而且計(jì)數(shù)器X bits數(shù)需調(diào)整為符合條件2X>=N才可以。
6.3 選擇器的設(shè)計(jì)
多路選擇器可以從多組數(shù)據(jù)來(lái)源中選取一組送入目的地。它的應(yīng)用范圍相當(dāng)廣泛,從組合邏輯的執(zhí)行,到數(shù)據(jù)路徑的選擇,經(jīng)??梢钥吹剿嫩櫽啊A硗庠谙駮r(shí)鐘,計(jì)數(shù)定時(shí)器等的輸出顯示電路中都可以看到利用多路選擇器制作掃描電路來(lái)分別驅(qū)動(dòng)輸出裝置(通常為七段數(shù)碼顯示管,點(diǎn)矩陣或液晶面板),以降低功率的消耗。有時(shí)也希望把兩組沒(méi)有必要同時(shí)觀察的數(shù)據(jù),共享一組顯示電路,以降低成本。
多路選擇器的結(jié)構(gòu)是2N個(gè)輸入線,會(huì)有N個(gè)地址選擇線及一個(gè)輸出線配合?,F(xiàn)以一個(gè)四選一的多路選擇器為例,其四選一電路的真值表如表6.2所示,其外部端口示意圖如圖6.3所示。
表6.2 四選一電路真值表
選擇輸入 數(shù)據(jù)輸入 數(shù)據(jù)輸出
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 四選一電路外部端口示意圖
描述四選一多路選擇器的方法有多種,例如在一個(gè)進(jìn)程中使用if-then-else語(yǔ)句;在一個(gè)進(jìn)程中使用case語(yǔ)句;使用with select構(gòu)造或使用結(jié)構(gòu)VHDL。現(xiàn)用if-then-else語(yǔ)句對(duì)它進(jìn)行描述,就可以得到如例6.6所示的程序。
【例6.6】設(shè)計(jì)一個(gè)四選一的多路選擇器的VHDL程序(使用if-then-else語(yǔ)句)。
--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語(yǔ)句描述的,程序中的ELSE項(xiàng)作為余下的條件,將選擇INPUT(3)從Y端輸出,這種描述比較安全。當(dāng)然,不用ELSE項(xiàng)也可以,這時(shí)必須列出SEL的所有可能出現(xiàn)的情況,加以一一確認(rèn)。在進(jìn)程中使用CASE語(yǔ)句會(huì)更清晰易讀。例6.7是用CASE語(yǔ)句描述的四選一選擇器。
【例6.7】設(shè)計(jì)一個(gè)四選一的多路選擇器的VHDL程序(使用case語(yǔ)句)。
--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】設(shè)計(jì)一個(gè)四選一的多路選擇器的VHDL程序(使用WHEN-ELSE并行條件賦值語(yǔ)句)。
--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 譯碼器的設(shè)計(jì)
譯碼器是把輸入的數(shù)碼解出其對(duì)應(yīng)的數(shù)碼,如果有N個(gè)二進(jìn)制選擇線,則最多可以譯碼轉(zhuǎn)換成2N個(gè)數(shù)據(jù)。譯碼器也經(jīng)常被應(yīng)用在地址總線或用作電路的控制線。像只讀存儲(chǔ)器(ROM)中便利用譯碼器來(lái)進(jìn)行地址選址的工作。
3-8譯碼器是最常用的種小規(guī)模集成電路。3-8譯碼器外部端口示意圖如圖6.9所示,它有3個(gè)二進(jìn)制輸入端a, b,c和8個(gè)譯碼輸出端y0~y7。對(duì)輸入a,b,c的值進(jìn)行譯碼,就可以確定輸出端y0~y7的哪一個(gè)輸出端變?yōu)橛行Вǖ碗娖剑?,從而達(dá)到譯碼的目的。另外為方便譯碼器的控制或便于將來(lái)擴(kuò)充用,在設(shè)計(jì)時(shí)常常會(huì)增加一個(gè)EN使能輸入腳。3-8譯碼器的真值表如表6.3所示。有了真值表,就可以直接用查表法來(lái)設(shè)計(jì)。
在VHDL 中,“WITH…SELECT”,“CASE…WHEN”及“WHEN…ELSE”這類指令都是執(zhí)行查表或?qū)?yīng)動(dòng)作的能手。
圖6.4 3-8譯碼器外部端口示意圖
表6.3 3-8譯碼器的真值表
使能 二進(jìn)制輸入端 譯碼輸出端
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設(shè)計(jì)一個(gè)3-8譯碼器(用“CASE…WHEN”語(yǔ)句)。
--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設(shè)計(jì)一個(gè)3-8譯碼器(用“WITH…SELECT”語(yǔ)句)。
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;
在本節(jié)中用到的兩種描述語(yǔ)句,“WITH…SELECT”是并行同時(shí)性語(yǔ)句,“CASE…WHEN”是與其功能相同的順序性語(yǔ)句,讀者在使用時(shí)一定要確定需要的是順序性語(yǔ)句還是并行性語(yǔ)句,否則程序在編譯時(shí)會(huì)發(fā)生錯(cuò)誤。
6.5 編碼器的設(shè)計(jì)
編碼器是將2^N個(gè)分離的信息代碼以N個(gè)二進(jìn)制碼來(lái)表示。它的功能和譯碼器正好相反。編碼器常常運(yùn)用于影音壓縮或通信方面,以達(dá)到精簡(jiǎn)傳輸量的目的??梢詫⒕幋a器看成壓縮電路,譯碼起看成解壓縮電路。傳送數(shù)據(jù)前先用編碼器壓縮數(shù)據(jù)后在傳送出去,在接收端則由譯碼器將數(shù)據(jù)解壓縮,還原其原來(lái)的數(shù)據(jù)。這樣,在傳送過(guò)程中,就可以以N個(gè)數(shù)碼來(lái)代替2^N個(gè)數(shù)碼的數(shù)據(jù)量,來(lái)提升傳輸效率。
6.5.1 一般編碼器的設(shè)計(jì)
如果沒(méi)有特別說(shuō)明,各編碼輸入端無(wú)優(yōu)先
區(qū)別。圖6.5是8-3編碼器的外部端口圖,
有了外部端口圖,就能夠做ENTITY的定義,
再根據(jù)編碼器的真值表如表6.4所示.,再使用
查表法就可以輕松描述結(jié)構(gòu)體了。
圖6.5 8-3編碼器外部端口圖
表6.4 8-3編碼器的真值表
輸入 二進(jìn)制編碼輸出
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設(shè)計(jì)一個(gè)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 優(yōu)先級(jí)編碼器的設(shè)計(jì)
優(yōu)先級(jí)編碼器長(zhǎng)用于中斷的優(yōu)先級(jí)控制,例如,74LS148是一個(gè)8輸入,3位二進(jìn)制碼輸出的優(yōu)先級(jí)編碼器。當(dāng)其某一個(gè)輸入有效時(shí),就可以輸出一個(gè)對(duì)應(yīng)的3位二進(jìn)制編碼。另外,當(dāng)同時(shí)有幾個(gè)輸入有效時(shí), 將輸優(yōu)先級(jí)最高的那個(gè)輸入所對(duì)應(yīng)的二進(jìn)制編碼。
該優(yōu)先級(jí)編碼器的真值表如表6. 5所示。表中的“X”項(xiàng)表示任意項(xiàng),它可以是“0”,也可以是“1”。INPUT(0)的優(yōu)先級(jí)最高,INPUT(7)的優(yōu)先級(jí)最低。
表6.5 優(yōu)先級(jí)編碼器真值表
輸入 二進(jìn)制編碼輸出
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設(shè)計(jì)一個(gè)8-3優(yōu)先級(jí)編碼器。
-- 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 寄存器的設(shè)計(jì)
寄存(鎖存)器是一種重要的數(shù)字電路部件,常用來(lái)暫時(shí)存放指令、參與運(yùn)算的數(shù)據(jù)或運(yùn)算結(jié)果等。它是數(shù)字測(cè)量和數(shù)字控制中常用的部件,是計(jì)算機(jī)的主要部件之一。寄存器的主要組成部分是具有記憶功能的雙穩(wěn)態(tài)觸發(fā)器。一個(gè)觸發(fā)器可以儲(chǔ)存一位二進(jìn)制代碼,要儲(chǔ)存N位二進(jìn)制代碼,就在有N個(gè)觸發(fā)器。寄存器從功能上說(shuō),通??煞譃閿?shù)碼寄存器和移位寄存器兩種。
6.6.1 數(shù)碼寄存器的設(shè)計(jì)
數(shù)碼寄存器用于寄存一組二進(jìn)制代碼,廣泛用于各類數(shù)字系統(tǒng)。下面給出—個(gè)8位寄存器的VHDL描述。
【例6.13】 用VHDL設(shè)計(jì)一個(gè)8位的數(shù)碼寄存器。
--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 移位寄存器的設(shè)計(jì)
移位寄存器除了具有存儲(chǔ)代碼的功能以外,還具有移位功能。所謂移位功能,是指寄存器里存儲(chǔ)的代碼能在移位脈沖的作用下依次左移或右移。因此,移位寄存器不但可以用來(lái)寄存代碼,還可用來(lái)實(shí)現(xiàn)數(shù)據(jù)的串并轉(zhuǎn)換、數(shù)值的運(yùn)算以及數(shù)據(jù)處理等。下面給出一個(gè)8位的移位寄存器,其具有左移一位或右移一位、并行輸入和同步復(fù)位的功能。
【例6.14】用VHDL設(shè)計(jì)一個(gè)8位的移位寄存器,其具有左移一位或右移一位、并行輸入和同步復(fù)位的功能.
--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 --同步復(fù)位功能的實(shí)現(xiàn)
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 并行加載移位寄存器的設(shè)計(jì)
在TTL手冊(cè)中的74LS166是一個(gè)帶清零端的8位并行加載的移位寄存器,其引腳圖及邏輯圖如圖6.6所示。
圖6.6 74LS166的引腳圖及邏輯圖
圖中各引腳名稱和功能如下:
A,B,C,D,E,F(xiàn),G,H:8位并行數(shù)據(jù)輸入端;
SER:串行數(shù)據(jù)輸入端;
QH:串行數(shù)據(jù)輸出端;
CLK: 時(shí)鐘信號(hào)輸入端;
CLKINH:時(shí)鐘信號(hào)禁止(FE)端;
SH/LD:移位加載控制(SL)端;
CLR:清零端。
當(dāng)清零輸入端CLR為‘0’時(shí),8個(gè)觸發(fā)器的輸出均為‘0’,從而使輸出Q為‘0’。CLKINH是時(shí)鐘禁止端,當(dāng)它為‘1’時(shí)將禁止時(shí)鐘,即不管時(shí)鐘信號(hào)如何變化,移位寄存器的狀態(tài)不發(fā)生改變。另外,時(shí)鐘信號(hào)只在上升沿時(shí)才有效,且CLKINH 為‘0’。當(dāng)控制端SH/LD =‘1’時(shí)是移位狀態(tài),在時(shí)鐘脈沖上升沿的控制下右移,當(dāng)SH/LD =‘0’時(shí)是加載狀態(tài),在時(shí)鐘脈沖上升沿的作用下,數(shù)據(jù)輸入端A~H的信號(hào)就是裝載到移位寄存器的QA~QH。根據(jù)上述描述,就可以用VHDL語(yǔ)言編寫出描述74166功能的程序。
【例6.15】用VHDL設(shè)計(jì)的帶清零端的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
SIGNAL TMPREG8:STD _ LOGIC _ VECTOR (7 DOWNTO O);
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 存儲(chǔ)器的設(shè)計(jì)
半導(dǎo)體存儲(chǔ)器的種類很多,從功能上可以分為只讀存儲(chǔ)器(READ_ONLY MEMORY,簡(jiǎn)稱ROM)和隨機(jī)存儲(chǔ)器(RANDOM ACCESS MEMORY,簡(jiǎn)稱RAM)兩大類。
6.7.1 只讀存儲(chǔ)器ROM的設(shè)計(jì)
只讀存儲(chǔ)器在正常工作時(shí)從中讀取數(shù)據(jù),不能快速地修改或重新寫入數(shù),適用于存儲(chǔ)固定數(shù)據(jù)的場(chǎng)合。下面是一個(gè)容量為256×4的ROM存儲(chǔ)的例子,該ROM有8位地址線ADR(0)~ADR(7),4位數(shù)據(jù)輸出線DOUT(0)~DOUT(3)及使能EN,如圖6. 7所示。
圖6. 7 ROM
【例6.16】 用VHDL設(shè)計(jì)一個(gè)一個(gè)容量為256×4的ROM存儲(chǔ)的例子,該ROM有8位地址線ADR(0)~ADR(7),4位數(shù)據(jù)輸出線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; --初始化結(jié)束
END IF;
ADR_IN<=CONV_INTEGER(ADR); --將向量轉(zhuǎn)化成整數(shù)
IF(EN=‘1’)THEN
DOUT<=ROM(ADR_IN);
ELSE
DOUT<=“ZZZZ”;
END IF;
END PROCESS;
END ARCHITECTURE ART;
6.7.2 讀寫存儲(chǔ)器SRAM的設(shè)計(jì)
RAM和ROM的主要區(qū)別在于RAM描述上有讀和寫兩種操作,而且在讀寫上對(duì)時(shí)間有較嚴(yán)格的要求。下面我們給出一個(gè)8×8位的雙口SRAM的VHDL描述實(shí)例,如圖6.8所示。
圖6. 8 雙口SRAM
【例6.17】 用VHDL設(shè)計(jì)一個(gè)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
--寫進(jìn)程
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;
--讀進(jìn)程
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 輸入電路的設(shè)計(jì)
6.8.1 鍵盤掃描電路的設(shè)計(jì)
計(jì)算機(jī)控制系統(tǒng)中,數(shù)據(jù)和控制信號(hào)的輸入主要使用鍵盤。下面給出—個(gè)鍵盤掃描電路VHDL描述。
【例6.18】 用VHDL設(shè)計(jì)一個(gè)鍵盤掃描電路。
-- 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”;
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;
LEDA<=SEL(0);
LEDB<=SEL(1);
LEDC<=SEL(2);
END HAV;
6.8.2 鍵盤接口電路的設(shè)計(jì)
PS/2鍵盤接口通常使用專用芯片實(shí)現(xiàn)。由于PS/2鍵盤或鼠標(biāo)串行輸出信號(hào)速度較高,普通單片機(jī)無(wú)法接收,現(xiàn)利用VHDL在目標(biāo)器件FPGA/CPLD上實(shí)現(xiàn)一個(gè)鍵碼接收部分。PS/2接口的鍵盤每按下一個(gè)鍵,該鍵的掃描碼即以十六進(jìn)制形式顯示在數(shù)碼管上。以下為接收PS/2鍵盤信號(hào)的VHDL邏輯描述。
【例6.20】 用VHDL設(shè)計(jì)一個(gè)接收PS/2鍵盤信號(hào)的接口電路。
-- 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 顯示電路的設(shè)計(jì)
常用的顯示器件有發(fā)光二極管,數(shù)碼管,液晶顯示器等,其中最常用的為數(shù)碼管。數(shù)碼管顯示數(shù)據(jù)的方式有靜態(tài)顯示和動(dòng)態(tài)顯示之分。所謂靜態(tài)顯示,就是將被顯示的數(shù)據(jù)的BCD碼,通過(guò)各自的4-7/8顯示譯碼器譯碼后,分別接到顯示譯碼器的顯示驅(qū)動(dòng)段a-g(p),而公共端COM則根據(jù)數(shù)碼管的類型(共陰/共陽(yáng))分別接GND/VCC。動(dòng)態(tài)顯示,就是將被顯示的數(shù)據(jù)的BCD碼,按照一定的變化頻率,在不同的時(shí)刻周期性地分別送到一個(gè)數(shù)據(jù)總線上,再通過(guò)一個(gè)公共的4-7/8顯示譯碼器譯碼后,接到多個(gè)顯示譯碼器的公共顯示驅(qū)動(dòng)段a-g(p)上,同時(shí),在不同的時(shí)刻周期性地選通對(duì)應(yīng)的數(shù)碼管的公共端COM。
6.9.1 數(shù)碼管靜態(tài)顯示電路的設(shè)計(jì)
七段數(shù)碼顯示器由7根顯示碼管組成,對(duì)每一根碼管,用一位二進(jìn)制表示。若該數(shù)碼管的為共陰數(shù)碼管,則該位為1時(shí),表示此碼管發(fā)光,如為0,表示此碼管不發(fā)光,對(duì)7根碼管編號(hào)。共陽(yáng)數(shù)碼管則正好相反。下面用一個(gè)7位二進(jìn)制數(shù)表示一個(gè)七段顯示器的編碼,其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;
下面給出一個(gè)4位二進(jìn)制加法計(jì)數(shù)器靜態(tài)顯示的VHDL程序。
【例6.21】 用VHDL設(shè)計(jì)一個(gè)4位二進(jìn)制加法計(jì)數(shù)器,并將計(jì)數(shù)結(jié)果用7段LED顯示數(shù)碼管進(jìn)行靜態(tài)顯示。
--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 數(shù)碼管動(dòng)態(tài)顯示電路的設(shè)計(jì)
下面我們就通過(guò)一個(gè)例子來(lái)說(shuō)明數(shù)據(jù)動(dòng)態(tài)掃描的工作原理和VHDL程序的設(shè)計(jì)方法。
【例6.22】用VHDL設(shè)計(jì)一個(gè)8位二進(jìn)制并行半加器,要求將被加數(shù)、加數(shù)和加法運(yùn)算和用動(dòng)態(tài)掃描的方式在共陰數(shù)碼管上同時(shí)顯示出,該數(shù)據(jù)動(dòng)態(tài)掃描顯示電路的外圍器件接線圖如圖6.9所示。
圖6.9?數(shù)據(jù)動(dòng)態(tài)掃描顯示電路外圍器件接線圖
--DISPLAY.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--實(shí)體說(shuō)明
ENTITY DISPLAY IS
PORT(CLK:IN STD_LOGIC; --動(dòng)態(tài)掃描顯示時(shí)鐘,24HZ以上
AIN: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --8位被加數(shù)
BIN: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --8位加數(shù)
SUM0,SUM1,SUM2:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--仿真觀測(cè)輸出
COM:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--數(shù)碼管COM端的選擇輸出端
SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --數(shù)碼管8段顯示驅(qū)動(dòng)輸出端
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
--進(jìn)行運(yùn)算前的準(zhǔn)備及加法運(yùn)算
AA<='0'&AIN;
BB<='0'&BIN;
SINT<=AA+BB;
SUM0<=SINT(3 DOWNTO 0); --運(yùn)算結(jié)果的仿真觀測(cè)輸出
SUM1<=SINT(7 DOWNTO 4); --運(yùn)算結(jié)果的仿真觀測(cè)輸出
SUM2<="000"&SINT(8); --運(yùn)算結(jié)果的仿真觀測(cè)輸出
--產(chǎn)生動(dòng)態(tài)掃描顯示的控制信號(hào)
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
--顯示數(shù)據(jù)的選擇,對(duì)應(yīng)顯示數(shù)碼管公共端的選通,低電平有效
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碼轉(zhuǎn)換成數(shù)碼管的8段驅(qū)動(dòng)信息,高電平有效
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 液晶顯示控制電路的設(shè)計(jì)
液晶顯示是一種將液晶顯示器件、連接件、集成電路、PCB線路板、背光源、結(jié)構(gòu)件裝配在一起的組件。下面給出—個(gè)液晶顯示控制電路的VHDL描述。
【例6.23】 用VHDL設(shè)計(jì)—個(gè)液晶顯示控制電路。
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;
評(píng)論
查看更多