MAXPLUS软件的使用(第3章 第5节)

更新时间:2024-05-27 09:04:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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

VARIABLE

ss : MACHINE

OF BITS (q1, q2, q3) WITH STATES (

s1 = B\s2 = B\s3 = B\

该例的意思是:

状态机的名字是ss,状态位q1, q2, 和 q3是该机寄存器的输出,状态机的状态是s1,s2,和s3, 并给出了当前状态值。

(9)逻辑段

在逻辑段中,说明设计文件的逻辑操作。 1) 布尔方程

逻辑段中布尔方程用于表达节点之间的逻辑关系,该关系必须遵从逻辑规则。 例:

a[] = ((c[] & -B\

表达式的左边可以是一个字符变量、端口和组,右边是布尔方程表达式。 2) 布尔控制方程

该控制方程用于建立状态机的时钟、复位和时钟使能信号,见下例: ss.clk = clk1; ss.reset = a & b; ss.ena = clk1ena;

该控制方程的格式为<状态机名>.<端口名>,所以该例中状态机名是ss,三个端口:时钟、复位和使能。 3)CASE语句 例: CASE f[].q IS

WHEN H\

addr[] = 0; s = a & b;

count[].d = count[].q + 1; f[3..0].d = addr[4..1];

119

WHEN H\

WHEN H\

WHEN OTHERS =>

f[].d = f[].q;

END CASE; 3) 缺省叙述语句

该语句指定真值表中变量的缺省值, 例: BEGIN

DEFAULTS

a = VCC; END DEFAULTS; IF y & z THEN

a = GND; END IF;

END;

4)IF THEN语句 例:

IF a[] == b[] THEN

c[8..1] = H \addr[3..1] = f[3..1].q; f[].d = addr[] + 1; f[].d = addr[]; d = VCC;

ELSIF g3 $ g4 THEN ELSE END IF;

4)FOR GENERATE 语句 例:

CONSTANT NUM_OF_ADDERS = 8; SUBDESIGN 4gentst ( )

VARIABLE

a[NUM_OF_ADDERS..1], b[NUM_OF_ADDERS..1], cin : INPUT; c[NUM_OF_ADDERS..1], cout

: OUTPUT;

carry_out[(NUM_OF_ADDERS+1)..1] : NODE;

120

BEGIN

carry_out[1] = cin;

FOR i IN 1 TO NUM_OF_ADDERS GENERATE

c[i] = a[i] $ b[i] $ carry_out[i];

% Full Adder %

carry_out[i+1] = a[i] & b[i] # carry_out[i] & (a[i] $ b[i]);

END GENERATE;

cout = carry_out[NUM_OF_ADDERS+1];

END;

5) 真值表语句

该语句用于指定组合逻辑和状态机的输入和输出行为。 例: TABLE

0, 0, 1,

B\ B\ B\B\

=> =>

=> =>

B\B\B\B\

1; 0; 0; 1;

a0, f[4..1].q => f[4..1].d, control;

X,

END TABLE;

该例中,a0和f[4..1].q 是输入,f[4..1].d和control是输出, 3.5.2

(1) AHDL中的保留关键字

AHDL语言建议用大写字母书写如下关键字: AND

FUNCTION OUTPUT

REPORT

RETURNS SEVERITY

ASSERT GENERATE PARAMETERS BEGIN GND BIDIR BITS CASE

HELP_ID

AHDL中的语言元素

IF SEGMENTS INPUT STATES

LOG2

TABLE

THEN

121

BURIED INCLUDE

CLIQUE IS SUBDESIGN CONNECTED_PINS

CONSTANT MACHINE

DEFAULTS MOD DESIGN NODE DEVICE NOR DIV NOT ELSE ELSIF END

(2) 保留识别符

AHDL中的保留识别符:

VCC

TITLE

TRI_STATE_NODE VARIABLE

DEFINE NAND TO

OF WHEN OPTIONS

WITH

OR XNOR

OTHERS XOR

FOR

CARRY JKFFE SRFFE CASCADE CEIL DFFE

JKFF

SRFF

LATCH TFFE LCELL TFF

USED WIRE

DFF M CELL TRI EXP MEMORY FLOOR OPENDRN GLOBAL

(3) AHDL中运算符

符号 + - == ! != > >= < <= & !& $ !$ # !#

SOFT X

功能 加号 减 数和串相等 NOT 不等于 大于 大于等于 小于 小于等于 AND NAND XOR XNOR OR BOR 122

(4)AHDL中的组

