3.5用AHDL语言设计数字系统
AHDL语言是ALTERA公司开发的高效、易学的硬件描述语言,在max+plus2软件中使用它比VHDL语言更有效。 3.5.1
AHDL 简介
一个AHDL逻辑设计至少必须包含一个分设计段(Subdesign Section)和一个逻辑设计段(Logic Section),
其它段和语句是可选择的,AHDL的设计文件是用Max+PlusⅡ软件的文本编辑器编写的源程序(*.tdf)
下面介绍AHDL的一些语句。 (1) 例:
CONSTANT UPPER_LIMIT = 130;
CONSTANT BAR = 1 + 2 DIV 3 + LOG2(256); CONSTANT FOO = 1;
CONSTANT FOO_PLUS_ONE = FOO + 1;
(2) 定义函数语句
该语句可以定义一个在分设计中使用函数, 例:
DEFINE MAX(a,b) = (a > b) ? a : b; SUBDESIGN (
dataa[MAX(WIDTH,0)..0]: INPUT; datab[MAX(WIDTH,0)..0]: OUTPUT; ) BEGIN
datab[] = dataa[]; END;
此例中MAX函数保证最小的数据位宽度。
(3)参数叙述语句
该语句可以声明参数化巨功能模块和宏功能模块的一个或几个参数
114
常数叙述语句
该语句可以用一个字符串代表数字、算数表达式
例:
PARAMETERS (
FILENAME = \ WIDTH, AD_WIDTH = 8,
NUMWORDS = 2^AD_WIDTH );
(4)函数描述语句
共有4种形式的逻辑函数可以供用户调用,它们是:
Megafunction—具有复杂逻辑功能的巨功能模块,放在mega_LPM库中,可以供用户调用 Primitive—一些基本逻辑功能函数,可以直接调用
Macrofunction—具有高水平的逻辑宏功能模块,共有300多种,放在max2lib子目录中 State Machine—一种具有多个状态的时序电路,可以形成符号图形,用户可以调用 以上几种逻辑功能函数都可以以逻辑函数名和符号图形的方式被调用,在AHDL源文件中调用时要首先进行声明,见如下例子。 1)参数化函数:
FUNCTION lpm_add_sub (cin, dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1..0], add_sub) WITH (LPM_WIDTH, LPM_REPRESENTATION, LPM_DIRECTION, ADDERTYPE, ONE_INPUT_IS_CONSTANT)
RETURNS (result[LPM_WIDTH-1..0], cout, overflow);
该函数名为lpm_add_sub,输入端口为 cin, dataa[LPM_WIDTH-1..0], and datab[LPM_WIDTH-1..0]; 关键字WITH后是参数表,
关键字RETURN后是输出口result[LPM_WIDTH-1..0], cout, and overflow 2)非参数化函数:
FUNCTION compare (a[3..0], b[3..0])
RETURNS (less, equal, greater);
该函数名为compare,输入端口为a3, a2, a1, a0, b3, b2, b1, and b0. 关键字RETURN后是输出口less, equal, greater 3)状态机函数:
当输入和输出是状态机时,应该按照如下例子定义函数,在返回结果语句中加MACHINE关键字
FUNCTION ss_def (clock, reset, count)
115
RETURNS (MACHINE ss_out);
(5) 最小位数选择语句
定义一组数据中的最小数位是否是MSB(most significant bit)或LSB(least significant bit) 例:
OPTIONS BIT0 = MSB;
(6)断言语句
该语句可以检验表达式、参数、数据、计算函数有效性和端口的使用情况。 例:
ASSERT (WIDTH > 0)
REPORT HELP_ID
\ERROR
INTVALUE; -- for internal Altera use only
SEVERITY
在该例中,WIDTH>0是断言条件,若此条件不满足,将显示REPORT后的内容和SEVERITY后的错误等级。
(7)分设计段
分设计段声明输入、输出和双向口 例:
SUBDESIGN top ( )
端口类型可以是:
INPUT, OUTPUT, BIDIR, MACHINE INPUT, 或 MACHINE OUTPU
其中MACHINE INPUT或MACHINE OUTPUT口不能用于TDF的顶层,在端口类型说明后可以加端口当前电平—VCC或者是GND。
(8)变量段
该段是声明和产生逻辑段中使用的变量的地方,如下是变量段的例子。 VARIABLE
foo, bar, clk1, clk2 : INPUT = VCC; a0, a1, a2, a3, a4 b[7..0]
: OUTPUT;
: BIDIR;
a, b, c : NODE;
116
temp : halfadd;
ts_node : TRI_STATE_NODE;
IF DEVICE_FAMILY == \TE
8kadder : flex_adder; d,e
: NODE;
ELSE GENERATE
7kadder : pterm_adder; f,g
: NODE;
END GENERATE;
1)函数变量声明例: VARIABLE
comp : compare;
adder : lpm_add_sub WITH (LPM_WIDTH = 8);
该变量段声明comp为函数compare的引用变量,声明adder为函数lpm_add_sub的引用变量,一旦声明完毕,就意味着: 变量comp就是如下端口的代表: a[3..0], b[3..0]
: INPUT;
-- inputs to compare
less, equal, greater : OUTPUT; -- outputs of compare 而变量adder是如下端口的代表: a[8..1], b[8..1] sum[8..1]
: INPUT;
-- inputs of adder
-- outputs of adder
: OUTPUT;
也就是如下的引用变量可以使用在当前的设计文件中: comp.a[], comp.b[], comp.less, comp.equal, comp.greater adder.dataa[], adder.datab[], adder.result[] 2)节点变量声明
AHDL 软件支持两种节点形式:NODE and TRI_STATE_NODE。 例:
SUBDESIGN node_ex ( )
VARIABLE
a, oe : INPUT; b c
: OUTPUT; : BIDIR;
b : NODE;
117
t : TRI_STATE_NODE; b = a;
BEGIN
out = b % therefore out = a % t = TRI(a, oe); t = c;
% t is bus of c and tri_stated a %
END;
如下的端口和功能模块能连接三态节点(TRI_STATE_NODE): TRI 三态功能模块
输入端口(INPUT) 端口从高层向下
输出或双向口(OUTPUT, BIDIR)从低层向上 当前文件中的双向口(BIDIR)
当前文件中的三态节点TRI_STATE_NODE
3)寄存器变量声明 该声明用于声明寄存器: D型:DFF,DFFE, T型:TFF,TFFE
JK型:JKFF,JKFFE,SRFF,SRFFE 琐存器:LATCH 例:
VARIABLE ff : TFF;
该变量一旦声明完毕,就可以使用如下变量: ff.t, ff.clk,ff.clrn,ff.prn,ff.q
对于只有一个输出的功能模块,可以简化使用。 DFF的功能说明为:
FUNCTION DFF(d, clk, clrn, prn) RETURNS (q);. 则对于如下的变量段,逻辑段的意思是a.d = b.q; VARIABLE
a, b : DFF; a = b; BEGIN END;
4)状态机变量声明 例:
118