第 8章
VHDL结构与要素
EDA技术 实用教程
KX
康芯科技
8.1 实 体
8.1.1 实体语句结构
ENTITY 实体名 IS
[GENERIC ( 类属表 );]
[PORT ( 端口表 );]
END ENTITY 实体名 ;
8.1.2 GENERIC类属说明语句
GENERIC([ 常数名,数据类型 [,设定值 ]
{ ;常数名,数据类型 [,设定值 ] } ) ;
KX
康芯科技【 例 8-1】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY andn IS
GENERIC ( n,INTEGER ); --定义类属参量及其数据类型
PORT(a,IN STD_LOGIC_VECTOR(n-1 DOWNTO 0);--用类属参量限制矢量长度
c,OUT STD_LOGIC);
END;
ARCHITECTURE behav OF andn IS
BEGIN
PROCESS (a)
VARIABLE int,STD_LOGIC;
BEGIN
int,= '1';
FOR i IN a'LENGTH - 1 DOWNTO 0 LOOP
IF a(i)='0' THEN int,= '0';
END IF;
END LOOP;
c <=int ;
END PROCESS;
END;
KX
康芯科技
【 例 8-2】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY exn IS
PORT(d1,d2,d3,d4,d5,d6,d7,IN STD_LOGIC;
q1,q2,OUT STD_LOGIC);
END;
ARCHITECTURE exn_behav OF exn IS
COMPONENT andn --元件调用声明
GENERIC ( n,INTEGER);
PORT(a,IN STD_LOGIC_VECTOR(n-1 DOWNTO0);
C,OUT STD_LOGIC);
END COMPONENT ;
BEGIN -- 类属映射语句,定义类属变量,n赋值为 2
u1,andn GENERIC MAP (n =>2)
PORT MAP (a(0)=>d1,a(1)=>d2,c=>q1);
u2,andn GENERIC MAP (n =>5) -- 定义类属变量,n赋值为 5
PORT MAP (a(0)=>d3,a(1)=>d4,a(2)=>d5,
a(3)=>d6,a(4)=>d7,c=>q2);
END;
KX
康芯科技
8.1.3 类属映射语句
8.1 实 体
【 例 8-3】
LIBRARY IEEE; --待例化元件
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_arith.ALL;
USE IEEE.STD_LOGIC_unsigned.ALL;
ENTITY addern IS
PORT (a,b,IN STD_LOGIC_VECTOR;
result,out STD_LOGIC_VECTOR);
END addern;
ARCHITECTURE behave OF addern IS
BEGIN
result <= a + b;
END;
KX
康芯科技接上页
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_arith.ALL;
USE IEEE.STD_LOGIC_unsigned.ALL;
ENTITY adders IS
GENERIC(msb_operand,INTEGER,= 15; msb_sum,INTEGER,=15);
PORT(b,IN STD_LOGIC_VECTOR (msb_operand DOWNTO 0);
result,OUT STD_LOGIC_VECTOR (msb_sum DOWNTO 0));
END adders;
ARCHITECTURE behave OF adders IS
COMPONENT addern
PORT ( a,b,IN STD_LOGIC_VECTOR;
result,OUT STD_LOGIC_VECTOR);
END COMPONENT;
SIGNAL a,STD_LOGIC_VECTOR (msb_sum /2 DOWNTO 0);
SIGNAL twoa,STD_LOGIC_VECTOR (msb_operand DOWNTO 0);
KX
康芯科技BEGIN
twoa <= a & a;
U1,addern PORT MAP (a => twoa,b => b,result => result);
U2,addern PORT MAP (a=>b(msb_operand downto msb_operand/2 +1),
b=>b(msb_operand/2 downto 0),result => a);
END behave;
接上页图 8-1 例 8-3的逻辑电路图
KX
康芯科技
8.1.4 PORT(端口 )说明
8.1 实 体
PORT ( 端口名,端口模式 数据类型 ;
{ 端口名,端口模式 数据类型 } ) ;
KX
康芯科技
8.2 结构体结构体的组成部分是:
对数据类型,常数,信号,子程序和元件等元素的说明部分 。
述实体逻辑行为的,以各种不同的描述风格表达的功能描述语句 。
以元件例化语句为特征的外部元件 ( 设计实体 ) 端口间的连接 。
1,结构体的一般语言格式
ARCHITECTURE结构体名 OF 实体名 IS
[说明语句 ]
BEGIN
[功能描述语句 ]
END ARCHITECTURE结构体名 ;
KX
康芯科技
8.2 结构体
2,结构体说明语句
3,功能描述语句结构进程语句信号赋值语句子程序调用语句元件例化语句
KX
康芯科技
8.3 子程序 (SUBPROGRAM)
8.3.1 函数( FUNCTION)
函数的语言表达格式如下:
FUNCTION 函数名 ( 参数表 ) RETURN 数据类型 --函数首
FUNCTION 函数名 ( 参数表 ) RETURN 数据类型 IS -- 函数体
[ 说明部分 ]
BEGIN
顺序语句 ;
END FUNCTION 函数名 ;
KX
康芯科技
【 例 8-4】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE packexp IS --定义程序包
FUNCTION max( a,b,IN STD_LOGIC_VECTOR) --定义函数首
RETURN STD_LOGIC_VECTOR ;
FUNCTION func1 ( a,b,c,REAL ) --定义函数首
RETURN REAL ;
FUNCTION "*" ( a,b,INTEGER ) --定义函数首
RETURN INTEGER ;
FUNCTION as2 (SIGNAL in1,in2,REAL ) --定义函数首
RETURN REAL ;
END ;
PACKAGE BODY packexp IS
FUNCTION max( a,b,IN STD_LOGIC_VECTOR) --定义函数体
RETURN STD_LOGIC_VECTOR IS
BEGIN
IF a > b THEN RETURN a;
ELSE RETURN b;
END IF;
END FUNCTION max; --结束 FUNCTION语句
END; --结束 PACKAGE BODY语句接下页
KX
康芯科技
LIBRARY IEEE; -- 函数应用实例
USE IEEE.STD_LOGIC_1164.ALL;
USE WORK.packexp.ALL ;
ENTITY axamp IS
PORT(dat1,dat2,IN STD_LOGIC_VECTOR(3 DOWNTO 0);
dat3,dat4,IN STD_LOGIC_VECTOR(3 DOWNTO 0);
out1,out2,OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );
END;
ARCHITECTURE bhv OF axamp IS
BEGIN
out1 <= max(dat1,dat2); --用在赋值语句中的并行函数调用语句
PROCESS(dat3,dat4)
BEGIN
out2 <= max(dat3,dat4); --顺序函数调用语句
END PROCESS;
END;
接上页
KX
康芯科技图 8-2 例 8-4的逻辑电路图
·
·
·
·
8.3.1 函数( FUNCTION)
KX
康芯科技
【 例 8-5】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL ;
ENTITY func IS
PORT ( a,IN STD_LOGIC_VECTOR (0 to 2 ) ;
m,OUT STD_LOGIC_VECTOR (0 to 2 ) );
END ENTITY func ;
ARCHITECTURE demo OF func IS
FUNCTION sam(x,y,z,STD_LOGIC) RETURN STD_LOGIC IS
BEGIN
RETURN ( x AND y ) OR z ;
END FUNCTION sam ;
BEGIN
PROCESS ( a )
BEGIN
m(0)?= sam( a(0),a(1),a(2) ) ;
m(1)?= sam( a(2),a(0),a(1) ) ;
m(2)?= sam( a(1),a(2),a(0) ) ;
END PROCESS ;
END ARCHITECTURE demo ;
KX
康芯科技
8.3.2 重载函数( OVERLOADED FUNCTION)
【 例 8-6】 ( 本例 MaxplusII不支持 )
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;
PACKAGE packexp IS --定义程序包
FUNCTION max( a,b,IN STD_LOGIC_VECTOR) --定义函数首
RETURN STD_LOGIC_VECTOR ;
FUNCTION max( a,b,IN BIT_VECTOR) --定义函数首
RETURN BIT_VECTOR ;
FUNCTION max( a,b,IN INTEGER ) --定义函数首
RETURN INTEGER ;
END;
PACKAGE BODY packexp IS
FUNCTION max( a,b,IN STD_LOGIC_VECTOR) --定义函数体
RETURN STD_LOGIC_VECTOR IS
BEGIN
IF a > b THEN RETURN a;
ELSE RETURN b; END IF;
END FUNCTION max; --结束 FUNCTION语句
FUNCTION max( a,b,IN INTEGER) --定义函数体
RETURN INTEGER IS
BEGIN
接下页
KX
康芯科技
IF a > b THEN RETURN a;
ELSE RETURN b; END IF;
END FUNCTION max; --结束 FUNCTION语句
FUNCTION max( a,b,IN BIT_VECTOR) --定义函数体
RETURN BIT_VECTOR IS
BEGIN
IF a > b THEN RETURN a;
ELSE RETURN b; END IF;
END FUNCTION max; --结束 FUNCTION语句
END; --结束 PACKAGE BODY语句
-- 以下是调用重载函数 max的程序:
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;
USE WORK.packexp.ALL;
ENTITY axamp IS
PORT(a1,b1,IN STD_LOGIC_VECTOR(3 DOWNTO 0);
a2,b2,IN BIT_VECTOR(4 DOWNTO 0);
a3,b3,IN INTEGER RANGE 0 TO 15;
c1,OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
c2,OUT BIT_VECTOR(4 DOWNTO 0);
c3,OUT INTEGER RANGE 0 TO 15);
END;
接上页
KX
康芯科技
ARCHITECTURE bhv OF axamp IS
BEGIN
c1 <= max(a1,b1); --对函数 max( a,b,IN STD_LOGIC_VECTOR)的调用
c2 <= max(a2,b2); --对函数 max( a,b,IN BIT_VECTOR) 的调用
c3 <= max(a3,b3); --对函数 max( a,b,IN INTEGER) 的调用
END;
接上页
【 例 8-7】
LIBRARY IEEE ; -- 程序包首
USE IEEE.std_logic_1164.all ;
USE IEEE.std_logic_arith.all ;
PACKAGE STD_LOGIC_UNSIGNED is
function "+" (L,STD_LOGIC_VECTOR ; R,INTEGER)
return STD_LOGIC_VECTOR ;
function "+" (L,INTEGER; R,STD_LOGIC_VECTOR)
return STD_LOGIC_VECTOR ;
function "+" (L,STD_LOGIC_VECTOR ; R,STD_LOGIC )
return STD_LOGIC_VECTOR ;
function SHR (ARG,STD_LOGIC_VECTOR ;
COUNT,STD_LOGIC_VECTOR ) return STD_LOGIC_VECTOR ;
接下页
KX
康芯科技
...
end STD_LOGIC_UNSIGNED ;
LIBRARY IEEE ; -- 程序包体
use IEEE.std_logic_1164.all ;
use IEEE.std_logic_arith.all ;
package body STD_LOGIC_UNSIGNED is
function maximum (L,R,INTEGER) return INTEGER is
begin
if L? R then return L;
else return R;
end if;
end;
function "+" (L,STD_LOGIC_VECTOR ; R,INTEGER)
return STD_LOGIC_VECTOR is
Variable result,STD_LOGIC_VECTOR (L’range) ;
Begin
result,= UNSIGNED(L) + R ;
return std_logic_vector(result) ;
end ;
...
end STD_LOGIC_UNSIGNED ;
接上页
KX
康芯科技
8.3.3 过程 (PROCEDURE)
PROCEDURE 过程名 (参数表 ) -- 过程首
PROCEDURE 过程名 (参数表 ) IS
[说明部分 ]
BIGIN -- 过程体顺序语句 ;
END PROCEDURE 过程名 ;
PROCEDURE pro1 (VARIABLE a,b,INOUT REAL) ;
PROCEDURE pro2 (CONSTANT a1,IN INTEGER ;
VARIABLE b1,OUT INTEGER ) ;
PROCEDURE pro3 (SIGNAL sig,INOUT BIT) ;
8.3 子程序 (SUBPROGRAM)
KX
康芯科技
8.3.3 过程 (PROCEDURE)
8.3 子程序 (SUBPROGRAM)
【 例 8-8】
PROCEDURE prg1(VARIABLE value:INOUT BIT_VECTOR(0 TO 7)) IS
BEGIN
CASE value IS
WHEN "0000" => value,"0101" ;
WHEN "0101" => value,"0000" ;
WHEN OTHERS => value,"1111" ;
END CASE ;
END PROCEDURE prg1 ;
KX
康芯科技【 例 8-9】
PROCEDURE comp ( a,r,IN REAL;
m,IN INTEGER ;
v1,v2,OUT REAL) IS
VARIABLE cnt,INTEGER ;
BEGIN
v1,= 1.6 * a ; -- 赋初始值
v2,= 1.0 ; -- 赋初始值
Q1,FOR cnt IN 1 TO m LOOP
v2,= v2 * v1 ;
EXIT Q1 WHEN v2 > v1; -- 当 v2 > v1,跳出循环 LOOP
END LOOP Q1
ASSERT (v2 < v1 )
REPORT "OUT OF RANGE" -- 输出错误报告
SEVERITY ERROR ;
END PROCEDURE comp ;
KX
康芯科技
8.3.4 重载过程 (OVERLOADED PROCEDURE)
8.3 子程序 (SUBPROGRAM)
【 例 8-10】
PROCEDURE calcu ( v1,v2,IN REAL ;
SIGNAL out1,INOUT INTEGER) ;
PROCEDURE calcu ( v1,v2,IN INTEGER ;
SIGNAL out1,INOUT REAL) ;
...
calcu (20.15,1.42,signl) ; -- 调用第一个重载过程 calcu
calcu (23,320,sign2 ) ; -- 调用第二个重载过程 calcu
...
KX
康芯科技
1,IEEE库
2,STD库
3,WORK库
4,VITAL库
8.4 VHDL库
8.4.1 库的种类
LIBRARY STD ;
USE STD.STANDARD.ALL ;
KX
康芯科技
8.4.2 库的用法
8.4 VHDL库
USE 库名,程序包名,项目名 ;
USE 库名,程序包名,ALL ;
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.STD_ULOGIC ;
USE IEEE.STD_LOGIC_1164.RISING_EDGE ;
KX
康芯科技
8.5 VHDL程序包程序包常数说明 VHDL数据类型说明 元件定义 子程序
PACKAGE 程序包名 IS -- 程序包首程序包首说明部分
END 程序包名 ;
PACKAGE BODY 程序包名 IS -- 程序包体程序包体说明部分以及包体内
END 程序包名 ;
KX
康芯科技
【 例 8-11】
PACKAGE pacl IS -- 程序包首开始
TYPE byte IS RANGE 0 TO 255 ; -- 定义数据类型 byte
SUBTYPE nibble IS byte RANGE 0 TO 15 ; -- 定义子类型 nibble
CONSTANT byte_ff,byte,= 255 ; -- 定义常数 byte_ff
SIGNAL addend,nibble ; -- 定义信号 addend
COMPONENTbyte_adder -- 定义元件
PORT( a,b,IN byte ;
c,OUT byte ;
overflow,OUT BOOLEAN ) ;
END COMPONENT ;
FUNCTION my_function (a,IN byte) Return byte ; -- 定义函数
END pacl ; -- 程序包首结束
8.5 VHDL程序包
KX
康芯科技【 例 8-12】
PACKAGE seven IS
SUBTYPE segments is BIT_VECTOR(0 TO 6) ;
TYPE bcd IS RANGE 0 TO 9 ;
END seven ;
USE WORK.seven.ALL ; -- WORK库默认是打开的,
ENTITY decoder IS
PORT (input,bcd; drive,out segments) ;
END decoder ;
ARCHITECTURE simple OF decoder IS
BEGIN
WITH input SELECT
drive <= B"1111110" WHEN 0,
B"0110000" WHEN 1,
B"1101101" WHEN 2,
B"1111001" WHEN 3,
B"0110011" WHEN 4,
B"1011011" WHEN 5,
B"1011111" WHEN 6,
B"1110000" WHEN 7,
B"1111111" WHEN 8,
B"1111011" WHEN 9,
B"0000000" WHEN OTHERS ;
END simple ;
KX
康芯科技常用的预定义的程序包
STD_LOGIC_1164程序包
STD_LOGIC_ARITH程序包
STD_LOGIC_UNSIGNED和
STD_LOGIC_SIGNED程序包
STANDARD和 TEXTIO
程序包
8.5 VHDL程序包
KX
康芯科技
8.6 配置配置语句的一般格式如下:
CONFIGURATION 配置名 OF 实体名 IS
配置说明
END 配置名 ;
配置可以把特定的结构体关联到(指定给)一个确定的实体。
KX
康芯科技
8.7 VHDL文字规则
8.7.1 数字整数,整数都是十进制的数,
实数文,实数也都是十进制的数,但必须带有小数点,
以数制基数表示的文字,用这种方式表示的数由五个部分组成 。
SIGNAL d1,d2,d3,d4,d5,,INTEGER RANGE 0 TO 255;
d1 <= 110#170# ; -- (十进制表示,等于 170)
d2 <= 16#FE# ; -- (十六进制表示,等于 254)
d3 <= 2#1111_1110#; -- (二进制表示,等于 254)
d4 <= 8#376# ; -- (八进制表示,等于 254)
d5 <= 16#E#E1 ; -- (十六进制表示,等于 2#1110000#,等于 224)
物理量文字 (VHDL综合器不接受此类文字 )。
KX
康芯科技
8.7 VHDL文字规则
8.7.2 字符串
(1) 文字字符串
(2) 数位字符串
data1 <= B"1_1101_1110" -- 二进制数数组,位矢数组长度是 9
data2 <= O"15" -- 八进制数数组,位矢数组长度是 6
data3 <= X"AD0" -- 十六进制数数组,位矢数组长度是 12
data4 <= B"101_010_101_010" -- 二进制数数组,位矢数组长度是 12
data5 <= "101_010_101_010" --表达错误,缺 B。
data6 <= "0AD0" --表达错误,缺 X。
KX
康芯科技
8.7 VHDL文字规则
8.7.3 标识符合法的标识符:
Decoder_1,FFT,Sig_N,Not_Ack,State0,Idle
非法的标识符:
_Decoder_1 -- 起始为非英文字母
2FFT -- 起始为数字
Sig_#N -- 符号,#” 不能成为标识符的构成
Not-Ack -- 符号,-” 不能成为标识符的构成
RyY_RST_ -- 标识符的最后不能是下划线,_”
data_ _BUS -- 标识符中不能有双下划线
return -- 关键词
KX
康芯科技
8.7 VHDL文字规则
8.7.4 下标名下标名的语句格式如下:
标识符 (表达式 )
SIGNAL a,b,BIT_VECTOR (0 TO 3) ;
SIGNAL m,INTEGER RANGE 0 TO 3 ;
SIGNAL y,z,BIT ;
y <= a(m) ; -- 不可计算型下标表示
z <= b(3) ; -- 可计算型下标表示
KX
康芯科技
8.8 数据类型标量型 (Scalar Type):
包括实数类型,整数类型,枚举类型,时间类型 。
复合类 型 (Composite Type):
可以由小的数据类型复合而成,如可由标量型复合而成 。 复合类型主要有数组型 (Array)和记录型 (Record)。
存取类型 (Access Type):
为给定的数据类型的数据对象提供存取方式 。
文件类型 (Files Type):
用于提供多值存取类型 。
KX
康芯科技
8.8.1 VHDL的预定义数据类型
1,布尔 (BOOLEAN)数据类型
2,位 (BIT)数据类型
TYPE BOOLEAN IS (FALSE,TRUE)
TYPE BIT IS ('0','1')
8.8 数据类型
KX
康芯科技
8.8.1 VHDL的预定义数据类型
3,位矢量 (BIT_VECTOR)数据类型
4,字符 (CHARACTER)数据类型
TYPE BIT_VECTOR IS ARRAY (Natural Range <> ) OF BIT ;
5,整数 (INTEGER)数据类型
8.8 数据类型
KX
康芯科技
8.8.1 VHDL的预定义数据类型
6,实数 (REAL)数据类型
7,字符串 (STRING)数据类型
1.0 十进制浮点数
0.0 十进制浮点数
65971.333333 十进制浮点数
65_971.333_3333 与上一行等价
8#43.6#e+4 八进制浮点数
43.6E- 4 十进制浮点数
VARIABLE string_var,STRING (1 TO 7 ) ;
string_var,= "a b c d" ;
8.8 数据类型
KX
康芯科技
8,时间 (TIME)数据类型
TYPE time IS RANGE - 2147483647 TO 2147483647
units
fs ; -- 飞秒,VHDL中的最小时间单位
ps = 1000 fs ; -- 皮秒
ns = 1000 ps ; -- 纳秒
us = 1000 ns ; -- 微秒
ms = 1000 us ; -- 毫秒
sec = 1000 ms ; -- 秒
min = 60 sec ; -- 分
hr = 60 min ; -- 时
end units ;
8.8.1 VHDL的预定义数据类型
KX
康芯科技
8.8.2 IEEE预定义标准逻辑位与矢量
1,标准逻辑位 STD_LOGIC数据类型
2,标准逻辑矢量 (STD_LOGIC_VECTOR)数据类型
TYPE STD_LOGIC_VECTOR IS ARRAY ( NATURAL RANGE
<> ) OF STD_LOGIC ; TYPE BOOLEAN IS (FALSE,TRUE)
8.8 数据类型
KX
康芯科技
8.8.3 其他预定义标准数据类型
1,无符号数据类型 (UNSIGNED TYPE)
LIBRARY IEEE ;
USE IEEE.STD_LOIGC_ARITH.ALL ;
VARIABLE var,UNSIGNED(0 TO 10) ;
SIGNAL sig,UNSIGNED(5 TO 0) ;
8.8 数据类型
KX
康芯科技
8.8.3 其他预定义标准数据类型
2,有符号数据类型 (SIGNED TYPE)
SIGNED'("0101") 代表 +5,5
SIGNED'("1011")代表 –5
VARIABLE var,SIGNED(0 TO 10);
8.8 数据类型
KX
康芯科技
8.8.4 数组类型
TYPE数组名 IS ARRAY(数组范围 )OF数据类型 ;
TYPE stb IS ARRAY (7 DOWNTO 0) of STD_LOGIC ;
TYPE x is (low,high) ;
TYPE data_bus IS ARRAY (0 TO 7,x) of BIT ;
TYPE数组名 IS ARRAY (数组下标名 RANGE)OF数据类型 ;
8.8 数据类型
KX
康芯科技
【 例 8-13】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY amp IS
PORT ( a1,a2,IN BIT_VECTOR(3 DOWNTO 0);
c1,c2,c3,IN STD_LOGIC_VECTOR (3 DOWNTO 0);
b1,b2,b3,INTEGER RANGE 0 TO 15;
d1,d2,d3,d4,OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );
END amp;
d1 <= TO_STDLOGICVECTOR(a1 AND a2); --(1)
d2 < = CONV_STD_LOGIC_VECTOR(b1,4) WHEN CONV_INTEGER(b2)=9
else CONV_STD_LOGIC_VECTOR(b3,4); --(2)
d3 < = c1 WHEN CONV_INTEGER(c2)= 8 ELSE c3; --(3)
d4 < = c1 WHEN c2 = 8 else c3; --(4)
KX
康芯科技
【 例 8-14】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY decoder3to8 IS
PORT ( input,IN STD_LOGIC_VECTOR (2 DOWNTO 0);
output,OUT STD_LOGIC_VECTOR (7 DOWNTO 0));
END decoder3to8;
ARCHITECTURE behave OF decoder3to8 IS
BEGIN
PROCESS (input)
BEGIN
output <= (OTHERS => '0');
output(CONV_INTEGER(input)) <= '1';
END PROCESS;
END behave;
KX
康芯科技
【 例 8-15】
FUNCTION To_bit ( s,std_ulogic; xmap,BIT,= '0' ) RETURN BIT ;
FUNCTION To_bitvector ( s,std_logic_vector ;
xmap,BIT,= '0' ) RETURN BIT_VECTOR ;
FUNCTION To_bitvector ( s,std_ulogic_vector;
xmap,BIT,= '0' ) RETURN BIT_VECTOR ;
8.8.4 数组类型
8.8 数据类型
KX
康芯科技下面是转换函数 To_bitvector的函数体:
FUNCTION To_bitvector ( s,std_logic_vector ;
xmap,BIT,= '0' )
RETURN BIT_VECTOR IS
ALIAS sv,std_logic_vector(s'LENGTH-1 DOWNTO 0 ) IS s ;
VARIABLE result,BIT_VECTOR(s'LENGTH-1 DOWNTO 0 );
BEGIN
FOR i IN result'RANGE LOOP
CASE sv(i) IS
WHEN '0'|'L' => result(i),= '0';
WHEN '1'|'H' => result(i),= '1';
WHEN OTHERS => result(i),= xmap;
END CASE ;
END LOOP ;
RETURN result ;
END ;
KX
康芯科技
8.9.1 逻辑操作符
8.9 VHDL操作符逻辑操作符 (Logical Operator)
关系操作符 (Relational Operator)
算术操作符 (Arithmetic Operator)
符号操作符 (Sign Operator)
重载操作符 (Overloading Operator)
严格遵循在基本操作符间操作数是同数据类型的规则。
严格遵循操作数的数据类型必须与操作符所要求的数据类型完全一致。
KX
康芯科技表 8-1 VHDL操作符列表类 型 操作符 功 能 操作数数据类型算术操作符
+ 加 整数
- 减 整数
& 并置 一维数组
* 乘 整数和实数 (包括浮点数 )
/ 除 整数和实数 (包括浮点数 )
MOD 取模 整数
REM 取余 整数
SLL 逻辑左移 BIT或布尔型一维数组
SRL 逻辑右移 BIT或布尔型一维数组
SLA 算术左移 BIT或布尔型一维数组
SRA 算术右移 BIT或布尔型一维数组
ROL 逻辑循环左移 BIT或布尔型一维数组
ROR 逻辑循环右移 BIT或布尔型一维数组
** 乘方 整数
ABS 取绝对值 整数
KX
康芯科技表 8-1 VHDL操作符列表关系操作符
= 等于 任何数据类型
/= 不等于 任何数据类型
< 小于 枚举与整数类型,及对应的一维数组
> 大于 枚举与整数类型,及对应的一维数组
<= 小于等于 枚举与整数类型,及对应的一维数组
>= 大于等于 枚举与整数类型,及对应的一维数组逻辑操作符
AND 与 BIT,BOOLEAN,STD_LOGIC
OR 或 BIT,BOOLEAN,STD_LOGIC
NAND 与非 BIT,BOOLEAN,STD_LOGIC
NOR 或非 BIT,BOOLEAN,STD_LOGIC
XOR 异或 BIT,BOOLEAN,STD_LOGIC
XNOR 异或非 BIT,BOOLEAN,STD_LOGIC
NOT 非 BIT,BOOLEAN,STD_LOGIC
符号操作符 + 正 整数
- 负 整数
KX
康芯科技
8.9.1 逻辑操作符
8.9 VHDL操作符运算符 优先级
NOT,ABS,** 最高优先级
*,/,MOD,REM
+(正号 ),- (负号 )
+,-,&
SLL,SLA,SRL,SRA,ROL,ROR
=,/=,<,<=,>,>=
AND,OR,NAND,NOR,XOR,XNOR 最低优先级表 8-2 VHDL操作符优先级
KX
康芯科技
8.9.1 逻辑操作符
8.9 VHDL操作符
【 例 8-16】
SIGNAL a,b,c,STD_LOGIC_VECTOR (3 DOWNTO 0) ;
SIGNAL d,e,f,g,STD_LOGIC_VECTOR (1 DOWNTO 0) ;
SIGNAL h,I,j,k,STD_LOGIC ;
SIGNAL l,m,n,o,p,BOOLEAN ;
...
a<=b AND c; --b,c 相与后向 a赋值,a,b,c的数据类型同属 4位长的位矢量
d<=e OR f OR g ; -- 两个操作符 OR相同,不需括号
h<=(i NAND j)NAND k ; -- NAND不属上述三种算符中的一种,必须加括号
l<=(m XOR n)AND(o XOR p); -- 操作符不同,必须加括号
h<=i AND j AND k ; -- 两个操作符都是 AND,不必加括号
h<=i AND j OR k ; -- 两个操作符不同,未加括号,表达错误
a<=b AND e ; -- 操作数 b 与 e的位矢长度不一致,表达错误
h<=i OR l ; -- i 的数据类型是位 STD_LOGIC,而 l的数据类型是
..,-- 布尔量 BOOLEAN,因而不能相互作用,表达错误。
KX
康芯科技
8.9.2 关系操作符
8.9 VHDL操作符
【 例 8-17】
ENTITY relational_ops_1 IS
PORT ( a,b,IN BIT_ VECTOR (0 TO 3) ;
m,OUT BOOLEAN) ;
END relational_ops_1 ;
ARCHITECTURE example OF relational_ops_1 IS
BEGIN
output <= (a = b) ;
END example ;
KX
康芯科技
8.9.2 关系操作符
8.9 VHDL操作符
【 例 8-18】
ENTITY relational_ops_2 IS
PORT (a,b,IN INTEGER RANGE 0 TO 3 ;
m,OUT BOOLEAN) ;
END relational_ops_2 ;
ARCHITECTURE example OF relational_ops_2 IS
BEGIN
output <= (a >= b) ;
END example ;
KX
康芯科技
8.9.3 算术操作符
8.9 VHDL操作符类 别 算术操作符分类
1 求和操作符 (Adding operators) +(加 ),- (减 ),?(并置 )
2 求 积 操 作 符 ( Multiplying
operators)
*,/,MOD,REM
3 符号操作符 (Sign operators) +(正 ),- (负 )
4 混 合 操 作 符 ( Miscellaneous
operators)
**,ABS
5 移位操作符 (Shift operators) SLL,SRL,SLA,SRA,ROL,
ROR
表 8-3 算术操作符分类表
KX
康芯科技
8.9.3 算术操作符
8.9 VHDL操作符
1,求和操作符
【 例 8-19】
VARIABLE a,b,c,d,e,f,INTEGER RANGE 0 TO 255 ;
...
a,= b + c ; d,= e – f ;
【 例 8-20】
PROCEDURE adding_e (a,IN INTEGER ; b,INOUT INTEGER ) IS
...
b,= a + b ;
KX
康芯科技
1,求和操作符
【 例 8-21】
PACKAGE example_arithmetic IS
TYPE small_INt IS RANGE 0 TO 7 ;
END example_arithmetic ;
USE WORK.example_arithmetic.ALL ;
ENTITY arithmetic IS
PORT (a,b,IN SMALL_INT ;
c,OUT SMALL_INT) ;
END arithmetic ;
ARCHITECTURE example OF arithmetic IS
BEGIN
c <= a + b ;
END example ;
KX
康芯科技
8.9.3 算术操作符
8.9 VHDL操作符
2,求积操作符
* (乘 ),/ (除 ),MOD (取模 ),RED (取余 )
3,符号操作符
,+,,,-

KX
康芯科技
8.9.3 算术操作符
8.9 VHDL操作符
4,混合操作符
,**,,,ABS,
【 例 8-22】
SIGNAL a,b,INTEGER RANGE - 8 to 7 ;
SIGNAL c,INTEGER RANGE 0 to 15 ;
SIGNAL d,INTEGER RANGE 0 to 3 ;
a <= ABS(b) ;
c <= 2 ** d ;
KX
康芯科技
8.9.3 算术操作符
8.9 VHDL操作符
5,移位操作符
SLL,SRL,SLA,SRA,ROL,ROR
移位操作符的语句格式是:
标识符 移位操作符 移位位数 ;
KX
康芯科技
8.9.3 算术操作符
5,移位操作符
【 例 8-23】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY decoder3to8 IS
port ( input,IN STD_LOGIC_VECTOR (2 DOWNTO 0);
output,OUT BIT_VECTOR (7 DOWNTO 0));
END decoder3to8;
ARCHITECTURE behave OF decoder3to8 IS
BEGIN
output <= "00000001" SLL CONV_INTEGER(input); --被移位部分是常数!
END behave;
KX
康芯科技习 题
8-1 说明实体概念,设计实体 。
8-2 举例说明类属,类属映射语句有何用处 。
8-3 说明端口模式 INOUT和 BUFFER有何异同点 。
8-4 什么是重载? 重栽函数有何用处?
8-5 在以下数据类型中,VHDL综合器支持哪些类型:
STRING,TIME,REAL,BIT
KX
康芯科技习 题
8-6 详细说明例 8-23中的语句作用和程序实现的功能 。
8-7 表式 C <= A + B中,A,B和 C的数据类型都是 STD_LOGIC_VECTOR
,是否能直接进行加法运算? 说明原因和解决方法 。
8-8 VHDL中有哪 3种数据对象? 详细说明它们的功能特点以及使用方法,
举例说明数据对象与数据类型的关系 。
8-9 能把任意一种进制的值向一整数类型的数据对象赋值吗? 如果能,怎样做?
8-10 判断下列 VHDL标识符是否合法,如果有误则指出原因:
16# 0FA#,10# 12F#,8# 789#,8# 356#,2# 0101010#
74HC245,\74HC574\,CLR/RESET,\IN 4/SCLK\,D100%
KX
康芯科技习 题
8-11 数据类型 BIT,INTEGER和 BOOLEAN分别定义在哪个库中? 哪些库和程序包总是可见的?
8-12 函数与过程有什么区别?
8-13 回答有关 Bit和 Boolean数据类型的问题:
(1) 解释 Bit和 Boolean类型的区别;
(2) 对于逻辑操作应使用哪种类型?
(3) 关系操作的结果为哪种类型?
(4) IF语句测试的表达式是哪种类型?
KX
康芯科技习 题
8-14 运算符重载函数通常要调用转换函数,以便能够利用已有的数据类型
。 下面给出一个新的数据类型 AGE,并且下面的转换函数已经实现:
function CONV_INTEGER(ARG:AGE) return INTEGER;
仿照本章中的示例,利用此函数编写一个,+” 运算符重载函数,支持下面的运算:
SIGNAL a,c,AGE;
...
c <= a + 20;
8-15 用两种方法设计 8位比较器,比较器的输入是两个待比较的 8位数
A=[A7..A0]和 B=[B7..B0],输出是 D,E,F。 当 A=B时 D=1; 当 A>B时 E=1; 当 A<B时 F=1。 第一种设计方案是常规的比较器设计方法,即直接利用关系操作符进行编程设计;第二种设计方案是利用减法器来完成,通过减法运算后的符号和结果来判别两个被比较值的大小 。 对两种设计方案的资源耗用情况进行比较,并给以解释 。
KX
康芯科技实 验 与 设 计
8-1 移位相加 8位硬件乘法器电路设计
(1) 实验目的:学习应用移位相加原理设计 8位乘法器 。
(2) 实验原理:该乘法器是由 8位加法器构成的以时序方式设计的 8位乘法器 。 其乘法原理是:乘法通过逐项移位相加原理来实现 。 从被乘数的最低位开始,若为 1,则乘数左移后与上一次的和相加;若为 0,左移后以全零相加,直至被乘数的最高位 。 从图 8-3的逻辑图及其乘法操作时序图图 8-4(示例中的相乘数为 9FH和 FDH )上可以清楚地看出此乘法器的工作原理,为了更好了解其工作原理,图 8-3中没有加入控制电路 ( 例 8-28) 。
图 8-3中,START信号的上跳沿及其高电平有两个功能,即 16
位寄存器清零和被乘数 A[7..0]向移位寄存器 SREG8B加载;它的低电平则作为乘法使能信号 。 CLK为乘法时钟信号 。 当被
KX
康芯科技实 验 与 设 计乘数被加载于 8位右移寄存器 SREG8B后,随着每一时钟节拍,
最低位在前,由低位至高位逐位移出 。 当为 1时,1位乘法器
ANDARITH打开,8位乘数 B[7..0]在同一节拍进入 8位加法器,
与上一次锁存在 16位锁存器 REG16B中的高 8位进行相加,其和在下一时钟节拍的上升沿被锁进此锁存器 。 而当被乘数的移出位为 0时,与门全零输出 。 如此往复,直至 8个时钟脉冲后,
最后乘积完整出现在 REG16B端口 。 在这里,1位乘法器
ANDARITH的功能类似于 1个特殊的与门,即当 ABIN为 ‘ 1’
时,DOUT直接输出 DIN,而当 ABIN为 ‘ 0’ 时,DOUT输出全,00000000” 。
8位移位相加原理构成的乘法器比用组合电路直接设计的同样功能的电路的资源 ( 逻辑宏单元 LCs) 耗用要小许多,由编译报告可知,前者是 52,后者是 169。
KX
康芯科技实 验 与 设 计图 8-3 8位乘法器逻辑原理图
KX
康芯科技实 验 与 设 计图 8-4 8位移位相加乘法器运算逻辑波形图从波形图图 8-4可见,当 9FH和 FDH相乘时,第 1个时钟上升沿后,其移位相加的结果 (在 REG16B端口 )是 4F80H,第 8个时钟上升沿后,最终相乘结果是 9D23H。
KX
康芯科技【 例 8-24】
LIBRARY IEEE; -- 8位右移寄存器
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY SREG8B IS
PORT ( CLK,LOAD,IN STD_LOGIC;
DIN,IN STD_LOGIC_VECTOR(7 DOWNTO 0);
QB,OUT STD_LOGIC );
END SREG8B;
ARCHITECTURE behav OF SREG8B IS
SIGNAL REG8,STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
PROCESS (CLK,LOAD)
BEGIN
IF CLK'EVENT AND CLK = '1' THEN
IF LOAD = '1' THEN REG8 <= DIN;
ELSE REG8(6 DOWNTO 0) <= REG8(7 DOWNTO 1);
END IF;
END IF;
END PROCESS;
QB <= REG8(0); -- 输出最低位
END behav;
KX
康芯科技
【 例 8-25】
LIBRARY IEEE; --8位加法器
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ADDER8B IS
PORT ( CIN,IN STD_LOGIC;
A,B,IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S,OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
COUT,OUT STD_LOGIC );
END ADDER8B;
ARCHITECTURE behav OF ADDER8B IS
SIGNAL SINT,AA,BB,STD_LOGIC_VECTOR(8 DOWNTO 0);
BEGIN
AA<='0'&A; BB<='0'&B; SINT<=AA+BB+CIN;S<=SINT(7 DOWNTO 0);
COUT<=SINT(8);
END behav;
KX
康芯科技【 例 8-26】
LIBRARY IEEE; --1位乘法器
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ANDARITH IS -- 选通与门模块
PORT ( ABIN,IN STD_LOGIC;
DIN,IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUT,OUT STD_LOGIC_VECTOR(7 DOWNTO 0) );
END ANDARITH;
ARCHITECTURE behav OF ANDARITH IS
BEGIN
PROCESS(ABIN,DIN)
BEGIN
FOR I IN 0 TO 7 LOOP -- 循环,完成 8位与 1位运算
DOUT(I) <= DIN(I) AND ABIN;
END LOOP;
END PROCESS;
END behav;
KX
康芯科技
【 例 8-27】
LIBRARY IEEE; --16位锁存器 /右移寄存器
USE IEEE.STD_LOGIC_1164.ALL;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY REG16B IS -- 16位锁存器
PORT (CLK,CLR,IN STD_LOGIC;
D,IN STD_LOGIC_VECTOR(8 DOWNTO0);
Q,OUT STD_LOGIC_VECTOR(15DOWNTO 0) );
END REG16B;
ARCHITECTURE behav OF REG16B IS
SIGNAL R16S,STD_LOGIC_VECTOR(15DOWNTO 0);
BEGIN
PROCESS(CLK,CLR) 接下页
KX
康芯科技接上页
BEGIN
IF CLR='1' THEN R16S<="0000000000000000";--时钟到来时,锁存输入值,并右移低 8位
ELSIF CLK'EVENT AND CLK='1' THEN
R16S(6 DOWNTO0) <=R16S(7 DOWNTO 1);--右移低 8位
R16S(15 DOWNTO 7) <= D; -- 将输入锁到高 8位
END IF;
END PROCESS;
Q <= R16S;
END behav;
KX
康芯科技
【 例 8-28】
LIBRARY IEEE; --运算控制模块
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ARICTLIS
PORT (CLK,START,IN STD_LOGIC;
CLKOUT,RSTALL,ARIEND,OUT STD_LOGIC );
END ARICTL;
ARCHITECTURE behav OF ARICTL IS
SIGNAL CNT4B,STD_LOGIC_VECTOR(3 DOWNTO0);
BEGIN
RSTALL <= START;
PROCESS(CLK,START)
BEGIN 接下页
KX
康芯科技接上页
IF START = '1' THEN CNT4B <= "0000";
ELSIF CLK'EVENT AND CLK = '1' THEN
IF CNT4B < 8 THEN CNT4B <= CNT4B + 1; END IF;
END IF;
END PROCESS;
PROCESS(CLK,CNT4B,START)
BEGIN
IF START = '0' THEN
IF CNT4B < 8 THEN CLKOUT <= CLK; ARIEND <= '0';
ELSE CLKOUT <= '0'; ARIEND <= '1'; END IF;
ELSE CLKOUT <= CLK; ARIEND <= '0';
END IF;
END PROCESS;
END behav;
KX
康芯科技
【 例 8-29】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
ENTITY MULTI8X8 IS -- 8位乘法器顶层设计
PORT ( CLKk,hkey,START,IN STD_LOGIC;
A,B,IN STD_LOGIC_VECTOR(7 DOWNTO 0);
mmax,out STD_LOGIC_VECTOR(3 DOWNTO 0);
ARIEND,OUT STD_LOGIC;
DOUT,OUT STD_LOGIC_VECTOR(15DOWNTO 0) );
END MULTI8X8;
ARCHITECTURE struc OF MULTI8X8 IS
COMPONENTARICTL
PORT ( CLK,IN STD_LOGIC; START,IN STD_LOGIC; 接下页
KX
康芯科技
CLKOUT,OUT STD_LOGIC; RSTALL,OUT STD_LOGIC;
ARIEND,OUT STD_LOGIC );
END COMPONENT;
COMPONENTANDARITH
PORT ( ABIN,IN STD_LOGIC;
DIN,IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUT,OUT STD_LOGIC_VECTOR(7 DOWNTO 0) );
END COMPONENT;
COMPONENTADDER8B
PORT (CIN,IN STD_LOGIC;
A,B,IN STD_LOGIC_VECTOR(7 DOWNTO0);
S,OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
COUT,OUT STD_LOGIC );
END COMPONENT; 接下页
KX
康芯科技
COMPONENTSREG8B
PORT ( CLK,IN STD_LOGIC; LOAD,IN STD_LOGIC;
DIN,IN STD_LOGIC_VECTOR(7 DOWNTO0);
QB,OUT STD_LOGIC );
END COMPONENT;
COMPONENTREG16B
PORT ( CLK,IN STD_LOGIC; CLR,IN STD_LOGIC;
D,IN STD_LOGIC_VECTOR(8 DOWNTO0);
Q,OUT STD_LOGIC_VECTOR(15DOWNTO 0) );
END COMPONENT;
SIGNAL GNDINT,INTCLK,RSTALL,NEWSTART,QB,clk,
STD_LOGIC;
SIGNALANDSD,STD_LOGIC_VECTOR(7 DOWNTO0);
SIGNAL count,maxx,STD_LOGIC_VECTOR(3 DOWNTO 0); 接下页
KX
康芯科技
SIGNAL DTBIN,STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL DTBOUT,STD_LOGIC_VECTOR(15 DOWNTO0);
BEGIN
DOUT <= DTBOUT; GNDINT <= '0';
PROCESS(CLK,START)
BEGIN
IF START='1' THEN NEWSTART<='1';
ELSIF CLK='0'THEN NEWSTART<='0';END IF;
END PROCESS;
process(hkey)
begin
if(hkey'event and hkey='1')then maxx<=maxx+'1';
end if;
end process; 接下页
KX
康芯科技
mmax<=maxx;
process(clkk)
begin
if clkk'event and clkk='1'then
if(count<maxx)then count<=count+'1';
else count<="0000"; clk<=not clk;
end if;
end if;
end process;
U1,ARICTL PORT MAP(CLK => CLK,START => NEWSTART,--FOR
THE BETTER
CLKOUT => INTCLK,RSTALL => RSTALL,ARIEND => ARIEND );
U2,SREG8B PORT MAP( CLK => INTCLK,LOAD => RSTALL,
DIN=>B,QB=>QB); 接下页
KX
康芯科技
U3,ANDARITH PORT MAP(ABIN => QB,DIN => A,DOUT => ANDSD);
U4,ADDER8B PORT MAP(CIN => GNDINT,A=>DTBOUT(15 DOWNTO
8),B=>ANDSD,
S => DTBIN(7 DOWNTO 0),COUT => DTBIN(8) );
U5,REG16B PORT MAP(CLK => INTCLK,CLR =>
RSTALL,D=>DTBIN,Q=>DTBOUT);
END struc;
KX
康芯科技实 验 与 设 计
(3) 实验内容 1,根据给出的乘法器逻辑原理图及其各模块的
VHDL描述,在 MAX+plusII上完成全部设计,包括编辑,编译,综合和仿真操作等 。 以 87H乘以 F5H为例,进行仿真,对仿真波形作出详细解释,包括对 8个工作时钟节拍中,每一节拍乘法操作的方式和结果,对照波形图给以详细说明,根据顶层设计例 8-29,结合图 8-3,画出乘法器的详细电路原理框图

(4) 实验内容 2,编程下载,进行实验验证。实验电路选择
No.1,8位乘数用键 2、键 1输入; 8位被乘数用键 4和键 3输入;
16位乘积可由 4个数码管(数码管 8,7,6,5)显示;用键 8输入 CLK,键 7输入 START( 注意,START由高到低是清 0,由低到高电平是允许乘法计算)。详细观察每一时钟节拍的运算结果,并与仿真结果进行比较。
KX
康芯科技实 验 与 设 计
(5) 实验内容 3,乘法时钟连接实验系统上的连续脉冲,如
clock0,设计一个此乘法器的控制模块,接受实验系统上的连续脉冲,如 clock0,当给定启动 /清 0信号后,能自动发出 CLK
信号驱动乘法运算,当 8个脉冲后自动停止 ( 例 8-28) 。
(6) 实验内容 4,设计一个纯组合电路的 8X8等于 16位的乘法器和一个 LPM乘法器 ( 选择不同的流水线方式 ),具体说明并比较这几种乘法器的逻辑资源占用情况和运行速度情况 。
(7) 实验报告,根据例 8-24至例 8-29,详细分析图 8-3中个模块的逻辑功能,及其他们工作原理,详细记录并分析实验 2和实验 3的过程和结果,完成实验报告 。
KX
康芯科技实 验 与 设 计
8-2 乐曲硬件演奏电路设计
(1) 实验目的,学习利用实验 5-4的数控分频器设计硬件乐曲演奏电路 。
(2) 实验原理,主系统由 3个模块组成,例 8-30是顶层设计文件
,其内部有 3个功能模块 (如图 8-5所示 ),TONETABA.VHD、
NOTETABS.VHD和 SPEAKER.VHD。
与利用微处理器 ( CPU或 MCU) 来实现乐曲演奏相比,以纯硬件完成乐曲演奏电路的逻辑要复杂得多,如果不借助于功能强大的 EDA工具和硬件描述语言,仅凭传统的数字逻辑技术,即使最简单的演奏电路也难以实现 。 本实验设计项目作为,梁祝
” 乐曲演奏电路的实现,其工作原理是这样的:
KX
康芯科技实 验 与 设 计我们知道,组成乐曲的每个音符的发音频率值及其持续的时间是乐曲能连续演奏所需的两个基本要素,问题是如何来获取这两个要素所对应的数值以及通过纯硬件的手段来利用这些数值实现所希望乐曲的演奏效果 。 图 8-5中,模块 U1类似于弹琴的人的手指; U2类似于琴键; U3类似于琴弦或音调发声器 。
下面首先来了解图 8-5的工作原理:
1,音符的频率可以由图 8-5中的 SPEAKERA获得,这是一个数控分频器 ( 其详细工作原理可参考实验 5-4) 。 由其 clk
端输入一具有较高频率 ( 这里是 12MHz) 的信号,通过
SPEAKERA分频后由 SPKOUT输出,由于直接从数控分频器中出来的输出信号是脉宽极窄的脉冲式信号,为了有利于驱动扬声器,需另加一个 D触发器以均衡其占空比,但这时的频率将
KX
康芯科技实 验 与 设 计是原来的 1/2。 SPEAKERA对 clk输入信号的分频比由 11位预置数 Tone[10..0]决定 。 SPKOUT的输出频率将决定每一音符的音调,这样,分频计数器的预置值 Tone[10..0] 与
SPKOUT的输出频率,就有了对应关系 。 例如在 TONETABA模块中若取 Tone[10..0]=1036,将发音符为,3” 音的信号频率 。
2,音符的持续时间须根据乐曲的速度及每个音符的节拍数来确定,图 8-5中模块 TONETABA 的功能首先是为 SPEAKERA
提供决定所发音符的分频预置数,而此数在 SPEAKER输入口停留的时间即为此音符的节拍值 。 模块 TONETABA 是乐曲简谱码对应的分频预置数查表电路,其中设置了,梁祝,乐曲全部音符所对应的分频预置数,共 13个,每一音符的停留时间由音乐节拍和音调发生器模块 NOTETABS
KX
康芯科技实 验 与 设 计的 clk的输入频率决定,在此为 4Hz。 这 13个值的输出由对应于 TONETABA 的 4 位 输 入 值 Index[3..0] 确定,而
Index[3..0] 最多有 16种可选值 。 输向 TONETABA中
Index[3..0]的值 ToneIndex[3..0]的输出值与持续的时间由模块 NOTETABS 决定 。
3,在 NOTETABS 中设置了一个 8位二进制计数器 ( 计数最大值为 138),作为音符数据 ROM的地址发生器 。 这个计数器的计数频率选为 4Hz,即每一计数值的停留时间为 0.25秒,恰为当全音符设为 1秒时,四四拍的 4分音符持续时间 。 例如,
NOTETABS 在以下的 VHDL逻辑描述中,,梁祝,乐曲的第一个音符为,3”,此音在逻辑中停留了 4个时钟节拍,即 1秒时间,相应地,所对应的,3” 音符分频预置值为 1036,在
SPEAKERA 的输入端停留了 1秒 。 随着 NOTETABS中的计数器
KX
康芯科技实 验 与 设 计按 4Hz的时钟速率作加法计数时,即随地址值递增时,音符数据 ROM 中的音符数据将从 ROM中通过 ToneIndex[3..0]端口输向 TONETABA 模块,,梁祝,乐曲就开始连续自然地演奏起来了 。
(3) 实验内容 1,定制例 8-33的 NoteTabs模块中的 音符数据
ROM“music”。 该 ROM中的音符数据已列在 例 8-34中 。 注意该例数据表中的数据位宽,深度和数据的表达类型 。 最后对该
ROM进行仿真,确认例 8-34中的 音符数据已经进入其中 。
(4) 实验内容 2,根据给出的乘法器逻辑原理图及其各模块的
VHDL描述,在 MAX+plusII上完成全部设计,包括编辑,编译,综合和仿真操作等 。 给出仿真波形,并作出详细说明 。
KX
康芯科技实 验 与 设 计
(5) 实验内容 3,硬件验证 。 先将引脚锁定,使 CLK12MHz与
clock9相接,接受 12MHz时钟频率 ( 输入待分频声调频率
12MHz,在实验板上的,高频组,处,用短路帽分别连接
clock9 和,12MHz”) ; CLK8Hz 与 clock2相接,接受
4Hz频率 ( 在实验板上的,低频组,处,用短路帽分别连接
Clock2 和,4Hz”) ; 发音输出 SPKOUT接 Speaker; 与演奏发音相对应的简谱码输出显示可由 CODE1在数码管 5显示;
HIGH1为高八度音指示,可由发光管 D5指示,最后向目标芯片下载适配后的 SOF逻辑设计文件 。 实验电路结构图为 NO.1

(6) 实验内容 4,填入新的乐曲,如,采茶舞曲,,或其它熟悉的乐曲 。 操作步骤如下:
1,根据所填乐曲可能出现的音符,修改例 8-34的音符数据表格,同时注意每一音符的节拍长短,
KX
康芯科技实 验 与 设 计
2,如果乐曲比较长,可增加模块 NOTETABA 中计数器的位数
,如 9位时可达 512个基本节拍 。
(7) 实验内容 5,争取可以在一个 ROM装上多首歌曲,可手动或自动选择歌曲 。
(8) 实验内容 6,根据此项实验设计一个电子琴,硬件测试可用电路结构图 NO.1。
(9) 思考题 1,例 8-31中的进程 DelaySpkS对扬声器发声有什么影响?
(10) 思考题 2,在电路上应该满足哪些条件,才能用数字器件直接输出的方波驱动扬声器发声?
KX
康芯科技实 验 与 设 计
(11) 实验报告:用仿真波形和电路原理图,详细叙述硬件电子琴的工作原理及其 4个 VHDL文件中相关语句的功能,叙述硬件实验情况 。
图 8-5 硬件乐曲演奏电路结构乐曲演奏电路的 VHDL逻辑描述如下,
KX
康芯科技
【 例 8-30】
LIBRARY IEEE; -- 硬件演奏电路顶层设计
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Songer IS
PORT ( CLK12MHZ,IN STD_LOGIC; --音调频率信号
CLK8HZ,IN STD_LOGIC; --节拍频率信号
CODE1,OUT STD_LOGIC_VECTOR (3 DOWNTO 0);-- 简谱码输出显示
HIGH1,OUT STD_LOGIC; --高 8度指示
SPKOUT,OUT STD_LOGIC );--声音输出
END;
ARCHITECTURE one OF Songer IS
COMPONENT NoteTabs
PORT ( clk,IN STD_LOGIC;
ToneIndex,OUT STD_LOGIC_VECTOR (3 DOWNTO 0) );
接下页
KX
康芯科技
END COMPONENT;
COMPONENT ToneTaba
PORT ( Index,IN STD_LOGIC_VECTOR (3 DOWNTO 0) ;
CODE,OUT STD_LOGIC_VECTOR (3 DOWNTO 0) ;
HIGH,OUT STD_LOGIC;
Tone,OUT STD_LOGIC_VECTOR (10 DOWNTO 0) );
END COMPONENT;
COMPONENT Speakera
PORT ( clk,IN STD_LOGIC;
Tone,IN STD_LOGIC_VECTOR (10 DOWNTO 0);
SpkS,OUT STD_LOGIC );
END COMPONENT;
SIGNAL Tone,STD_LOGIC_VECTOR (10 DOWNTO0);
SIGNAL ToneIndex,STD_LOGIC_VECTOR (3 DOWNTO 0); 接下页
KX
康芯科技
BEGIN
u1,NoteTabs PORT MAP (clk=>CLK8HZ,ToneIndex=>ToneIndex);
u2,ToneTaba PORT MAP
(Index=>ToneIndex,Tone=>Tone,CODE=>CODE1,HIGH=>HIGH1);
u3,Speakera PORT MAP(clk=>CLK12MHZ,Tone=>Tone,
SpkS=>SPKOUT );
END;
【 例 8-31】
LIBRARY IEEE;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Speakera IS 接下页
KX
康芯科技
PORT ( clk,IN STD_LOGIC;
Tone,IN STD_LOGIC_VECTOR (10 DOWNTO 0);
SpkS,OUT STD_LOGIC );
END;
ARCHITECTURE one OF Speakera IS
SIGNAL PreCLK,FullSpkS,STD_LOGIC;
BEGIN
DivideCLK,PROCESS(clk)
VARIABLE Count4,STD_LOGIC_VECTOR (3 DOWNTO 0) ;
BEGIN
PreCLK <= '0'; -- 将 CLK进行 16分频,PreCLK为 CLK的 16分频
IF Count4>11 THEN PreCLK <= '1'; Count4,= "0000";
ELSIF clk'EVENT AND clk = '1' THEN Count4,= Count4 + 1;
END IF; 接下页
KX
康芯科技END PROCESS;
GenSpkS,PROCESS(PreCLK,Tone)-- 11位可预置计数器
VARIABLE Count11,STD_LOGIC_VECTOR (10 DOWNTO 0);
BEGIN
IF PreCLK'EVENTAND PreCLK = '1' THEN
IF Count11 = 16#7FF#THEN Count11,= Tone ; FullSpkS <= '1';
ELSE Count11,= Count11 + 1; FullSpkS <= '0'; END IF;
END IF;
END PROCESS;
DelaySpkS,PROCESS(FullSpkS)--将输出再 2分频,展宽脉冲,使扬声器有足够功率发音
VARIABLE Count2,STD_LOGIC;
BEGIN
IF FullSpkS'EVENTAND FullSpkS = '1' THEN Count2,= NOT Count2;
接下页
KX
康芯科技IF Count2 = '1' THEN SpkS <= '1';
ELSE SpkS <= '0'; END IF;
END IF;
END PROCESS;
END;
【 例 8-32】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ToneTaba IS
PORT ( Index,IN STD_LOGIC_VECTOR (3 DOWNTO 0) ;
CODE,OUT STD_LOGIC_VECTOR (3 DOWNTO 0) ;
HIGH,OUT STD_LOGIC;
Tone,OUT STD_LOGIC_VECTOR (10 DOWNTO 0) );
END; 接下页
KX
康芯科技ARCHITECTURE one OF ToneTaba IS
BEGIN
Search,PROCESS(Index)
BEGIN
CASE Index IS -- 译码电路,查表方式,控制音调的预置数
WHEN "0000" => Tone<="11111111111" ; CODE<="0000";HIGH <='0';-- 2047
WHEN "0001" => Tone<="01100000101" ; CODE<="0001";HIGH <='0';-- 773;
WHEN "0010" => Tone<="01110010000" ; CODE<="0010";HIGH <='0';-- 912;
WHEN "0011" => Tone<="10000001100" ; CODE<="0011";HIGH <='0';--1036;
WHEN "0101" => Tone<="10010101101" ; CODE<="0101";HIGH <='0';--1197;
WHEN "0110" => Tone<="10100001010" ; CODE<="0110";HIGH <='0';--1290;
WHEN "0111" => Tone<="10101011100" ; CODE<="0111";HIGH <='0';--1372;
WHEN "1000" => Tone<="10110000010" ; CODE<="0001";HIGH <='1';--1410;
WHEN "1001" => Tone<="10111001000" ; CODE<="0010";HIGH <='1';--1480;
WHEN "1010" => Tone<="11000000110" ; CODE<="0011";HIGH <='1';--1542;
WHEN "1100" => Tone<="11001010110" ; CODE<="0101";HIGH <='1';--1622;
WHEN "1101" => Tone<="11010000100" ; CODE<="0110";HIGH <='1';--1668;
WHEN "1111" => Tone<="11011000000" ; CODE<="0001";HIGH <='1';--1728;
WHEN OTHERS => NULL;
接下页
KX
康芯科技END CASE;
END PROCESS;
END;
【 例 8-33】
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY NoteTabs IS
PORT ( clk,IN STD_LOGIC;
ToneIndex,OUT STD_LOGIC_VECTOR (3 DOWNTO 0) );
END;
ARCHITECTURE one OF NoteTabs IS 接下页
KX
康芯科技COMPONENTMUSIC --音符数据 ROM
PORT(address,IN STD_LOGIC_VECTOR (7 DOWNTO 0);
inclock,IN STD_LOGIC ;
q,OUT STD_LOGIC_VECTOR (3 DOWNTO 0));
END COMPONENT;
SIGNAL Counter,STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
CNT8,PROCESS(clk)
BEGIN
IF Counter=138 THEN Counter <= "00000000";
ELSIF (clk'EVENT AND clk = '1') THEN Counter <= Counter+1; END IF;
END PROCESS;
u1,MUSIC PORT MAP(address=>Counter,q=>ToneIndex,inclock=>clk);
END;
KX
康芯科技【 例 8-34】
WIDTH= 4 ; --“梁祝,乐曲演奏数据
DEPTH= 256 ;
ADDRESS_RADIX = DEC ;
DATA_RADIX = DEC ;
CONTENT BEGIN --注意实用文件中要展开以下数据,每一组占一行
00,3 ; 01,3 ; 02,3 ; 03,3; 04,5; 05,5; 06,5;07,6; 08,8; 09,8;
10,8 ; 11,9 ; 12,6 ; 13,8; 14,5; 15,5; 16,12;17,12;18,12; 19:15;
20:13 ; 21:12 ; 22:10 ; 23:12; 24,9; 25,9; 26,9; 27,9; 28,9; 29,9;
30,9 ; 31,0 ; 32,9 ; 33,9; 34,9; 35:10; 36,7; 37,7; 38,6; 39,6;
40,5 ; 41,5 ; 42,5 ; 43,6; 44,8; 45,8; 46,9; 47,9; 48,3; 49,3;
50,8 ; 51,8 ; 52,6 ; 53,5; 54,6; 55,8; 56,5; 57,5; 58,5; 59,5;
60,5 ; 61,5 ; 62,5 ; 63,5; 64:10; 65:10; 66:10; 67:12; 68,7; 69,7;
70,9 ; 71,9 ; 72,6 ; 73,8; 74,5; 75,5; 76,5; 77,5; 78,5; 79,5;
80,3 ; 81,5 ; 82,3 ; 83,3; 84,5; 85,6; 86,7; 87,9; 88,6; 89,6;
90,6 ; 91,6 ; 92,6 ; 93,6; 94,5; 95,6; 96,8; 97,8; 98,8; 99,9;
100:12 ;101:12 ;102:12 ;103:10;104,9;105,9;106:10;107:9;108,8;109,8;
110:6 ;111,5 ;112,3 ;113,3;114,3;115,3;116,8;117,8;118,8;119,8;
120:6 ;121,8 ;122,6 ;123,5;124,3;125,5;126,6;127,8;128,5;129,5;
130:5 ;131,5 ;132,5 ;133,5;134,5;135,5;136,0;137,0;138,0;
END ;
KX
康芯科技实 验 与 设 计
8-3 乒乓球游戏电路设计以下 8个 VHDL文件是一个乒乓球游戏电路的完整设计 。 其中,模块 tennis是顶层设计,在 MAX+PLUSII中可设其为工程文件; ball是模拟乒乓球行进路径的发光管亮灯控制模块
,在游戏中,以一排发光管交替发光指示乒乓球的行进路径,
其行进的速度可由输入的时钟信号 clk控制; board是乒乓板接球控制模块,即当发光管亮到最后一个的瞬间,若检测到对应的表示球拍的键的信号,立即将,球,反向运行,如果此瞬间没有接到键信号,将给出出错鸣叫,同时为对方记 1分,并将记分显示出来; cou4和 cou10分别是失球计数器的高低位计数模块; mway是乒乓球行进方向控制模块,主要由发球键控制; sound是失球提示发声模块 。 实验要求如下:
KX
康芯科技实 验 与 设 计
(1) 实验内容 1,根据给出的各模块的 VHDL描述,完成全部设计,包括编辑,编译,综合和仿真操作等,给出仿真波形和完整电路的原理图框图,并就各模块的功能作出详细说明 。
顶层设计例 8-35的各端口功能 ( 选择电路结构图 NO.3),bain和 bbin分别为左右球拍控制信号可分别由键 8和键 1控制; clr是清 0控制,可由键 7控制; clk是乒乓球的行进速度时钟 ( 即发光管的亮灯传递速度 ),可接 clock2
,4Hz; souclk失球提示发声时钟,可接 clock5,1024Hz; ballout[7..0]指示球路行进情况,可用 8个发光管担任,即发光管 D1,D2,..,D8担任;
countbh[3..0]和 countbl[3..0]可接数码管 7和 6,分别指示左边球手的得分的高位和低位; countah[3..0]和 countal[3..0] 可接数码管 3和 2,分别指示右边球手的得分的高位和低位; lamp接数码管 7的一个段,指示 clock2速度;
speaker接蜂鸣器,指示失球提示 。
KX
康芯科技实 验 与 设 计
(2) 实验内容 2,硬件测试 。 操作步骤:选电路模式 NO.3
( 用琴键方式 ) ; clock5接 1024Hz,为失球提示提供声响频率; clock1接 4Hz,乒乓球行进提供时钟信号;选手甲的模拟球拍是键 8,选手乙的模拟球拍是键 1,可由一方先发球
( 按键 ) ;双方失球分数分别显示于数码管 3/2和数码管 7/6

(3) 实验内容 3,完善以上设计,使之更符合乒乓球运动的各项规则 。
乒乓球游戏电路的完整设计的 VHDL描述如下,
KX
康芯科技【 例 8-35】
LIBRARY IEEE; --乒乓球游戏顶层文件
use ieee.std_logic_1164.all;
entity TENNIS is
port(bain,bbin,clr,clk,souclk:in std_logic;
ballout:out std_logic_vector(7 downto 0);
countah,countal,countbh,countbl:out std_logic_vector(3 downto 0);
lamp,speaker:out std_logic);
end;
architecture ful of TENNIS is
component sound
port (clk,sig,en:in std_logic;
sout:out std_logic);
end component;
component ballctrl 接下页
KX
康芯科技port(clr,bain,bbin,serclka,serclkb,clk:in std_logic;
bdout,serve,serclk,ballclr,ballen:out std_logic);
end component;
component ball
port(clk,clr,way,en:instd_logic;
ballout:out std_logic_vector(7 downto 0));
end component;
component board
port (ball,net,bclk,serve:in std_logic;
couclk,serclk:out std_logic);
end component;
component cou10
port(clk,clr:in std_logic;
cout:out std_logic;
qout:out std_logic_vector(3 downto 0)); 接下页
KX
康芯科技end component;
component cou4
port(clk,clr:in std_logic;
cout:out std_logic;
qout:out std_logic_vector(3 downto 0));
end component;
component mway
port(servea,serveb:in std_logic;
way:out std_logic);
end component;
signal net,couclkah,couclkal,couclkbh,couclkbl,cah,cbh:std_logic;
signal serve,serclka,serclkb,serclk,ballclr,bdout,way,ballen:std_logic;
signal bbll:std_logic_vector( 7 downto 0);
begin
net<=bbll(4); ballout<=bbll; lamp<=clk; 接下页
KX
康芯科技
uah:cou4 port map (couclkah,clr,cah,countah);
ual:cou10port map (couclkal,clr,couclkah,countal);
ubh:cou4 port map (couclkbh,clr,cbh,countbh);
ubl:cou10port map (couclkbl,clr,couclkbh,countbl);
ubda:board port map (bbll(0),net,bain,serve,couclkal,serclka);
ubdb:board port map (bbll(7),net,bbin,serve,couclkbl,serclkb);
ucpu:ballctrl port map
(clr,bain,bbin,serclka,serclkb,clk,bdout,serve,serclk,ballclr,ballen);
uway:mway port map (serclka,serclkb,way);
uball,ball port map (clk,ballclr,way,ballen,bbll);
usound:sound port map(souclk,ballen,bdout,speaker);
end;
KX
康芯科技
【 例 8-36】
library ieee;
use ieee.std_logic_1164.all;
entity sound is
port (clk:in std_logic;--发声时钟
sig:in std_logic;--正确接球信号
en:in std_logic;--球拍接球脉冲
sout:out std_logic);--提示声输出,接小喇叭
end sound;
architecture ful of sound is
begin
sout<=clk and (not sig) and en;--球拍接球,没接到时
,发提示声
end;
KX
康芯科技
【 例 8-37】
library ieee; --总控制模块
use ieee.std_logic_1164.all;
entity ballctrl is
port(clr:in std_logic;--系统复位
bain:in std_logic;--左球拍
bbin:in std_logic;--右球拍
serclka:in std_logic;--左拍准确接球或发球
serclkb:in std_logic;--右拍准确接球或发球
clk:in std_logic;--乒乓球灯移动时钟
bdout:out std_logic;--球拍接球脉冲
serve:out std_logic;--发球状态信号
serclk:out std_logic;--球拍正确接球信号
ballclr:out std_logic;--乒乓球灯清零信号
ballen:out std_logic);--乒乓球灯使能 接下页
KX
康芯科技
end ballctrl;
architecture ful of ballctrl is
signal bd:std_logic;
signal ser:std_logic;
begin
bd<=bain or bbin;
ser<=serclka or serclkb; serclk<=ser;--球拍正确接球信号
bdout<=bd;--球拍接球脉冲
process(clr,clk,bd)
begin
if(clr='1' ) then --系统复位
serve<='1'; --系统处在发球状态
ballclr<='1'; --乒乓球灯清零
else --系统正常 接下页
KX
康芯科技
if(bd='1')then --球拍发球或接球时
ballclr<='1'; --乒乓球灯清零
if(ser='1') then--球拍发球或准确接球
ballen<='1';--乒乓球灯使能允许
serve<='0'; --系统处在接球状态
else ballen<='0';
serve<='1'; --系统处在发球状态
end if;
else ballclr<='0';--没发球或接球时乒乓球灯不清零
end if;
end if;
end process;
end; 接下页
KX
康芯科技
【 例 8-38】 --乒乓球灯模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ball is
port(clk:in std_logic;--乒乓球灯前进时钟
clr:in std_logic;--乒乓球灯清零
way:in std_logic;--乒乓球灯前进方向
en:in std_logic;--乒乓球灯使能
ballout:out std_logic_vector(7 downto 0));--乒乓球灯
end ball;
architecture ful of ball is
signal lamp:std_logic_vector(9 downto 0);
begin 接下页
KX
康芯科技
process(clk,clr,en)
begin
if(clr='1') then lamp<="1000000001"; --清零
elsif en='0' then
elsif (clk'event and clk='1') then--使能允许,乒乓球灯前进时钟上升沿
if(way='1') then lamp(9 downto 1)<=lamp(8 downto 0);lamp(0)<='0';--乒乓球灯右移
else lamp(8 downto 0)<=lamp(9 downto 1); lamp(9)<='0';--乒乓球灯左移
end if;
end if;
ballout<=lamp(8 downto 1);
end process;
end;
KX
康芯科技
【 例 8-39】 --乒乓拍模块
library ieee;
use ieee.std_logic_1164.all;
entity board is
port (ball:in std_logic;--接球点,也就是乒乓球灯的末端
net:in std_logic;--乒乓球灯的中点,乒乓球过中点时,counclk、
serclk复位
bclk:in std_logic;--球拍接球信号
serve:in std_logic;--发球信号
couclk:out std_logic;
serclk:out std_logic);end board;
architecture ful of board is
begin
process(bclk,net)
begin
接下页
KX
康芯科技
if(net='1')then serclk<='0'; couclk<='0'; --乒乓球过中点时,counclk,serclk
复位
elsif(bclk'event and bclk='1')then --球拍接球时
if(serve='1')then serclk<='1'; --系统处于发球状态时 --发球成功
else --系统处于接球状态
if(ball='1') then serclk<='1';--乒乓球刚落在接球点上,接球成功
else serclk<='0'; couclk<='1'; end if;
end if;
end if;
end process;
end;
KX
康芯科技
【 例 8-40】 --十进制计数器用来做失球低位计数
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cou10 is
port(clk,clr:in std_logic;
cout:out std_logic;
qout:out std_logic_vector(3 downto 0));
end cou10;
architecture ful of cou10 is
signal qqout:std_logic_vector(3 downto 0);
begin
process(clr,clk)
begin 接下页
KX
康芯科技
if(clr='1') then qqout<="0000"; cout<='0';
elsif(clk'event and clk='1') then
if(qqout>"1000")THEN qqout<="0000"; cout<='1';
else qqout<=qqout+'1'; cout<='0'; end if;
end if;
qout<=qqout;
end process;
end;
KX
康芯科技
【 例 8-41】 --四进制计数器用来做失球高位计数
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cou4 is
port(clk,clr:in std_logic;
cout:out std_logic;
qout:out std_logic_vector(3 downto 0));
end cou4;
architecture ful of cou4 is
signal qqout:std_logic_vector(3 downto 0);
begin
process(clr,clk)
begin 接下页
KX
康芯科技
if(clr='1') then qqout<="0000"; cout<='0';
elsif(clk'event and clk='1') then
if(qqout>"0010")THEN qqout<="0000"; cout<='1';
else qqout<=qqout+'1'; cout<='0'; end if;
end if;
qout<=qqout;
end process;
end;
KX
康芯科技【 例 8-42】 --乒乓球前进方向产生模块
library ieee;
use ieee.std_logic_1164.all;
entity mway is
port(servea:in std_logic;--左选手发球信号
serveb:in std_logic;--右选手发球信号
way:out std_logic);--乒乓球灯前进方向信号
end mway;
architecture ful of mway is
begin
process(servea,serveb)
begin
if(servea='1') then way<='1';--左选手发球方向向右
elsif(serveb='1') then way<='0';--右选手发球方向向左
end if;
end process;
end;