具有相同类型的端口可以形成一个组,该组可以有256个成员“BIT”, 如下的组虽然表达方式不同,但实际是同一个组。 b[5..0]

(b5, b4, b3, b2, b1, b0) b[]

(5)AHDL中的数

二进制例: B\ 八进制例: Q\ 十六进制例:H\

(6)AHDL中的算数表达式

运算符 + - ! ^ MOD DIV * LOG2 + - == == != > >= < <= & AND !& NAND $ XOR !$ ) XNOR

说明 (unary)+1 positive (unary)-1 negative !a NOT a ^ 2 exponent 4 MOD 2 modulus 4 DIV 2 division a * 2 multiplication LOG2(4-3) logarithm base2 1+1 addition 1-1 subtraction (numeric) 5 == 5 numeric equality (string) \ string equality 5 != 4 not equal to 5 > 4 greater than 5 >= 5 greater than or equal to a < b+2 less than a <= b+2 less than or equal to a & b AND a AND b 1 !& 0 NAND (AND inverter) 1 NAND 0 1 $ 1 XOR (exclusive OR) 1 XOR 1 1 !$ 1 XNOR (exclusive NOR 1 XNOR 1 123

优先级别 1 1 1 1 2 2 2 2 3 3 4 4 4 4 4 4 4 5 5 6 6

# OR !# NOR ?

a # b OR a OR b a !# b NOR (OR inverter) a NOR b (5<4) ? 3:4 ternary 7 7 8 (7)巨功能模块(LPM功能) Mega功能模块列表: 门类:

lpm_and lpm_inv lpm_bustri lpm_clshift

lpm_mux lpm_or

lpm_constant lpm_xor lpm_decode mux busmux 运算类:

lpm_abs lpm_counter lpm_add_sub lpm_mult lpm_compare 存储类: csfifo lpm_ff

lpm_ram_dq lpm_rom

csdpram lpm_ram_io

lpm_latch lpm_dff (for backward compatibility only) lpm_shiftreg lpm_tff (for backward compatibility only) 其它类: clklock pll ntsc 核心类: a16450 a8255 a6402 fft a6850 rgb2ycrcb a8237 a8251

具体的功能块输入输出信号见Max+plusⅡ软件帮助。

124

ycrcb2rgb

(8)老逻辑功能块(Old-Style Macrofunctions)和宏功能块(Macrofunction) 分类列表:

功能模块 Adders Latches Arithmetic Logic Units Multipliers Buffers Multiplexers Comparators Parity Generators/Checkers Converters Rate Multipliers Counters Registers Decoders Shift Registers Digital Filters Storage Registers EDAC SSI Functions Encoders True/Complement I/O Elements Frequency Dividers

具体的功能块输入输出信号见Max+plusⅡ软件帮助。

(9)基本逻辑功能块(Primitives) 缓冲器类:

CARRY OPNDRN CASCADE SOFT EXP TRI GLOBAL (SCLK) WIRE (GDFs only) LCELL (MCELL)

触发器和琐存器类:

DFF SRFF DFFE SRFFE JKFF

125

TFF JKFFE TFFE LATCH

输入输出端口类:

BIDIR INOUT INPUT IN OUTPUT OUT BIDIRC (GDFs only) INPUTC (GDFs only) OUTPUTC (GDFs only) 逻辑类:

AND NOR NOT OR XNOR XOR NAND VCC (GDFs only) BAND (GDFs only) BNAND (GDFs only) BNOR (GDFs only) BOR (GDFs only) GND (GDFs only)

具体的功能块的功能和输入输出信号见Max+plusⅡ软件帮助。 3.5.3

(1)使用AHDL中的数 例1:

SUBDESIGN decode1 (

address[15..0] : INPUT; chip_enable : OUTPUT; )

126

AHDL的使用例子

BEGIN

chip_enable = (address[15..0] == H\END;

在该例中当地址为十六进制数370时,输出端“chip_enable”输出高电平。

(2)常数和定义函数功能的使用 例1:常数使用例。

CONSTANT IO_ADDRESS = H\常数% SUBDESIGN decode2 (

a[15..0] : INPUT; ce : OUTPUT; ) BEGIN

ce = (a[15..0] == IO_ADDRESS); END;

例2:定义函数使用例。 PARAMETERS (WIDTH);

DEFINE MAX(a,b) = (a > b) ? a : b; %使用定义功能定义的函数,该函数保证端口位数的数量%

SUBDESIGN minport (

dataA[MAX(WIDTH,0)..0] : INPUT; dataB[MAX(WIDTH,0)..0] : OUTPUT; ) BEGIN

dataB[] = dataA[]; END;

(3)布尔表达式的使用 例1:

SUBDESIGN boole1 (

a0, a1, b : INPUT; out1, out2 : OUTPUT;

127

) BEGIN

out1 = a1 & !a0; out2 = out1 # b; END;

例2:具有一个声明的节点 SUBDESIGN boole2 (

a0, a1, b : INPUT; out : OUTPUT; )

VARIABLE

a_equals_2 : NODE; %被声明的节点% BEGIN

a_equals_2 = a1 & !a0; out = a_equals_2 # b; END;

例3:具有组的例。

OPTIONS BIT0 = MSB; %指定BIT0是MSB%

CONSTANT MAX_WIDTH = 1+2+3-3-1; % 声明常数MAX_WIDTH = 2 % SUBDESIGN group1 (

a[1..2], use_exp_in[1+2-2..MAX_WIDTH] : INPUT; d[1..2], use_exp_out[1+2*2-4..MAX_WIDTH] : OUTPUT; dual_range[5..4][3..2] : OUTPUT; ) BEGIN

d[] = a[] + B\

use_exp_out[] = use_exp_in[]; dual_range[][] = VCC; END;

例4:具有条件语句的例。 SUBDESIGN priority (

low, middle, high : INPUT;

128

highest_level[1..0] : OUTPUT; ) BEGIN

IF high THEN highest_level[] = 3; ELSIF middle THEN highest_level[] = 2; ELSIF low THEN highest_level[] = 1; ELSE

highest_level[] = 0; END IF; END;

在本例中,high信号具有最高优先权,若三个信号high,middle和low都被VCC驱动,则只有high信号起作用,输出highest_level[] = 3。 例5:有CASE的语句的例。 SUBDESIGN decoder ( ) BEGIN

CASE code[] IS

WHEN 0 => out[] = B\WHEN 1 => out[] = B\WHEN 2 => out[] = B\WHEN 3 => out[] = B\code[1..0]

: INPUT;

out[3..0] : OUTPUT;

END CASE;

END;

例6:7段显示译码器例 7段显示器的笔划顺序 % -a- % % f| |b % % -g- % % e| |c %

129

% -d- % 该显示器可以显示如下数字和字母: % 0 1 2 3 4 5 6 7 8 9 A b C d E F % 7段译码器程序: SUBDESIGN 7segment (

i[3..0] : INPUT; a, b, c, d, e, f, g : OUTPUT; ) BEGIN TABLE

i[3..0] => a, b, c, d, e, f, g;

H\ => 1, 1, 1, 1, 1, 1, 0; H\ => 0, 1, 1, 0, 0, 0, 0; H\ => 1, 1, 0, 1, 1, 0, 1; H\ => 1, 1, 1, 1, 0, 0, 1; H\ => 0, 1, 1, 0, 0, 1, 1; H\ => 1, 0, 1, 1, 0, 1, 1; H\ => 1, 0, 1, 1, 1, 1, 1; H\ => 1, 1, 1, 0, 0, 0, 0; H\ => 1, 1, 1, 1, 1, 1, 1; H\ => 1, 1, 1, 1, 0, 1, 1; H\ => 1, 1, 1, 0, 1, 1, 1; H\ => 0, 0, 1, 1, 1, 1, 1; H\ => 1, 0, 0, 1, 1, 1, 0; H\ => 0, 1, 1, 1, 1, 0, 1; H\ => 1, 0, 0, 1, 1, 1, 1; H\ => 1, 0, 0, 0, 1, 1, 1; END TABLE; END;

例7:地址译码器例。 SUBDESIGN decode3 (

addr[15..0], m/io : INPUT;

130

rom, ram, print, sp[2..1] : OUTPUT; ) BEGIN TABLE

m/io, addr[15..0] => rom, ram, print, sp[]; 1, B\ => 1, 0, 0, B\ 1, B\ => 0, 1, 0, B\ 0, B\ => 0, 0, 1, B\ 0, B\ => 0, 0, 0, B\ 0, B\ => 0, 0, 0, B\

END TABLE; END;

例8:使用lpm译码功能译码

该译码器功能:

Enable data[LPM_WIDTH1..0] eq[LPM_DECODES-1..0] 0 X 0000...00 1 LPM_DECODES 1 1000...00 1 L _DECODES PM 2 0100...00 … … … 1 1 0000...10 1 0 0000...01

该函数的AHDL说明:

FUNCTION lpm_decode (data[LPM_WIDTH-1..0], enable, clock, aclr) WITH (LPM_WIDTH, LPM_DECODES, LPM_PIPELINE) RETURNS (eq[LPM_DECODES-1..0]); 在此例中不需要enable,clock和acir端口。 该译码器源文件:

INCLUDE \SUBDESIGN decode4 (

address[15..0] : INPUT; chip_enable : OUTPUT; ) BEGIN

chip_enable = lpm_decode(data[]=address[])

131

WITH (LPM_WIDTH=16, LPM_DECODES=2^10)

RETURNS (.eq[H\返回地址为H\位置的码% END;

(4) 变量缺省值的使用 例1:

SUBDESIGN default1 (

i[3..0] : INPUT; ascii_code[7..0] : OUTPUT; ) BEGIN DEFAULTS

ascii_code[] = B\问号的ASCII码 % END DEFAULTS; TABLE

i[3..0] => ascii_code[];

B\ B\ B\ B\ END TABLE; END;

在该例中若没有译码输出时,输出问号。 例2:

SUBDESIGN default2 (

a, b, c : INPUT; select_a, select_b, select_c : INPUT; wire_or, wire_and : OUTPUT; ) BEGIN DEFAULTS wire_or = GND; wire_and = VCC;

132

END DEFAULTS;

IF select_a THEN wire_or = a; wire_and = a; END IF;

IF select_b THEN wire_or = b; wire_and = b; END IF;

IF select_c THEN wire_or = c; wire_and = c; END IF; END;

(5) 低电平激活信号 例1:

SUBDESIGN daisy ( /local_request : INPUT; /local_grant : OUTPUT; /request_in

: INPUT;

/request_out : OUTPUT;

/grant_in : INPUT; /grant_out

: OUTPUT; ) BEGIN DEFAULTS /local_grant = VCC; /request_out = VCC;

/grant_out

= VCC;

END DEFAULTS;

133

IF /request_in == GND # /local_request == GND THEN /request_out = GND;

END IF;

IF /grant_in == GND THEN IF /local_request == GND THEN /local_grant = GND; ELSIF /request_in == GND THEN

/grant_out = GND;

END IF;

END IF;

END;

(4) 时序逻辑

例1:定义D触发器的输入输出信号。 SUBDESIGN bur_reg (

clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT; )

VARIABLE

ff[7..0] : DFFE; BEGIN ff[].clk = clk; ff[].ena = load; ff[].d = d[]; q[] = ff[].q; END;

该例中分别定义7个D触发器的信号

例2:调用巨功能模块 INCLUDE \SUBDESIGN lpm_reg (

clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT;

134

) BEGIN

q[] = lpm_dff (.clock=clk, .enable=load, .data[]=d[]) WITH (LPM_WIDTH=8) RETURNS (.q[]); END;

例3:在变量段声明寄存器的输出。 SUBDESIGN reg_out (

clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT; )

VARIABLE

q[7..0] : DFFE; % outputs also declared as registers % BEGIN q[].clk = clk; q[].ena = load; q[] = d[]; END;

例4:16位计数器例 SUBDESIGN ahdlcnt (

clk, load, ena, clr, d[15..0] : INPUT; q[15..0] : OUTPUT; )

VARIABLE

count[15..0] : DFF; BEGIN

count[].clk = clk;

count[].clrn = !clr; %清零% IF load THEN

count[].d = d[]; %置数% ELSIF ena THEN

count[].d = count[].q + 1; %计数%

135

ELSE

count[].d = count[].q; %保持% END IF; q[] = count[]; END;

例5:具有D触发器功能的状态机 SUBDESIGN simple (

clk, reset, d : INPUT; q : OUTPUT; )

VARIABLE

ss: MACHINE WITH STATES (s0, s1); BEGIN ss.clk = clk; ss.reset = reset; CASE ss IS WHEN s0 => q = GND; IF d THEN ss = s1; END IF; WHEN s1 => q = VCC; IF !d THEN ss = s0; END IF; END CASE; END;

例6:步进马达控制器 SUBDESIGN stepper (

clk, reset : INPUT;

136

ccw, cw : INPUT; phase[3..0] : OUTPUT; )

VARIABLE

ss: MACHINE OF BITS (phase[3..0]) WITH STATES ( s0 = B\ s1 = B\ s2 = B\ s3 = B\BEGIN

ss.clk = clk; ss.reset = reset; TABLE

ss, ccw, cw => ss; %--------------------------------------------------% s0, 1, x => s3; s0, x, 1 => s1; s1, 1, x => s0; s1, x, 1 => s2; s2, 1, x => s1; s2, x, 1 => s3; s3, 1, x => s2; s3, x, 1 => s0; END TABLE; END;

例7:指定一个输出BIT的状态机 SUBDESIGN moore1 (

clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; )

137

VARIABLE

% current current % % state output % ss: MACHINE OF BITS (z) WITH STATES (s0 = 0, s1 = 1, s2 = 1, s3 = 0); BEGIN

ss.clk = clk; ss.reset = reset; TABLE

% current current next % % state input state % ss, y => ss; %-------------------------------------% s0, 0 => s0; s0, 1 => s2; s1, 0 => s0; s1, 1 => s2; s2, 0 => s2; s2, 1 => s3; s3, 0 => s3; s3, 1 => s1; END TABLE; END;

例8:不声明输出状态的状态机 SUBDESIGN moore2 (

clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; )

138

VARIABLE

ss: MACHINE WITH STATES (s0, s1, s2, s3); zd: NODE; BEGIN

ss.clk = clk; ss.reset = reset;

z = DFF(zd, clk, VCC, VCC); TABLE

% current current next next % % state input state output % ss, y => ss, zd; s0, 0 => s0, 0; s0, 1 => s2, 1; s1, 0 => s0, 0; s1, 1 => s2, 1; s2, 0 => s2, 1; s2, 1 => s3, 0; s3, 0 => s3, 0; s3, 1 => s1, 1; END TABLE; END;

例9:异步状态机 SUBDESIGN mealy (

clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; )

VARIABLE

ss: MACHINE WITH STATES (s0, s1, s2, s3); BEGIN ss.clk = clk; ss.reset = reset; TABLE

139

% current current current next % % state input output state % ss, y => z, ss;

s0, 0 => 0, s0; s0, 1 => 1, s1; s1, 0 => 1, s1; s1, 1 => 0, s2; s2, 0 => 0, s2, 1 => 1, s3, 0 => 0, s3, 1 => 1, END TABLE; END;

例10:非指定状态的处理 例:

SUBDESIGN recover (

clk : INPUT; go : INPUT; ok : OUTPUT; )

VARIABLE

sequence : MACHINE OF BITS (q[2..0]) WITH STATES ( idle, one, two, three, four, illegal1, illegal2, illegal3);

s2; s3; s3; s0; 140

BEGIN

sequence.clk = clk; CASE sequence IS WHEN idle => IF go THEN sequence = one; END IF; WHEN one => sequence = two; WHEN two => sequence = three; WHEN three => sequence = four;

WHEN OTHERS => %其它状态转入idle% sequence = idle; END CASE;

ok = (sequence == four); END;

(6)基本逻辑模块/老型号宏功能模块/某些巨功能模块的使用

这些模块放在\\maxplus2\\max2lib\\mega_lpm和\\maxplus2\\max2inc子目录中,使用包括(Include)语句,可以使的这些文件在TDF文件中使用。 使用方法:

1. 在变量段声明这些模块的引用变量

2. 在逻辑段用<引用名>.<端口名>的格式使用端口

如下例子是四位计数器连接四/十六译码器,这些模块的引用在变量段的引用声明说明的。 INCLUDE \INCLUDE \SUBDESIGN macro1 (

clk : INPUT; out[15..0] : OUTPUT; )

VARIABLE counter : 4count;

141

decoder : 16dmux; BEGIN

counter.clk = clk; counter.dnup = GND;

decoder.(d,c,b,a) = counter.(qd,qc,qb,qa); out[15..0] = decoder.q[15..0]; END;

该例子中使用了ALTERA提供的宏函数4count和16dmux,它们在变量段给予了声明,使counter代表4count,decoder代表16dmux,两个函数的输入口以<引用名>.<端口名>的格式在逻辑段布尔表达式的左边,输出口以同样的方式放在右边。

这两个被引用的函数放在4count.inc和16dmux.inc文件中,定义如下: FUNCTION 4count (clk, clrn, setn, ldn, cin, dnup, d, c, b, a) RETURNS (qd, qc, qb, qa, cout); FUNCTION 16dmux (d, c, b, a) RETURNS (q[15..0]);

(7)创造宏功能和巨功能模块

创造一个AHDL能用的宏功能和巨功能模块需要如下步骤: 1)编译和仿真设计文件以保证设计的正确性 2)最好建立一个专门的子目录放设计文件 3)打开文本编辑器窗口,调入设计文件

4)选择File/Create Default Include File菜单建立TDF能使用的包括文件 5)选择File/Create Default Symbol菜单建立图形编辑器能使用的符号文件

142

本文来源:https://www.bwwdw.com/article/qig7.html

Top