原文:http://blog.csdn.net/Dr_JIA/article/details/45790579
方案一 (本实现方案只编写了一个vhdl文件,计数器和译码器的vhdl描述写在了一个文件里。本文件包含三个实体:分别是计数器counter4,译码器decoder,以及一个顶层实体HIERARCHIC,顶层文件里实现了计数器和译码器的结合。)
源程序:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY HIERARCHIC IS PORT(CP,R,EN:IN STD_LOGIC; CO:OUT STD_LOGIC; LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END HIERARCHIC; ARCHITECTURE HI OF HIERARCHIC IS SIGNAL SIGN1:STD_LOGIC_VECTOR(3 DOWNTO 0); COMPONENT COUNTER4 PORT(CP,R,EN:IN STD_LOGIC; CO:OUT STD_LOGIC; Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO0)); END COMPONENT; COMPONENT DECODER PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END COMPONENT; BEGIN U1:COUNTER4 PORT MAP(CP,R,EN,CO,SIGN1); U2:DECODER PORT MAP(SIGN1,LED); END HI; --------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COUNTER4 IS PORT(CP,R,EN:IN STD_LOGIC; Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); CO:OUT STD_LOGIC); END COUNTER4; ARCHITECTURE COUNT OF COUNTER4 IS BEGIN PROCESS(CP,R) BEGIN IF(R='1')THEN Q<="0000"; ELSIF(CP'EVENT AND CP='1'AND EN='1')THEN IF(Q="1111")THEN Q<="0000"; ELSE Q<=Q+1; END IF; END IF; END PROCESS; CO<='1'WHEN Q=15 AND EN='1'ELSE'0'; END COUNT; ---------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DECODER IS PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END DECODER; ARCHITECTURE DECODE OF DECODER IS SIGNAL SIGN2:STD_LOGIC_VECTOR(6 DOWNTO 0); BEGIN WITH Ain SELECT SIGN2<="0111111"WHEN"0000", "0000110"WHEN"0001", "1011011"WHEN"0010", "1001111"WHEN"0011", "1100110"WHEN"0100", "1101101"WHEN"0101", "1111101"WHEN"0110", "0000111"WHEN"0111", "1111111"WHEN"1000", "1101111"WHEN"1001", "1110111"WHEN"1010", "1111100"WHEN"1011", "0111001"WHEN"1100", "1011110"WHEN"1101", "1111001"WHEN"1110", "1110001"WHEN"1111", NULL WHEN OTHERS; LED(6)<=SIGN2(6); LED(5)<=SIGN2(5); LED(4)<=SIGN2(4); LED(3)<=SIGN2(3); LED(2)<=SIGN2(2); LED(1)<=SIGN2(1); LED(0)<=SIGN2(0); END DECODE;
方案二(该实现方案编写了三个vhdl文件,即将方案一中的三个实体分开来写。在quartusII开发环境下,只要使新建工程名与实体名一致,然后将程序2、3包含到工程中即可。同样,在顶层实体中实现计数器和译码器的结合。方案一和方案二的顶层实体文件是完全相同的。)
hierarchi.vhd(顶层文件):
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY HIERARCHIC IS PORT(CP,R,EN:IN STD_LOGIC; CO:OUT STD_LOGIC; LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END HIERARCHIC; ARCHITECTURE HI OF HIERARCHIC IS SIGNAL SIGN1:STD_LOGIC_VECTOR(3 DOWNTO 0); COMPONENT COUNTER4 PORT(CP,R,EN:IN STD_LOGIC; CO:OUT STD_LOGIC; Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO0)); END COMPONENT; COMPONENT DECODER PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END COMPONENT; BEGIN U1:COUNTER4 PORT MAP(CP,R,EN,CO,SIGN1); U2:DECODER PORT MAP(SIGN1,LED); END HI;
4位十六进制计数器counter4.vhd:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COUNTER4 IS PORT(CP,R,EN:IN STD_LOGIC; Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0); CO:OUT STD_LOGIC); END COUNTER4; ARCHITECTURE COUNT OF COUNTER4 IS BEGIN PROCESS(CP,R) BEGIN IF(R='1')THEN Q<="0000"; ELSIF(CP'EVENT AND CP='1'AND EN='1')THEN IF(Q="1111")THEN Q<="0000"; ELSE Q<=Q+1; END IF; END IF; END PROCESS; CO<='1'WHEN Q=15 AND EN='1'ELSE'0'; END COUNT;
七段显示译码器decoder.vhd:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DECODER IS PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END DECODER; ARCHITECTURE DECODE OF DECODER IS SIGNAL SIGN2:STD_LOGIC_VECTOR(6 DOWNTO 0); BEGIN WITH Ain SELECT SIGN2<="0111111"WHEN"0000", "0000110"WHEN"0001", "1011011"WHEN"0010", "1001111"WHEN"0011", "1100110"WHEN"0100", "1101101"WHEN"0101", "1111101"WHEN"0110", "0000111"WHEN"0111", "1111111"WHEN"1000", "1101111"WHEN"1001", "1110111"WHEN"1010", "1111100"WHEN"1011", "0111001"WHEN"1100", "1011110"WHEN"1101", "1111001"WHEN"1110", "1110001"WHEN"1111", NULL WHEN OTHERS; LED(6)<=SIGN2(6); LED(5)<=SIGN2(5); LED(4)<=SIGN2(4); LED(3)<=SIGN2(3); LED(2)<=SIGN2(2); LED(1)<=SIGN2(1); LED(0)<=SIGN2(0); END DECODE;后话:译码器的实现方案是多种多样的,大家在学习hdl语言时应充分注意活学活用。
以下再附三则decoder的实现方案,供各位参考。
实现方法之一:
(说明:本例直接在select语句中将结果赋给端口输出,而不再像源程序借助signal的那样。)
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DECODER IS PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END DECODER; ARCHITECTURE DECODE OF DECODER IS BEGIN WITH Ain SELECT LED<="0111111"WHEN"0000", "0000110"WHEN"0001", "1011011"WHEN"0010", "1001111"WHEN"0011", "1100110"WHEN"0100", "1101101"WHEN"0101", "1111101"WHEN"0110", "0000111"WHEN"0111", "1111111"WHEN"1000", "1101111"WHEN"1001", "1110111"WHEN"1010", "1111100"WHEN"1011", "0111001"WHEN"1100", "1011110"WHEN"1101", "1111001"WHEN"1110", "1110001"WHEN"1111", NULL WHEN OTHERS; END DECODE;实现方法二:
(说明:本例的妙处是在process中使用for-loop语句,从而使信号的赋值变得简洁。当赋值语句更多时,
使用循环来实现重复的工作的优势将更加显著。注意:for-loop只能在process中出现。)
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DECODER IS PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END DECODER; ARCHITECTURE DECODE OF DECODER IS SIGNAL SIGN2:STD_LOGIC_VECTOR(6 DOWNTO 0); BEGIN WITH Ain SELECT SIGN2<="0111111"WHEN"0000", "0000110"WHEN"0001", "1011011"WHEN"0010", "1001111"WHEN"0011", "1100110"WHEN"0100", "1101101"WHEN"0101", "1111101"WHEN"0110", "0000111"WHEN"0111", "1111111"WHEN"1000", "1101111"WHEN"1001", "1110111"WHEN"1010", "1111100"WHEN"1011", "0111001"WHEN"1100", "1011110"WHEN"1101", "1111001"WHEN"1110", "1110001"WHEN"1111", NULL WHEN OTHERS; PROCESS(SIGN2) BEGIN FOR N IN 6 DOWNTO 0 LOOP LED(N)<=SIGN2(N); END LOOP; END PROCESS; END DECODE;实现方法三:
(说明:本例基于case语句。)
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY DECODER IS PORT(Ain:IN STD_LOGIC_VECTOR(3 DOWNTO 0); LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END DECODER; ARCHITECTURE DECODE OF DECODER IS BEGIN PROCESS(Ain) BEGIN CASE Ain IS WHEN"0000"=>LED<="0111111"; WHEN"0001"=>LED<="0000110"; WHEN"0010"=>LED<="1011011"; WHEN"0011"=>LED<="1001111"; WHEN"0100"=>LED<="1100110"; WHEN"0101"=>LED<="1101101"; WHEN"0110"=>LED<="1111101"; WHEN"0111"=>LED<="0000111"; WHEN"1000"=>LED<="1111111"; WHEN"1001"=>LED<="1101111"; WHEN"1010"=>LED<="1110111"; WHEN"1011"=>LED<="1111100"; WHEN"1100"=>LED<="0111001"; WHEN"1101"=>LED<="1011110"; WHEN"1110"=>LED<="1111001"; WHEN"1111"=>LED<="1110001"; WHEN OTHERS=>LED<=NULL; END CASE; END PROCESS; END DECODE;