EDA技术基础 CPLD技术及其应用.

Slides:



Advertisements
Similar presentations
什么是SOPC: SOPC是英文System On a Programmable Chip的缩写,称为片上可编程系统。SOPC将传统的EDA技术、计算机系统、嵌入式系统、数字信号处理等融为一体,综合了各自的优势,且在结构上形成一块芯片。 为什么用SOPC:SOPC是现代电子技术和电子系统设计的发展趋势,建立了电子系统设计的新模式。用户利用SOPC开发平台,自行设计高速、高性能的DSP处理器、特定功能的CPU及其外围接口电路,创建结构最为简洁的电子系统。
Advertisements

TMS320F2812串行外设接口 Serial Peripheral Interface (SPI)
第2章 SOPC硬件开发环境及流程.
第2章 FPGA/CPLD结构与应用.
第4章 VHDL设计初步.
Chapter 5 Sequential Logic Circuit
第八章 可编程逻辑器件 本章的重点: 本章的难点: 1.PLD的基本特征,分类以及每种类型的特点;
Combinational Logic 組合邏輯
加速度計 指導老師 : 洪正瑞 製作人 : 蔡昌佑.
CH1 Number Systems and Conversion
电工电子实验中心.
AKA Embedded 开放实验室系列普及讲座之一 FPGA/CPLD的应用和开发简介
EPF10K10TI144-4晶片燒錄.
组合逻辑 刘鹏 Mar. 17, 2015 浙江大学 信息与电子工程系
第三章 组合逻辑电路 第一节 组合电路的分析和设计 第二节 组合逻辑电路中的竞争与冒险 第三节 超高速集成电路硬件描述语言VHDL
CH.2 Introduction to Microprocessor-Based Control
FC OB1 FB SFC 操作系统 SFB OBs 结构化编程 其它
VHDL數位電路實習與專題設計 文魁資訊-UE301
触发器和时序电路分析 刘鹏 浙江大学信息与电子工程学院 March 30, 2017 ZDMC.
第4章 处理器(CPU) 4.1 引言 4.2 逻辑设计的一般方法 4.3 建立数据通路 4.4 一个简单的实现机制 4.5 多周期实现机制.
VHDL數位電路實習與專題設計 文魁資訊-UE301
Chapter 5 Verilog 硬體描述語言
Chapter 5 Verilog硬體描述語言
结构化编程 FC OB1 FB SFC 操作系统 SFB OBs 其它
邏輯設計.
Ch01-2 Verilog語法 資料流(DataFlow)設計 行為(Behavior)設計
memory array (2n words by m bits)
二、相關知識 在數位系統中,資料的表示方式通常是以0與1這兩種基本型態組合而成的,資料若要作處理,則必須將它轉為處理單元所能接受的型式(碼),此即所謂的編碼(encode)。可以完成此編碼工作的電路稱為編碼器(encoder)。而當處理單元將資料處理完之後,則必須將它呈現出來,此時我們需要將它更改為人們所熟悉的資料型式,此種動作我們稱之為解碼(decode)。可以完成此解碼工作的電路稱為解碼器(decoder)。
VHDL 硬體描述語言 數位電路設計實務 第四章 VHDL 的語言結構.
版权所有,禁止未经授权的商业使用行为 何宾 Tel: 北京中教仪装备技术有限公司.
VHDL 硬體描述語言 數位電路設計實務 第六章 函數副程序以及套件程式庫.
EDA原理及应用 何宾
EDA原理及应用 何宾
第四章 同步时序电路的分析 二进制串行计数器 二进制同步计数器 用跳越的方法实现任
第四阶段实验 ISP器件的设计与应用 一、实验目的 二、实验内容与要求 三、ISP器件的开发流程 四、EDA Pro2K实验系统介绍
memory array (2n words by m bits)
微程序控制器 刘鹏 Dept. ISEE Zhejiang University
欢迎参加VHDL培训 VHDL培训教程 浙江大学电子信息技术研究所 电子设计自动化(EDA)培训中心
数字系统设计复习 Digital System Design Summary
微处理器设计2 刘鹏 College of ISEE Zhejiang University
   OR-CAD培训教程 欢迎参加OR-CAD培训      .
组合逻辑3 Combinational Logic
Danny Mok Altera HK FAE AHDL培训教材 Danny Mok Altera HK FAE 2018/12/9 P.1.
第15章 串行通信及接口电路.
第14章 其它DSP设计库 14.1 总线控制库 14.2 复数信号库 14.3 Gates库 14.4 状态机函数库
第3章 變數、資料型別與運算子 3-1 變數與資料型別的基礎 3-2 變數的命名與宣告 3-3 資料型別 3-4 運算式與運算子
Programmable Logic Architecture Verilog HDL FPGA Design
使用VHDL設計--Moore Machine
JTAG INTERFACE SRAM TESTER WITH C-LCM
邏輯設計 Logic Design 顧叔財, Room 9703, (037)381864,
第9章 DSP集成开发环境CCS 内容提要 CCS是TI公司推出的用于开发DSP芯片的集成开发环境,它采用Windows风格界面,集编辑、编译、链接、软件仿真、硬件调试以及实时跟踪等功能于一体,极大地方便了DSP芯片的开发与设计,是目前使用最为广泛的DSP开发软件之一。 本章对CCS开发软件的使用作了详细地介绍。首先,对CCS开发软件作了简要地说明,并介绍了该软件的安装及配置;其次,介绍了CCS的基本操作,包括:CCS的窗口和工具条、文件的编辑、反汇编窗口、存储器窗口、寄存器窗口、观察窗口
本章中將會更詳細地考慮有關重複的概念,並且會 介紹for和do…while等兩種用來控制重複的敘述 式。 也將會介紹switch多重選擇敘述式。 我們會討論直接和迅速離開某種控制敘述式的 break敘述式,以及用來跳過重複敘述式本體剩餘 部份的continue敘述式。 本章會討論用來組合控制條件的邏輯運算子,最後.
时序电路设计 刘鹏 浙江大学信息与电子工程系 Apr. 24, 2011 EE141
第12章 图像边缘检测器的设计与分析 12.1 系统设计要求 12.2 系统设计方案 12.3 主要LPM原理图和VHDL源程序
精简指令集(RISC)CPU的构造原理和设计方法
第 2 章 数字逻辑电路基础 和计算机中的逻辑部件
義守大學電機工程學系 陳慶瀚 第3章 VHDL Concurrent語法 義守大學電機工程學系 陳慶瀚
第六章 VHDL设计共享.
第五章 VHDL主要描述语句.
第一次上机安排 第六周 第七周 周一晚(提高1、2,通信001~012) 周二上(通信014~085) 周四上(通信086~154)
Speaker: Liu Yu-Jiun Date: 2009/4/29
计算机学院 数字逻辑实验的要求.
设计示例一 用门级结构描述D触发器:.
數位邏輯設計 VHDL.
第7章 VHDL设计应用实例 7.1 8位加法器的设计 7.2 分频电路 7.3 数字秒表的设计.
FPGA组合逻辑 王安然.
第六章 时序逻辑电路的分析与设计 各位老师,同学,大家好!
Programmable Logic System Design
陳慶瀚 機器智慧與自動化技術(MIAT)實驗室 國立中央大學資工系 2013年5月28日
第七章 基本逻辑电路设计.
Presentation transcript:

EDA技术基础 CPLD技术及其应用

硬件描述语言 — AHDL

什么是 AHDL Altera Hardware Description Language 由Altera公司开发 集成在Altera软件 Max+Plus II中 描述硬件用语言而不是图形 容易建立 容易修改 对以下设计非常优越 复杂的组合逻辑 BCD 到 7 段编码转换 地址译码 状态机 其他…

什么是 AHDL 续… 和图形输入一样容易 和其他硬件描述语言一样强大 如HDL (Hardware Description Language) VHDL, Verilog HDL 等

首先建立工程 Project…

怎样使用 ADHL 可使用任何文本编辑器创建文件 Altera软件 Max+Plus II 提供文本编辑器 Type in your AHDL design file 可使用任何文本编辑器创建文件 Altera软件 Max+Plus II 提供文本编辑器

创建你的 AHDL 文件 续.

两处须同名 保存 ADHL 文件名为 xxxx.TDF 续.

当前工程名

续...

AHDL设计的附加选项

打开 Max+Plus II 附加选项 有些内置的附加选项对工程师在使用AHDL 设计进程中有所帮助 选项菜单中的语法色彩选项 将这一选项 On/Off 绿色表示注释 兰为ADHL 保留字

用户可自行修改颜色选项 使用选项菜单中的调色板,自定义如下颜色: comments, illegal characters, megafunctions, macrofuncitons? 可选元素 颜色选定

编译过程中的错误定位 很容易定位错误 错误定位 双击错误信息 点击定位按钮

AHDL 模板 忘记怎么办? If-then-else case-end case loop-end loop ?????

使用 AHDL 模板

使用AHDL模板

使用AHDL模板

使用AHDL模板 修改代码

使用 Help 选项

AHDL程序规范

AHDL 程序架构 可选 必须 Subdesign Section Variable Section Logic Section Title Statement Include Statement Constant Statement Define Statement Parameters Statement Function Prototype Statement Options Statement Design Section Subdesign Section Variable Section Logic Section AHDL 可选 程序架构 必须

AHDL 书写格式 SUBDESIGN file_name ( input_pin_name : INPUT; input_bus_name[15..0] : INPUT; output_pin_name : OUTPUT; output_bus_name : OUTPUT; ) BEGIN ouptut_pin_name = input_pin_name; output_bus_name = input_bus_name; END; 关键字 定义 I/O 口 逻辑项

引 言

1、使用数字

使用数字 SUBDESIGN decode1 ( address[15..0] : INPUT; chip_enable : OUTPUT; 数字是用来定义布尔表达式、方程、算术表达式及参数中的常数值,AHDL支持十进制、二进制、八进制及十六进制数。 SUBDESIGN decode1 ( address[15..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (address[15..0] == H"0370"); END; 在此例中,十进制数15-0用来定义地址总线的比特位, 十六进制数H“0370”用来定义被译码的地址。

AHDL设计1 – 地址译码器 Graph? a0 a1 a2 a3 SUBDESIGN decode1 a4 chip_enable a0 a2 a1 a3 a4 a5 a6 a7 a9 a15 a10 a11 a12 a13 a14 a8 SUBDESIGN decode1 ( a[15..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (a[15..0] == H“370"); END;

AHDL设计1 – 地址译码器 AHDL ? SUBDESIGN decode1 a0 ( a[3..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (a[3..0] == H"7"); END; a2 a1 a0 a3 chip_enable chip_enable = a0 & a1 & a2 & !a3

相关问题 – 数字的使用 例: B"0110X1X10" Radix: Values: Decimal <series of digits 0 to 9> Binary B"<series of 0's, 1's, X's>" (where X = "don't care") Octal O"<series of digits 0 to 7>" or Q"<series of digits 0 to 7>" Hexadecimal X"<series from 0 to 9, A to F>" or H"<series from 0 to 9, A to F>" 例: B"0110X1X10" Q"4671223" H"123AECF"

为什么使用 AHDL 而不用图形 易于修改 电路由代码表示 SUBDESIGN decode1 ( a[3..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (a[3..0] == H"A"); END; Chip_enable = !a0 & a1 & !a2 & a3 a2 a1 a0 a3 chip_enable 修改费力 自动解释功能 仅改此处

更有甚者 SUBDESIGN decode1 ( a[3..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (a[3..0] == B"1x0x"); END; 有些bit位在比较时可忽略

需要了解的运算符号 Addition : + Subtraction : - Numeric Equality : == Not equal to : != Greater than : > Greater than or equal to : >= Less than : < Less than or equal to : <= Logical OR : # Logical AND : &

赋值问题 B“00001011” 而不是 B“00100011” B“001011” 而不是 B“00100011”,位数不匹配,出错。 a[7..0] = (H“2”, H“3”)------- 编译器翻译为 B“00001011” 而不是 B“00100011” a[7..0] = (B"0010", H"3") ------- 编译器翻译为 B“001011” 而不是 B“00100011”,位数不匹配,出错。 建议:用二进制写全。

2、使用常数和求值函数

使用常数 CONSTANT IO_ADDRESS = H"0370"; SUBDESIGN decode2 ( a[15..0] : INPUT; ce : OUTPUT; ) BEGIN ce = (a[15..0] == IO_ADDRESS); END;

使用常数功能 CONSTANT IO_ADDRESS = H"A"; 一处修改 SUBDESIGN decode1 定义CONSTANT在关键字SUBDESIGN之前 CONSTANT IO_ADDRESS = H"A"; SUBDESIGN decode1 ( a[3..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = (a[3..0] == IO_ADDRESS); IF(a[3..0] == IO_ADDRESS) THEN ... END; 一处修改 各处自动替换

有关常数的进一步定义 Constant example CONSTANT IO_ADDRESS = H“70” CONSTANT FOO = 1+2*3 - LOG2(256); CONSTANT FOO_PLUS_one = FOO + 1; 定义一个常数值 定义一个算法式 依靠前一定义值

以下示例定义常数 FAMILY,然后使用它在 Assert 陈述中来检查现在的器件是否是 FLEX 8000系列。 PARAMETERS ( DEVICE_FAMILY % DEVICE_FAMILY is a predefined Altera parameter % ); CONSTANT FAMILY = "FLEX8000"; SUBDESIGN strcmp a : INPUT; b : OUTPUT; ) BEGIN IF (DEVICE_FAMILY == FAMILY) GENERATE ASSERT REPORT "Detected compilation for FLEX8000 family" SEVERITY INFO; b = a; ELSE GENERATE REPORT "Detected compilation for % family" DEVICE_FAMILY SEVERITY ERROR; END GENERATE; END;

使用求值函数 使用DEFINE定义求值函数 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、一个单域组包含符号名或端口名,后随用方括弧括起的单域。例: a[4..1] 。 一旦组被定义,[]就可用来简化定义整个域。 一个单数字可用来替换一个域,例: a[5] ,此时和a5 等价。 2、一个双域组包含符号名或端口名,后随用方括弧括起的双域。例: d[6..0][2..0] 。 双于域组被用来设计两维总线结构。一旦组被定义,[][]就可用来简化定义整个域。一个单独的节点可被命名为 name[y][z] 或 name y_z 。 y和z 为数字。 3、一个序列组包含一个符号名、端口和数字的列表 ,以逗号分隔,以圆括弧括起。例: (a, b, c) 。单域和双域也可以列表用圆括弧括起或作为列表内容。例:(a、b、c[5..1]) 。 定义组示例: b[5..0] (b5, b4, b3, b2, b1, b0) b[] b[log2(256)..1+2-1] b[2^8..3 mod 1] b[2*8..8 div 2]

定义组 例:单域名组 a[4..1] 包含节点a4、a3、a2、a1。 一个组(GROUP)最多包含256个成员或BITS,当作一个节点集看待,操作时当作一个整体。一个组可定义为单域名、双域名或序列域名形式。 例:单域名组 a[4..1] 包含节点a4、a3、a2、a1。 双域名组 a[2..1][5..3] 包含节点a2_5、a2_4、a2_3、a1_5、a1_4、a1_3。 序列域名 (a、b、c)包含节点a、b、c 。 在布尔方程中,一个组可被赋予一个布尔表达式、其他组、一个单节点、VCC、GNG、1或0。在每一种情况中,组获得的值是不同的。 Options 说明可用于定义组中最低数字的比特位是MSB还是LSB。 1、一旦组被定义,[]就可用来简化定义整个域。例:a[4..1] 可被缩写为a[] ,同样, b[5..4][3..2]可简写为 b[][]。 2、为避免混淆组名,在组名中禁止使用数字尾缀。例:编译器分不清组 q1[15..0] 和 q11[15..0]。

组的定义–实例 OPTIONS 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"10"; use_exp_out[] = use_exp_in[]; dual_range[][] = VCC; END;

组使用说明: 当组被其他组赋值且大小相等时,按照排序位置一一对应。 例:d[2..0]=q[8..6]---d2-q8,d1-q7,d0-q6 当一个组被赋予一个单节点,则所有的位都接到节点上。 例:d[2..0]=n。 当一个组被接到VCC或 GND, 所有位都赋予1或0值。 例: d[2..0]=VCC。 当一个组被接到十进制1上,仅LSB位接VCC,其他接GND。 例: d[2..0]=1。 等效于d[2..0]=B”001”。 尽量不造成组不匹配情况

组操作 a0 out0 b0 功能同样更容易 a1 out1 b1 a2 out2 b2 a3 out3 b3 SUBDESIGN decode1 ( a[3..0], b[3..0] : INPUT; out[3..0] : OUTPUT; ) BEGIN out0 = a0 & b0; out1 = a1 & b1; out2 = a2 & b2; out3 = a3 & b3; END; a0 b0 out0 a1 b1 out1 a2 b2 out2 a3 b3 out3 功能同样更容易 SUBDESIGN decode1 ( a[3..0], b[3..0] : INPUT; out[3..0]: OUTPUT; ) BEGIN out1[] = a[] & b[]; END;

组操作渐进 组操作 a[9..0], b[9..0] a[] = b[]; a[7..4] = b[9..6]; a[9..8] = VCC; a[9..8] = 1; a[9..8] = 2; a[9..8] = 3; a[3..0] = GND a[3..0] = 0; temp = b0& b1; a[2..1] = temp a7=b9, a6=b8, a5=b7, a4=b6 a[9..8] connect to VCC a[9..8] = B“01” a[9..8] = B“10” a[9..8] = B“11” a[3..0] connect to GND a[3..0] = B”0000” a2 = temp, a1 = temp

组操作更进 Bus [Group] b[3..0] ARRAY BUS [Group] a[3..0][2..0] b3, b2, b1, b0 (有4个成员) MSB is b3, LSB is b0 ARRAY BUS [Group] a[3..0][2..0] a3_2, a3_1, a3_0, a2_2, a2_1, a2_0, a1_2, a1_1, a1_0, a0_2, a0_1, a0_0 (有12 个成员) MSB is a3_2, LSB is a0_) a[3..2][1..0] = b[]; 后面先改变 a3_1 = b3 a3_0 = b2 a2_1 = b1 a2_0 = b0

组合逻辑

综合布尔表达式和方程 ------陈述句

综合组合逻辑 AHDL ? Graphic SUBSDESIGN boole1 ( a0, a1, b : INPUT; a0 out1, out2 : OUTPUT; ) BEGIN out1 = a0 & !a1; out2 = out1 # b; END; a0 a1 b out1 out2 out1 = a0 & !a1 out2 = a0 & !a1 # b

定义节点

声明节点 SUBDESIGN boole2 ( a0, a1, b : INPUT; out : OUTPUT; ) a0 VARIABLE a_equals_2 : NODE; BEGIN a_equals_2 = a1 & !a0; out = a_equals_2 # b; END; a0 a1 b a_equals_2 out

声明节点 AHDL ? SUBDESIGN boole3 a0 temp ( a0, a1, b, d: INPUT; out2, out3 : OUTPUT; ) VARIABLE temp : NODE; BEGIN temp = a0 & !a1; out2 = temp # b; out3 = temp & d; END; a0 a1 b out3 out2 d temp out2 = a0 & !a1 # b out3 = a0 & !a1 & d

节点分为普通节点(关键字NODE)和三态节点(关键字TRI_STATE_NODE) 。 NODE 和 TRI_STATE_NODE 的不同在于多重分配时产生不同的结果: 对于NODE 的多重分配,是将信号线集总起来实现线与(wired-AND)或者线或(wired-OR )功能。在 Defaults 声明中昭示的变量缺省值决定其行为:缺省值为 VCC 产生 wired-AND功能;缺省值为GND 产生 wired-OR 功能。 多重分配对于TRI_STATE_NODE 意味着将信号线接于同一节点。 如果只有一个信号线接于 TRI_STATE_NODE, 该节点当着 NODE看待。

变量部分声明

变量部分声明 普通节点 实例声明 三态节点 VARIABLE a, b, c : NODE; temp : halfadd; ts_node : TRI_STATE_NODE; IF DEVICE_FAMILY == "FLEX8000" GENERATE 8kadder : flex_adder; d,e : NODE; ELSE GENERATE 7kadder : pterm_adder; f,g : NODE; END GENERATE; 普通节点 实例声明 三态节点

命名规则

引用和非引用命名 符号名是用户在AHDL中自定义的标识符,常用于TDF文件中的以下部分的命名: -内部(临时定义)和外部(输入输出端口)的节点和组 -常数 -状态机名、状态位和状态名 -实例 -参数 -存储器段 -求值函数 -指定操作 Subdesign 名是用户自定义的子设计文件名。 Subdesign 名必须和TDF文件名一致。 端口名是用来确定逻辑函数输入输出的符号名。 编译器产生的命名包含“~”符号,出现在工程的适配文件Fit File中。如果反注 Fit File 分配表,这些命名将出现在工程的ACF文件中。 “~”符号仅是编译器产生命名的保留符号,不能用于用户文档的管脚、节点和组的命名。

规则列表 例:合法的非引用型命名 a /a1 非法的非引用型命名 -foo node 55 有两种符号可以出现在subdesign, symbolic, 及 port 命名中: 引用和非引用型。引用型就是用(‘) 把字符串括起来,而非引用型则无。 例:合法的非引用型命名 a /a1 非法的非引用型命名 -foo node 55 合法的引用型命名 ‘ -bar ’ ‘ table ’ ‘ 1221 ’ 非法的引用型命名 ‘bowling4$’ ‘has a space’ ‘a_name_with_more_than_32_characters’ 规则列表 -------------------------------------------------------------------------------------------------------------------------- Legal Name Unquoted Quoted Unquoted Quoted Unquoted Quoted Characters Subdesign Subdesign Symbolic Symbolic Port Port Name Name Name Name Name Name A-Z Yes Yes Yes Yes Yes Yes a-z Yes Yes Yes Yes Yes Yes 0-9 Yes Yes Yes Yes Yes Yes Underscore (_) Yes Yes Yes Yes Yes Yes Slash (/) No No Yes Yes Yes Yes Dash (-) No Yes No Yes No Yes Digits only (0-9) Yes Yes No Yes Yes Yes Keyword No Yes No Yes No Yes Identifier No Yes No No No Yes Max. Characters 32 32 32 32 32 32

保留关键字 AND FUNCTION OUTPUT ASSERT GENERATE PARAMETERS BEGIN GND REPORT BIDIR HELP_ID RETURNS BITS IF SEGMENTS BURIED INCLUDE SEVERITY CASE INPUT STATES CLIQUE IS SUBDESIGN CONNECTED_PINS LOG2 TABLE CONSTANT MACHINE THEN DEFAULTS MOD TITLE DEFINE NAND TO DESIGN NODE TRI_STATE_NODE DEVICE NOR VARIABLE DIV NOT VCC ELSE OF WHEN ELSIF OPTIONS WITH END OR XNOR FOR OTHERS XOR

保留标示符 CARRY JKFFE SRFFE CASCADE JKFF SRFF CEIL LATCH TFFE DFFE LCELL TFF DFF MCELL TRI EXP MEMORY USED FLOOR OPENDRN WIRE GLOBAL SOFT

运算进阶 操作符/ 举例: 描述 优先级 比较符: + (unary) +1 正 1 - (unary) -1 负 1 ! !a 非 1 操作符/ 举例: 描述 优先级 比较符: + (unary) +1 正 1 - (unary) -1 负 1 ! !a 非 1 ^ a ^ 2 指数 1 MOD 4 MOD 2 取模 2 DIV 4 DIV 2 除 2 * a * 2 乘 2 LOG2 LOG2(4-3) 底2对数 2 + 1+1 加 3 - 1-1 减 3 == (numeric) 5 == 5 数字等 4 == (string) “a” == “b” 字符串等 4 运算进阶

运算进阶 操作符/ 举例: 描述 优先级 比较符: != 5 != 4 不等于 4 > 5 > 4 大于 4 操作符/ 举例: 描述 优先级 比较符: != 5 != 4 不等于 4 > 5 > 4 大于 4 >= 5 >= 5 大于等于 4 < a < b+2 小于 4 <= a <= b+2 小于等于 4 & a & b 与 5 AND a AND b !& 1 !& 0 与非 (与取反) 5 NAND 1 NAND 0 $ 1 $ 1 异或 6 XOR 1 XOR 1 !$ 1 !$ 1 异或非 6 XNOR 1 XNOR 1 # a # b 或 7 OR a OR b !# a !# b 或非 (或取反) 7 NOR a NOR b ? (5<4) ? 3:4 三变数 8 运算进阶

DEFINE---定义描述

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;

条件逻辑综合

AHDL IF描述逻辑 Graphic high Highest_level1 middle Highest_level0 low SUBDESIGN priority ( low, middle, high : INPUT; 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; Graphic Highest_level1 Highest_level0 high middle low

Case 描述 CASE f[].q IS WHEN H"00" => addr[] = 0; s = a & b; count[].d = count[].q + 1; WHEN H"02", H"03", H"04" => f[3..0].d = addr[4..1]; WHEN OTHERS => f[].d = f[].q; END CASE;

Case 描述逻辑 Graphic code0 out0 code1 out1 out2 out3 SUBDESIGN decoder ( code[1..0] : INPUT; out[3..0] : OUTPUT; ) BEGIN CASE code[] IS WHEN 0 => out[] = B"0001"; WHEN 1 => out[] = B"0010"; WHEN 2 => out[] = B"0100"; WHEN 3 => out[] = B"1000"; END CASE; END; out2 out1 out0 out3 code1 code0

If Then描述 与 Case描述

If Then 描述差异 If Then 描述1 Compiler 翻译 If Then 描述2 IF a THEN c = d; ELSIF b THEN f = e; END IF; Compiler 翻译 IF a THEN c = d; END IF; IF !a & b THEN f = e; If Then 描述2 IF a THEN c = d; END IF; IF b THEN f = e;

If Then 描述 Compiler 翻译 IF a THEN IF a THEN c = d; c = d; END IF; ELSIF b THEN IF !a & b THEN c = e; c = e; ELSE IF !a & !b THEN c = f; c = f; END IF; END IF;

If Then 描述 与 Case 描述 If Then 描述 Case 描述 CASE a[] IS IF a[] == 0 THEN WHEN 0 => y = c & d; y = c & d; ELSIF a[] == 1 THEN WHEN 1 => y = e & f; y = e & f; ELSIF a[] == 2 THEN WHEN 2 => y = g & h; y = g & h; ELSIF a[] == 3 THEN WHEN 3 => y = i; y = i; ELSE WHEN OTHERS => y = GND; y = GND; END IF; END CASE;

IF-THEN-ELSE 与 CASE比较 If-then-else 与 CASE相似 有些情况下使用任何一种都能达到同样的结果 这两个条件可能完全无关 条件必须是同样的 CASE a[] IS WHEN 0 => y=c&d; WHEN 1 => IF a[] == 0 THEN y=c&d; ELSIF b == 0 THEN z = x#y; END IF;

比较实例 SUBDESIGN decoder (low, medium, high : INPUT; highest_level[3..0] : OUTPUT; ) VARIABLE code[2..0] : NODE; BEGIN code2=high; code1=medium; code0=low; CASE code[] IS WHEN 4 => highest_level[] = B"1000"; WHEN 2 => highest_level[] = B"0100"; WHEN 1 => highest_level[] = B"0010"; WHEN OTHERS => highest_level[] = B"0001"; END CASE; END; SUBDESIGN priority ( low, middle, high : INPUT; highest_level[3..0] : OUTPUT; ) BEGIN IF high THEN highest_level[] = B“1000”; ELSIF middle THEN highest_level[] = B“0100”; ELSIF low THEN highest_level[] = B“0010”; ELSE highest_level[] = B“0001”; END IF; END;

IF-THEN-ELSE AHDL Graphic high Highest_level3 middle Highest_level2 SUBDESIGN priority ( low, middle, high : INPUT; highest_level[3..0] : OUTPUT; ) BEGIN IF high THEN highest_level[] = B“1000”; ELSIF middle THEN highest_level[] = B“0100”; ELSIF low THEN highest_level[] = B“0010”; ELSE highest_level[] = B“0001”; END IF; END; high low middle Highest_level3 Highest_level2 Highest_level1 Highest_level0

需要 4个 LCELL

进一步考察 IF-THEN-ELSE IF-THEN-ELSE 可实现按优先级编码 为什么?? 当 high=1, middle=1, low=1 ? high=0, middle=1, low=1 ? high=1, middle=1, low=0 ? high=1, middle=0, low=0 ? highest_level[] 输出是什么? high=1, middle=x, low=x high=0, middle=1, low=x high=1, middle=x, low=x high=1, middle=x, low=x high low middle Highest_level3 Highest_level2 Highest_level1 Highest_level0

Case 陈述举例 high /high medium /medium low /low Graphic? Highest_level3 high /high medium /medium low /low Highest_level2 Highest_level1 Highest_level0 Case 陈述举例 SUBDESIGN decoder (low, medium, high : INPUT; highest_level[3..0] : OUTPUT; ) VARIABLE code[2..0] : NODE; BEGIN code2=high; code1=medium; code0=low; CASE code[] IS WHEN 4 => highest_level[] = B"1000"; WHEN 2 => highest_level[] = B"0100"; WHEN 1 => highest_level[] = B"0010"; WHEN OTHERS => highest_level[] = B"0001"; END CASE; END; Graphic? 此处声明有何用

进一步考察 CASE Statement CASE 不能实现按优先级编码 为什么?? 当 highest_level[] 输出是什么? high=0, middle=1, low=1 ? high=1, middle=1, low=1 ? high=1, middle=1, low=0 ? high=1, middle=0, low=0 ? highest_level[] 输出是什么? Highest_level3 high /high medium /medium low /low Highest_level2 Highest_level1 Highest_level0

创建译码器举例 ----真值表法

创建译码器 a g d a g d a g d a g d a g d a g d a g d a g d a g d a g d a g 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"0" => 1, 1, 1, 1, 1, 1, 0; H"1" => 0, 1, 1, 0, 0, 0, 0; H"2" => 1, 1, 0, 1, 1, 0, 1; H"3" => 1, 1, 1, 1, 0, 0, 1; H"4" => 0, 1, 1, 0, 0, 1, 1; H"5" => 1, 0, 1, 1, 0, 1, 1; H"6" => 1, 0, 1, 1, 1, 1, 1; H"7" => 1, 1, 1, 0, 0, 0, 0; H"8" => 1, 1, 1, 1, 1, 1, 1; H"9" => 1, 1, 1, 1, 0, 1, 1; H"A" => 1, 1, 1, 0, 1, 1, 1; H"B" => 0, 0, 1, 1, 1, 1, 1; H"C" => 1, 0, 0, 1, 1, 1, 0; H"D" => 0, 1, 1, 1, 1, 0, 1; H"E" => 1, 0, 0, 1, 1, 1, 1; H"F" => 1, 0, 0, 0, 1, 1, 1; END TABLE; END; 创建译码器 a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e H“0" => 1, 1, 1, 1, 1, 1, 0; H“1" => 0, 1, 1, 0, 0, 0, 0; H“2" => 1, 1, 0, 1, 1, 0, 1; H“3" => 1, 1, 1, 1, 0, 0, 1; H“4" => 0, 1, 1, 0, 0, 1, 1; H“5" => 1, 0, 1, 1, 0, 1, 1; H“6" => 1, 0, 1, 1, 1, 1, 1; H“7" => 1, 1, 1, 0, 0, 0, 0; H“8" => 1, 1, 1, 1, 1, 1, 1; H“9" => 1, 1, 1, 1, 0, 1, 1; H“A" => 1, 1, 1, 0, 1, 1, 1; H“B" => 0, 0, 1, 1, 1, 1, 1; H“C" => 1, 0, 0, 1, 1, 1, 0; H“D" => 0, 1, 1, 1, 1, 0, 1; 修改很容易 H“E" => 1, 0, 0, 1, 1, 1, 1; H“F" => 1, 0, 0, 0, 1, 1, 1;

SUBDESIGN decode3 ( addr[15..0], m/io : INPUT; rom, ram, print, sp[2..1] : OUTPUT; ) BEGIN TABLE m/io, addr[15..0] => rom, ram, print, sp[]; 1, B"00XXXXXXXXXXXXXX" => 1, 0, 0, B"00"; 1, B"100XXXXXXXXXXXXX" => 0, 1, 0, B"00"; 0, B"0000001010101110" => 0, 0, 1, B"00"; 0, B"0000001011011110" => 0, 0, 0, B"01"; 0, B"0000001101110000" => 0, 0, 0, B"10"; END TABLE; END;

INCLUDE "lpm_decode.inc"; SUBDESIGN decode4 ( address[15..0] : INPUT; chip_enable : OUTPUT; ) BEGIN chip_enable = lpm_decode(.data[]=address[]); WITH (LPM_WIDTH=16, LPM_DECODES=2^10); RETURNS (.eq[H"0370"]); END;

变量缺省值的使用

何处使用 Default 通常应用于节点和组 当节点和组在 AHDL 文档中有些地方没有指定时

使用 Default SUBDESIGN decoder ( low, medium, high : INPUT; highest_level[3..0] : OUTPUT; ) VARIABLE code[2..0] : node; BEGIN DEFAULTS highest_level[] = B"0001"; END DEFAULTS; code2=high; code1=medium; code0=low; CASE code[] IS WHEN 4 => highest_level[] = B"1000"; WHEN 2 => highest_level[] = B"0100"; WHEN 1 => highest_level[] = B"0010"; END CASE; END;

变量缺省值 SUBDESIGN default1 ( i[3..0] : INPUT; ascii_code[7..0] : OUTPUT; ) BEGIN DEFAULTS ascii_code[] = B"00111111"; % ASCII question mark "?" % END DEFAULTS; TABLE i[3..0] => ascii_code[]; B"1000" => B"01100001"; % "a" % B"0100" => B"01100010"; % "b" % B"0010" => B"01100011"; % "c" % B"0001" => B"01100100"; % "d" % END TABLE; END;

竞争实例 1 SUBDESIGN default2 ( a,b : INPUT; select_a, select_b : INPUT; out1 : OUTPUT; ) BEGIN DEFAULTS out1 = GND; END DEFAULTS; IF select_a THEN out1 = a; END IF; IF select_b THEN out1 = b; END; a or b Normal Default SELECT_A A SELECT_B B out1

竞争实例 2 SUBDESIGN default2 ( a,b : INPUT; select_a, select_b : INPUT; out1 : OUTPUT; ) BEGIN DEFAULTS out1 = VCC; END DEFAULTS; IF select_a THEN out1 = a; END IF; IF select_b THEN out1 = b; END; a and b Normal Default SELECT_A A SELECT_B B out1

变量缺省值 Graphic? SELECT_A A SELECT_B WIRE_OR B SELECT_C C WIRE_AND 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; END DEFAULTS; IF select_a THEN wire_or = a; wire_and = a; END IF; IF select_b THEN wire_or = b; wire_and = b; IF select_c THEN wire_or = c; wire_and = c; END; 变量缺省值 Graphic? SELECT_A A SELECT_B B SELECT_C C WIRE_OR WIRE_AND

低有效电路综合

菊花链总线仲裁电路 —优先级电路 单元电路 低有效典型电路 /LoR— 低一级请求 /LoG— 低一级允许 /LR— 本地请求 /LG— 本地允许 /HiR— 向高一级请求 /HiR—高一级允许 /LoR /LoG /LR /HiR /HiG /LG 单元电路

菊花链总线仲裁电路 —优先级电路 菊花链接 低有效典型电路 最高级 中间级 最低级 /LoR /LoG /LR /HiR /HiG /LG GND

低有效典型电路 Graphic SUBDESIGN daisy ( /LR : INPUT; /LG : OUTPUT; /LoR : INPUT; % from lower priority % /LoG : OUTPUT; % to lower priority % /HiR : OUTPUT; % to higher priority % /HiG : INPUT; % from higher priority % ) BEGIN DEFAULTS /LG = VCC; % active-low output % /LoG = VCC; % signals should default % /HiR = VCC; % to VCC % END DEFAULTS; IF (/LoR == GND) # (/LR == GND) THEN /HiR = GND; END IF; IF( /HiG == GND )THEN IF( /LR == GND )THEN /LG = GND; ELSIF( /LoR == GND )THEN /LoG = GND; Graphic /LoR /LoG /LR /HiR /HiG /LG

典型电路细化 /LoR /LoG /LR /HiR /HiG /LG Graphic /HiR /HiG /LoR /LoG /LR /LG

For 循环 用同样的方程更容易 CONSTANT num_of_bit = 8; SUBDESIGN numbit ( a[num_of_bit..0] : input; b[num_of_bit..0] : output; ) BEGIN FOR i IN 0 TO num_of_bit GENERATE b[num_of_bit - i] = a[i]; END GENERATE; END; CONSTANT num_of_bit = 8; SUBDESIGN numbit ( a[num_of_bit..0] :INPUT; b[num_of_bit..0] :OUTPUT; ) BEGIN b[8] = a[0]; b[7] = a[1]; b[6] = a[2]; b[5] = a[3]; b[4] = a[4]; b[3] = a[5]; b[2] = a[6]; b[1] = a[7]; b[0] = a[8]; END; 用同样的方程更容易 CONSTANT num_of_bit = 8; SUBDESIGN numbit (a[num_of_bit..0] : INPUT; b[num_of_bit..0] : OUTPUT; ) BEGIN b[num_of_bit..0] = a[0..num_of_bit]; END;

AHDL 使用图形方式 使用 File 菜单为AHDL 设计文档创建 Symbol 这个 symbol 可用作图形输入

寄存器逻辑

寄存器引用 原形函数 电路图形 方法2 先声明,后成员赋值 方法1 直接代换 默认 D CLK Q PRN CLRN 电路图形 FUNCTION DFF (D, CLK, CLRN, PRN) RETURNS (Q); 原形函数 方法2 先声明,后成员赋值 SUBDESIGN flip_flop ( d, clk : INPUT; q : OUTPUT;) VARIABLE temp :DFF; BEGIN temp.D = d; temp.CLK = clk; Q= temp.q; END; 方法1 直接代换 SUBDESIGN flip_flop ( d, clk : INPUT; q : OUTPUT;) BEGIN 默认 声明一个D触发器 q = DFF(d,clk, ,); END; Q<=DFF(d, clk, CLRN, PRN) Q<=DFF(d, CLK, CLRN, PRN) Q<=DFF(d, clk, CLRN, PRN) Q<=DFF(D, CLK, CLRN, PRN) 成员赋值

更详细… 函数成员引用的意义 temp SUBDESIGN flip_flop ( d, clk : INPUT; q : OUTPUT;) PRN CLRN INPUT OUTPUT d temp.q VARIABLE temp :DFF; INPUT clk temp BEGIN temp.D = d; temp.CLK = clk; Q= temp.q; END;

功能表 FUNCTION DFF (D, CLK, CLRN, PRN) RETURNS (Q); Inputs | Output PRN CLRN CLK D | Q L H X X | H H L X X | L L L X X | Illegal H H L | L H H H | H H H L X | Qo* H H H X | Qo D CLK Q PRN CLRN

D触发器及使能端、清零端和置位端 D Q D Q D Q D Q D Q D Q SUBDESIGN flip_flop_enable ( clock, data : INPUT; enable, preset, clear : INPUT; qout : OUTPUT; ) VARIABLE temp : DFFE; BEGIN qout = temp.Q; temp.D = data; temp.CLK = clock; temp.CLRN= clear; temp.PRN = preset; temp.ENA= enable; END; D CLK Q PRN CLRN ENA D CLK Q PRN CLRN ENA D CLK Q PRN CLRN ENA D CLK Q PRN CLRN ENA D CLK Q PRN CLRN ENA D CLK Q PRN CLRN ENA

功能表 FUNCTION DFFE (D, CLK, CLRN, PRN, ENA) RETURNS (Q); Inputs | Output CLRN PRN ENA D CLK | Q L H X X X | L H L X X X | H L L X X X | Illegal H H L X X | Qo* H H H L | L H H H H | H H H X X L | Qo* D CLK Q PRN CLRN ENA

有关寄存器更多... 寄存器组如何操作 其他种类的寄存器如何操作 DFFE (DFF 带使能) TFF/TFFE JKFF/JKFFE SRFF/SRFFE

寄存器组声明 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; 寄存器组声明 D CLK Q PRN CLRN ENA

寄存器组声明的意义 SUBDESIGN bur_reg ( clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT; ) VARIABLE ff[7..0] : DFF; BEGIN ff[].CLK = clk; ff[].D = d[]; q[] = ff[].Q; END; ff[0].CLK = clk; ff[1].CLK = clk; ff[2].CLK = clk; ff[3].CLK = clk; ff[4].CLK = clk; ff[5].CLK = clk; ff[6].CLK = clk; ff[7].CLK = clk; ff[0].D = d[0]; ff[1].D = d[1]; ff[2].D = d[2]; ff[3].D = d[3]; ff[4].D = d[4]; ff[5].D = d[5]; ff[6].D = d[6]; ff[7].D = d[7]; q[0] = ff[0].Q; q[1] = ff[1].Q; q[2] = ff[2].Q; q[3] = ff[3].Q; q[4] = ff[4].Q; q[5] = ff[5].Q; q[6] = ff[6].Q; q[7] = ff[7].Q;

其他类型的触发器

FUNCTION JKFFE (J, K, CLK, CLRN, PRN, ENA) RETURNS (Q); Inputs | Output ENA PRN CLRN CLK J K | Q X L H X X X | H X H L X X X | L X L L X X X | Illegal X H H L X X | Qo* H H H L L | Qo* H H H H L | H H H H L H | L H H H H H | Toggle L H H X X X | Qo* J CLK Q PRN CLRN ENA K

FUNCTION JKFF (J, K, CLK, CLRN, PRN) RETURNS (Q); Inputs | Output PRN CLRN CLK J K | Q L H X X X | H H L X X X | L L L X X X | Illegal H H L X X | Qo* H H L L | Qo* H H H L | H H H L H | L H H H H | Toggle J CLK Q PRN CLRN K

FUNCTION TFFE (T, CLK, CLRN, PRN, ENA) RETURNS (Q); Inputs | Output CLRN PRN ENA T CLK | Q L H X X X | L H L X X X | H L L X X X | Illegal H H L X X | Qo* H H H L | Qo* H H H H | Toggle H H X X L | Qo* T CLK Q PRN CLRN ENA

FUNCTION TFF (T, CLK, CLRN, PRN) RETURNS (Q); Inputs | Output PRN CLRN CLK T | Q L H X X | H H L X X | L L L X X | Illegal H H L | Qo* H H H | Toggle H H L X | Qo* T CLK Q PRN CLRN

FUNCTION SRFFE (S, R, CLK, CLRN, PRN, ENA) RETURNS (Q); Inputs | Output ENA PRN CLRN CLK S R | Q X L H X X X | H X H L X X X | L X L L X X X | Illegal X H H L X X | Qo* H H H L L | Qo* H H H H L | H H H H L H | L H H H H H | Toggle L H H X X X | Qo* R CLK Q PRN CLRN ENA S

FUNCTION SRFF (S, R, CLK, CLRN, PRN) RETURNS (Q); Inputs | Output PRN CLRN CLK S R | Q L H X X X | H H L X X X | L L L X X X | Illegal H H L X X | Qo* H H L L | Qo* H H H L | H H H L H | L H H H H | Toggle R CLK Q PRN CLRN S

带寄存器的输出声明 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;

LPM——参数模块化函数[略]

FUNCTION lpm_dff (data[LPM_WIDTH-1 FUNCTION lpm_dff (data[LPM_WIDTH-1..0], clock, enable, shiftin, shiften, sclr, sset, sconst, aclr, aset, aconst) WITH (LPM_WIDTH, LPM_AVALUE, LPM_SVALUE) RETURNS (q[LPM_WIDTH-1..0], shiftout); FUNCTION lpm_ff (data[LPM_WIDTH-1..0], clock, enable, sclr, sset, sload, aclr, aset, aload) WITH (LPM_WIDTH, LPM_AVALUE, LPM_SVALUE, LPM_FFTYPE) RETURNS (q[LPM_WIDTH-1..0]);

INCLUDE "lpm_dff.inc"; SUBDESIGN lpm_reg ( clk, load, d[7..0] : INPUT; q[7..0] : OUTPUT; ) BEGIN q[] = lpm_dff (.clock=clk, .enable=load, .data[]=d[]) WITH (LPM_WIDTH=8) RETURNS (.q[]); END;

怎样使用 Help 菜单 问 : 不知到 Altera DFF/JKFFE等定义, 该怎么办 ? 答 : Altera Help 菜单是寻找相关信息的好地方。 问 : 如何使用 Help 菜单? 答 : 容易且有趣。 DFFE

如何使用 Help 菜单

寄存器的应用 -------三态总线的综合

Tri-state 三态缓存器引用 电路图形 FUNCTION TRI (in, oe) RETURNS (out); AHDL原形函数 方法2 先声明,后成员赋值 SUBDESIGN tri_state ( a, enable : INPUT; b : OUTPUT;) VARIABLE temp : TRI; BEGIN temp.in = a; temp.oe = enable; b = temp.out; END; 方法1 直接代换 SUBDESIGN tri_state (a, enable : INPUT; b : OUTPUT;) BEGIN 声明 b = TRI(a,enable); END; out<=TRI(a, oe) out<=TRI(a, enable) out<=TRI(in, oe) 成员赋值

更详细… 函数成员引用的意义 SUBDESIGN tri_state ( a, enable : INPUT; b : OUTPUT;) VARIABLE temp : TRI; in out oe enable a b BEGIN temp.in = a; temp.oe = enable; b = temp.out; END;

TRI 三态原形 AHDL原形函数 FUNCTION TRI (in, oe) RETURNS (out); VHDL 元件声明 COMPONENT TRI PORT (a_in : IN STD_LOGIC; oe: IN STD_LOGIC; a_out: OUT STD_LOGIC); END COMPONENT; 功能表 Inputs | Output IN OE | OUT X 0 | Z 1 1 | 1 0 1 | 0 oe in out Graphic

OPNDRN – 漏极开路缓存器引用 电路图形 FUNCTION OPNDRN (in) RETURNS (out); AHDL原形函数 方法2 先声明,后成员赋值 SUBDESIGN opn_drn ( enable : INPUT; b : OUTPUT;) VARIABLE temp : OPNDRN; BEGIN temp.in = enable; b = temp.out; END; 方法1 直接代换 SUBDESIGN opn_drn ( enable : INPUT; b : OUTPUT;) BEGIN 声明 b = OPNDRN(enable); END; out<= OPNDRN(in) out<= OPNDRN(enable) 成员赋值

OPNDRN的功能 Z态 “0” “1” OPNDRN 从不输出高。怎样才能高?? 解决方案:外设置上拉电阻,在高阻的情况下将输出拉高。

更详细… 函数成员引用的意义 SUBDESIGN opn_drn ( enable : INPUT; b : OUTPUT;) VARIABLE temp : OPNDRN; in out b BEGIN temp.in = enable ; enable b = temp.out; END;

OPNDRN原形 AHDL原形函数 FUNCTION OPNDRN (in) RETURNS (out); VHDL 元件声明 COMPONENT OPNDRN PORT (a_in : IN STD_LOGIC; a_out: OUT STD_LOGIC); END COMPONENT; 功能表 Inputs | Output IN | OUT 1 | Z 0 | 0 Graphic in out

使用三态缓冲器须仔细 功能表 Inputs | Output IN OE | OUT X 0 | Z 1 1 | 1 0 1 | 0 SUBDESIGN tri_state ( enable : INPUT; b : OUTPUT; ) VARIABLE temp : TRI; BEGIN temp.oe = enable; temp.in = VCC; b = temp.out; END; 功能表 Inputs | Output IN OE | OUT X 0 | Z 1 1 | 1 0 1 | 0

发生了什么 !!!! 得到了一个 OPNDRN 而非 TRI Max+Plus II哪错了? SUBDESIGN tri_state ( enable : INPUT; b : OUTPUT; ) VARIABLE temp : TRI; BEGIN temp.oe = enable; temp.in = GND; b = temp.out; END; 发生了什么 !!!! 得到了一个 OPNDRN 而非 TRI Max+Plus II哪错了?

OPNDRN 与 TRI 比较 功能是相同的 TRI (in, oe) RETURNS (out) oe = ?? in = out oe = ?? out = Z OPNDRN (in) RETURNS (out) in = ?? out = Z in = ?? out = ? 功能是相同的 TRI : in = GND oe = enable (1) out = GND oe = enable (0) out = Z OPNDRN : in = !enable (!0) out = Z in = !enable (!1) out = GND

将 Tri-State 改为 OPNDRN 点击这一选项 On/Off

Tri-State 和 OPNDRN TRI(gnd, enable) 如果要保留 TRI-State buffer, 点击off “ Automatic Open-drain pin”选项。 如果想将 TRI-State buffer 变为 OPEN-DRAIN,点击on “ Automatic Open-drain pin”选项。 off in out oe enable b gnd in out oe enable b gnd on in out !enable b

使用 AHDL与 Schematic一样容易 但 使用 AHDL 更强大。

三态总线综合 SUBDESIGN tri_bus ( in[3..1], oe[3..1] : INPUT; out1 : OUTPUT; ) VARIABLE tnode : TRI_STATE_NODE; BEGIN tnode = TRI(in1, oe1); tnode = TRI(in2, oe2); tnode = TRI(in3, oe3); out1 = tnode; END; Graphic tnode in3 in2 in1 oe1 oe2 oe3 out1

双向引脚综合 Graphic SUBDESIGN bus_reg3 ( clk : INPUT; oe : INPUT; io : BIDIR; ) VARIABLE my_dff : DFF; my_tri : TRI; BEGIN my_dff.d = io; my_dff.clk = clk; my_tri.in = my_dff.q; my_tri.oe = oe; io = my_tri.out; END; D CLK Q PRN CLRN IO OE BIDIR SUBDESIGN bus_reg2 ( clk : INPUT; oe : INPUT; io : BIDIR; ) VARIABLE dff_out : NODE; BEGIN dff_out = DFF(io, clk, ,); io = TRI(dff_out, oe); END; oe clk io OE bus_reg2 CLK IO

FUNCTION bus_reg2 (clk, oe) RETURNS (io); SUBDESIGN bidir1 ( clk, oe : INPUT; io[3..0] : BIDIR; ) BEGIN io0 = bus_reg2(clk, oe); io1 = bus_reg2(clk, oe); io2 = bus_reg2(clk, oe); io3 = bus_reg2(clk, oe); END; oe clk io OE bus_reg2 CLK IO1 Graphic oe clk io OE bus_reg2 CLK IO2 oe clk io OE bus_reg2 CLK IO3

内部Tri-state 被Max+Plus II oe1 in1 oe2 in2 in3 out AHDL SUBDESIGN tri_state_bus ( in1, in2, in3 : INPUT; oe1, oe2 : INPUT; out : OUTPUT;) VARIABLE tnode : TRI_STATE_NODE; BEGIN tnode = TRI(in1, oe1); tnode = TRI(in2, oe2); out = in3 & tnode; END; tnode -- Node name is 'out' from file "tri_state_bus.tdf" line 10, column 1 out = _LC1_B1; ~33~2 = LCELL( _EQ001); _EQ001 = !oe1 # in1; _LC1_B1 = LCELL( _EQ002); _EQ002 = in3 & !oe2 & ~33~2 # in2 & in3 & ~33~2; 编译结果 节点在内部 内部Tri-state 被Max+Plus II 自动转化为多路选择器 MUX out=in3&(!oe1#in1)&(!oe2#in2)

I/O Tri-State 总线 AHDL oe1 in1 out oe2 in2 I/O 管脚支持真Tri-State TRI tnode SUBDESIGN tri_state_bus ( in1, in2, in3 : INPUT; oe1, oe2 : INPUT; out : OUTPUT;) VARIABLE tnode : TRI_STATE_NODE; BEGIN tnode = TRI(in1, oe1); tnode = TRI(in2, oe2); out = tnode; END; tnode I/O 管脚支持真Tri-State

逻辑与(AND)

寄存器的应用 -------设计计数器

设计计数器 SUBDESIGN 8bits (clk : INPUT; q[7..0] : OUTPUT; ) VARIABLE temp[7..0] : DFF; BEGIN temp[].CLK = clk; temp[].D = temp[].Q +1; q[] = temp[].Q; END;

Creating Counters 设计计数器 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; ELSE count[].D = count[].Q; END IF; q[] = count[]; END; Creating Counters 设计计数器

clk q0 clr T CLK Q PRN CLRN ena q15 q1 load d0 d1 d15

INCLUDE "lpm_counter.inc"; SUBDESIGN lpm_cnt ( clk, load, ena, clr, d[15..0] : INPUT; q[15..0] : OUTPUT; ) VARIABLE my_cntr: lpm_counter WITH (LPM_WIDTH=16); BEGIN my_cntr.clock = clk; my_cntr.aload = load; my_cntr.cnt_en = ena; my_cntr.aclr = clr; my_cntr.data[] = d[]; q[] = my_cntr.q[]; END;

FUNCTION lpm_counter (data[LPM_WIDTH-1 FUNCTION lpm_counter (data[LPM_WIDTH-1..0], clock, clk_en, cnt_en, updown, cin, aclr, aset, aconst, aload, sclr, sset, sconst, sload) WITH (LPM_WIDTH, LPM_DIRECTION, LPM_MODULUS, LPM_AVALUE, LPM_SVALUE, CARRY_CNT_EN, LABWIDE_SCLR) RETURNS (q[LPM_WIDTH-1..0], cout, eq[15..0])

时序逻辑

状态机声明 可以这样创建一个状态机,通过在Variable Section中声明一个状态机名,它的状态,以及附加的状态位。 以下为状态机声明的范例: VARIABLE ss :MACHINE OF BITS (q1, q2, q3) WITH STATES ( s1 = B"000", s2 = B"010", s3 = B"111"); 状态位名 状态机名 状态分配值 状态名

<number of states> <= 2^<number of state bits> 状态机名是一个符号名。在上例中,状态机名是 ss。 在状态机名后紧跟一个冒号 “:” 及关键字 MACHINE。 状态机声明必须包括一个状态列表,可以包含一个状态位名列表。 附加的状态位用关键字OF BITS 定义,随后是以逗号分隔的符号名列表,列表必须以括号“()”括起。上例中定义的状态位是q1, q2, 及 q3。 状态用关键字WITH STATES定义,随后是以逗号分隔的符号名列表,列表必须以括号“()”括起。上例中定义的状态是s1, s2, 及 s3。 列在WITH STATES子句中的第一个状态是状态机的起始(复位)状态 。 状态名或许还会被安排一个附加值,用等号“=”和其后的数字表示。上例中s1 被安排为 B“000”, s2被安排为 B“010”, 及 s3被安排为 B “ 111 ” 。 还可以用一个状态机别名声明来对一个状态机安排一个替用名,该状态机可能在当前文档中被声明,或引用别的文档。状态机声明以分号“;”结束。 状态机的每一个状态以触发器组输出信号高低组成的某一图案唯一确定。状态位就是状态机用来储存状态的触发器输出。在一个状态机中,状态数和状态位数有以下关系: <number of states> <= 2^<number of state bits>

状态机初步 jump=0 s0 q=0 状态转换图 jump=1 jump=1 s1 q=1 jump=0

状态机初步 q jump clk reset CASE ss IS WHEN s0 => q = GND; IF jump THEN ss = s1; END IF; WHEN s1 => q = VCC; ss = s0; END CASE; END; SUBDESIGN simple ( clk, reset, jump : INPUT; q : OUTPUT; ) VARIABLE ss: MACHINE WITH STATES (s0, s1); BEGIN ss.clk = clk; ss.reset = reset; 注意 : 所有的状态机变量都关联此时钟 T CLK Q PRN CLRN jump clk VCC q reset

IF (jump) THEN ss = s1; END IF; IF (jump) THEN ss = s0; END IF;

复位- 高有效还是低有效? ss : MACHINE WITH STATES (S0,S1) 高有效

分配状态机比特位和值 一个状态位就是就是一个触发器的输出,该触发器被状态机用于储存状态的一位值。 在大多数情况下,应该允许MAX+PLUS II编译器分配状态位和值以便最小化所需的逻辑资源:逻辑综合器自动最小化所需的状态位数,同时优化器件的可利用性和性能。 然而,有些状态机用超过最小状态位数的状态值可能运行更快。此外,可能要求状态机输出直接就是状态位。为了控制这些情况,在状态机声明中,可以人为确定状态位和值。

状态机更进一步 BEGIN ss.clk = clk; ss.reset = reset; TABLE IF(reset) THEN ss = s2; END IF; phase[] = temp[]; 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; SUBDESIGN stepper ( clk, reset : INPUT; ccw, cw : INPUT; phase[3..0] : OUTPUT; ) VARIABLE ss: MACHINE OF BITS (temp[3..0]) WITH STATES ( s0 = B"0001", s1 = B"0010", s2 = B"0100", s3 = B"1000"); 注意: 不需要声明 temp的属性 自动声明为 DFF。

用户可以控制状态 Bit

具有同步输出的状态机 Moore型 !y !y y s0 !y y s1 1 s2 1 !y y y s3

具有同步输出的状态机 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; SUBDESIGN moore1 ( clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; ) VARIABLE % current current % % state output % ss: MACHINE OF BITS (z) WITH STATES s0 = 0, s1 = 1, s2 = 1, s3 = 0 );

D CLK Q PRN CLRN y clk z reset

SUBDESIGN moore2 ( clk : INPUT; reset : INPUT; y : INPUT; z : OUTPUT; ) 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;

Mealy型 s0 s3 s1 s2 In=0 out=0 In=1 out=1 In=1 out=1 In=0 out=0 In=0

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 % 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; s2, 1 => 1, s3; s3, 0 => 0, s3; s3, 1 => 1, s0; END TABLE; END;

D CLK Q PRN CLRN y clk z reset

带有状态恢复的状态机

例: ok = (sequence == four); BEGIN sequence.clk = clk; 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); 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; END CASE; ok = (sequence == four); END;

状态机卡在 FOUR

非法状态的恢复 ok = (sequence == four); 3个 bits 有8个状态 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 => sequence = idle; END CASE; ok = (sequence == four); END; 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); 3个 bits 有8个状态 只有5个状态是有用的。 使用这些 RECOVER 项最好

RECOVER

状态机的输入和输出

定义一个状态机具有状态 : S1, S2, S3, S4, S5 SUBDESIGN ss_def (clk, reset, count : INPUT; ss_out : MACHINE OUTPUT; ) VARIABLE ss: MACHINE WITH STATES (s1, s2, s3, s4, s5); BEGIN ss_out = ss; CASE ss IS WHEN s1=> IF count THEN ss = s2; ELSE ss = s1; END IF; WHEN s2=> IF count THEN ss = s3; ELSE ss = s2; END IF; WHEN s3=> IF count THEN ss = s4; ELSE ss = s3; END IF; WHEN s4=> IF count THEN ss = s5; ELSE ss = s4; END IF; WHEN s5=> IF count THEN ss = s1; ELSE ss = s5; END IF; END CASE; ss.(clk, reset) = (clk, reset); END;

(ss_in : MACHINE INPUT; out : OUTPUT; ) BEGIN SUBDESIGN ss_use (ss_in : MACHINE INPUT; out : OUTPUT; ) BEGIN out = (ss_in == s2) OR (ss_in == s4); END; 状态机: 再此定义,在别处使用

FUNCTION ss_def (clk, reset, count) RETURNS (MACHINE ss_out); FUNCTION ss_use (MACHINE ss_in) RETURNS (out); SUBDESIGN top1 ( sys_clk, /reset, hold : INPUT; sync_out : OUTPUT; ) VARIABLE ss_ref: MACHINE; % Machine Alias Declaration % BEGIN ss_ref = ss_def(sys_clk, !/reset, !hold); sync_out = ss_use(ss_ref); END;

状态机输入输出 状态机别名 状态机在此使用 状态机定义在此 ss_def SS_REF ss_use sys_clk sync_out RESET COUNT SS_OUT SS_REF SS_IN OUT ss_use sys_clk sync_out reset hold 状态机别名 状态机在此使用 状态机定义在此

FUNCTION ss_def (clk, reset, count) RETURNS (MACHINE ss_out); FUNCTION ss_use (MACHINE ss_in) RETURNS (out); SUBDESIGN top2 ( sys_clk, /reset, hold : INPUT; sync_out : OUTPUT; ) VARIABLE sm_macro : ss_def; sync : ss_use; BEGIN sm_macro.(clk, reset, count) = (sys_clk, !/reset, !hold); sync.ss_in = sm_macro.ss_out; sync_out = sync.out; END;

AHDL 支持层次设计 层次设计 子模块设计 易于管理和理解 可利用已完善并验证的设计成果

例 1 : div2 subtop 4count count SUBTOP 7segment CLK2 CLK OUT[6..0] LDN A B C D CIN DNUP SETN CLRN CLK clk QA QB QC QD COUT i0 i1 i2 i3 i[3..0] SUBTOP E F G I[3..0] a b c d e f g 7segment

SUBDESIGN div2 ( clk2 : INPUT; clk : OUTPUT; ) VARIABLE temp : DFF; BEGIN temp.clk = clk2; temp.d = !(temp.q); clk = temp.q; END;

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"0" => 1, 1, 1, 1, 1, 1, 0; H"1" => 0, 1, 1, 0, 0, 0, 0; H"2" => 1, 1, 0, 1, 1, 0, 1; H"3" => 1, 1, 1, 1, 0, 0, 1; H"4" => 0, 1, 1, 0, 0, 1, 1; H"5" => 1, 0, 1, 1, 0, 1, 1; H"6" => 1, 0, 1, 1, 1, 1, 1; H"7" => 1, 1, 1, 0, 0, 0, 0; H"8" => 1, 1, 1, 1, 1, 1, 1; H"9" => 1, 1, 1, 1, 0, 1, 1; H"A" => 1, 1, 1, 0, 1, 1, 1; H"B" => 0, 0, 1, 1, 1, 1, 1; H"C" => 1, 0, 0, 1, 1, 1, 0; H"D" => 0, 1, 1, 1, 1, 0, 1; H"E" => 1, 0, 0, 1, 1, 1, 1; H"F" => 1, 0, 0, 0, 1, 1, 1; END TABLE; END;

INCLUDE “7segment.inc” INCLUDE “4count” SUBDESIGN subtop ( clk : INPUT; out[6..0] : OUTPUT; ) VARIABLE temp : 7segment; temp1 : 4count; BEGIN temp1.clk = clk; temp.i[] = temp1.(qd,qc,qb,qa); out[] = temp.(a,b,c,d,e,f,g); END;

什么是 INC 文件 INC 提供接口信息 INC 文件实例 FUNCTION 7segment (i[3..0]) RETURNS (a, b, c, d, e, f, g); FUNCTION div2 (clk2) RETURNS (clk); 这个函数输入矢量为 i[3..0] 输出端子名为 a,b,c,d,e,f,g

INCLUDE“subtop.inc” INCLUDE “div2 ” SUBDESIGN top ( clk50 : INPUT; segment[6..0] : OUTPUT; ) VARIABLE temp : subtop; temp1 : div2; BEGIN temp1.clk2 = clk50; temp.clk = temp1.clk; Segment[ ] = temp.out[ ]; END;

仿真结果 a g d a g d a g d a g d a g d a g d a g d a g d a g d a g d a g d H"0" => 1, 1, 1, 1, 1, 1, 0; H"1" => 0, 1, 1, 0, 0, 0, 0; H"2" => 1, 1, 0, 1, 1, 0, 1; H"3" => 1, 1, 1, 1, 0, 0, 1; H"4" => 0, 1, 1, 0, 0, 1, 1; H"5" => 1, 0, 1, 1, 0, 1, 1; H"6" => 1, 0, 1, 1, 1, 1, 1; H"7" => 1, 1, 1, 0, 0, 0, 0; H"8" => 1, 1, 1, 1, 1, 1, 1; H"9" => 1, 1, 1, 1, 0, 1, 1; H"A" => 1, 1, 1, 0, 1, 1, 1; H"B" => 0, 0, 1, 1, 1, 1, 1; H"C" => 1, 0, 0, 1, 1, 1, 0; H"D" => 0, 1, 1, 1, 1, 0, 1; H"E" => 1, 0, 0, 1, 1, 1, 1; H"F" => 1, 0, 0, 0, 1, 1, 1; a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e a b f g d c e

INCLUDE "ss_use.inc"; INCLUDE "ss_def.inc"; SUBDESIGN top1 (sys_clk, reset, hold : INPUT; sync_out : OUTPUT; ) VARIABLE ss_ref: MACHINE; BEGIN ss_ref = ss_def(sys_clk, reset, hold); sync_out = ss_use(ss_ref); END;

AHDL进阶 欲用必知

使用 Altera 提供的函数 Altera 提供 Old-Style 宏函数 何处获得 ? 怎样使用 ? 74xx MAXPLUS2\MAX2LIB\MF 怎样使用 ?

怎样使用 7400 INCLUDE 7400; SUBDESIGN mf1 ( a, b : INPUT; c : OUTPUT;) VARIABLE temp : 7400; BEGIN temp.2 = a; temp.3 = b; c = temp.1; END;

怎样使用 4COUNT INCLUDE “4count.inc” SUBDESIGN prim1 ( clk : INPUT; out[3..0] : OUTPUT;) VARIABLE temp : 4count; BEGIN temp.clk = clk; out0 = temp.qa; out1 = temp.qb; out2 = temp.qc; out3 = temp.qd; END;

使用 Altera 提供的LPM 库安装在 - MAXPLUS2\MAX2LIB\MEGA_LPM 如何使用 LPM_ADD_SUB、LPM_RAM/ LPM_FIFO 等如何使用

例: 使用 LPM_MULT Help 菜单提供在AHDL中如何使用 LPM 有关信息

INCLUDE "lpm_mult. inc"; SUBDESIGN lpm_mult1 ( a[3. 0], b[3 INCLUDE "lpm_mult.inc"; SUBDESIGN lpm_mult1 ( a[3..0], b[3..0] : INPUT; c[7..0] : OUTPUT; ) VARIABLE temp : lpm_mult with (LPM_WIDTHA = 4, LPM_WIDTHB = 4, LPM_WIDTHP = 8, LPM_WIDTHS = 1); BEGIN temp.dataa[]=a[]; temp.datab[]=b[]; c[]=temp.result[]; END;

例 : 使用 LPM_RAM_DQ

试一试 INCLUDE “lpm_ram_dq.inc” SUBDESIGN lpmram ( address[7..0], we, data[7..0] :INPUT; dataout[7..0] : OUTPUT; ) VARIABLE temp : lpm_ram_dq with (LPM_WIDTH = 8, LPM_WIDTHAD = 8, LPM_INDATA = 揢NREGISTERED? LPM_ADDRESS_CONTROL = 揢NREGISTERED? LPM_OUTDATA = 揢NREGISTERED? EAB = 揙N); BEGIN temp.address[] = address[]; temp.data[] = data[]; temp.we = we; dataout[] = temp.q[]; END;

AHDL进阶 或可有助

什么是 Parameter 使用 Parameter, 设计很容易调试。 Parameter值 在编译阶段提供,而不是在设计阶段。

Parameter 实例 需要 8个 DFF 需要 8个 DFF 此值在设计阶段提供 此值在编译阶段提供 在编译阶段怎样赋值? SUBDESIGN flip_flop ( clk, d[7..0] : INPUT; q[7..0] : OUTPUT; ) VARIABLE temp[7..0] : DFF; BEGIN temp[].d = d[]; temp[].clk = clk; q = temp[].q; END; SUBDESIGN flip_flop ( clk, d[length..0] : INPUT; q[length..0] : OUTPUT; ) VARIABLE temp[lenght..0] : dff; BEGIN temp[].d = d[]; temp[].clk = clk; q = temp[].q; END; 需要 8个 DFF 需要 8个 DFF 此值在设计阶段提供 此值在编译阶段提供 在编译阶段怎样赋值?

Parameter 在编译过程中传递 修改一处, 自动更新其余 PARAMETERS ( length ); SUBDESIGN flip_flop ( clk, d[length..0] : INPUT; q[length..0] : OUTPUT; ) VARIABLE temp[length..0] : DFF; BEGIN temp[].d = d[]; temp[].clk = clk; q[] = temp[].q; END; 修改一处, 自动更新其余

Parameter进一步 缺省值 PARAMETERS ( length = 5 ); SUBDESIGN flip_flop ( clk, d[length..0] : INPUT; q[length..0] : OUTPUT; ) VARIABLE temp[length..0] : DFF; BEGIN temp[].d = d[]; temp[].clk = clk; q[] = temp[].q; END; 缺省值 Parameter value assignment : if (parameter provide through the Global parameter option) then use the Global parameter option else if (default value is provided) then use the default value ERROR : missing parameter value end if

创建自己的 LPM 参数化符号 PARAMETERS ( length = 5 ); SUBDESIGN flip_flop ( clk, d[length..0] : INPUT; q[length..0] : OUTPUT; ) VARIABLE temp[length..0] : DFF; BEGIN temp[].d = d[]; temp[].clk = clk; q[] = temp[].q; END; 参数化符号

旧的 Schematic设计如何沿用??? 问: 旧的 Schematic 设计, 在 AHDL如何沿用 ? 答: 改为AHDL设计。 问: 但设计很大且无BUG, 又不想冒险,如何处理? 答: Altera 提供AHDL与Schematic设计的接口。 问: 需要做什么,能否保证100%正确 ? 答: 不需做任何事情 Max+Plus II 保证 100% 正确。

解决方案 首先创建 INC 文件 如何做 ? D Q 25MHz INCLUDE "test1.inc"; INCLUDE "4count"; SUBDESIGN advan ( clk50 : INPUT; ca[3..0] : OUTPUT; cb[3..0] : OUTPUT; ) VARIABLE temp : test1; tempa : 4count; tempb : 4count; BEGIN temp.50mhz = clk50; tempa.clk = clk50; tempb.clk = temp.25mhz; ca[] = tempa.(qd, qc, qb, qa); cb[] = tempb.(qd, qc, qb, qa); END; D CLK Q PRN CLRN 50MHz 25MHz

仿真结果 50MHz 25MHz

AHDL 格式总结 Title Statement Parameters Statement Include Statement TITLE “display Controller use EPM7032LC44-7 ” Parameters Statement PARAMETERS ( width, numwords = 8); Include Statement INCLUDE “8count” Constant Statement CONSTANT address_decode = H “78” Define Statement DEFINE MAX(a,b) = (a > b) ? a : b; AHDL 格式总结 Subdesign Section SUBDESIGN project_name ( a[width..0] : INPUT; b[numwords..0] : OUTPUT;) Variable Section VARIABLE temp : DFF; temp1 : TRI_STATE_NODE; temp3 : MACHINE; Logic Section BEGIN DEFAULTS a[]= VCC; END DEFAULTS IF ( ) THEN END IF; END;

Logic Section - Defaults Statement - Assert Statement - Boolean Equations - Boolean Control Equations - Case Statement - For Generate Statement - If Then Statement - If Generate Statement - In-Line Logic Function Reference - Truth Table Statement Title Statement Include Statement Constant Statement Define Statement Parameters Statement Function Prototype Statement Options Statement Assert Statement Subdesign Section Variable Section - Instance Declaration - Node Declaration - Register Declaration - State Machine Declaration - Machine Alias Declaration

Altera TDO 和 ACO 文件 是什么?

当在 Max+Plus II v8.0下做的工程, 换为v9.x后怎么办 ? ss_def CLK RESET COUNT SS_OUT SS_REF SS_IN OUT ss_use sys_clk sync_out reset hold 当在 Max+Plus II v8.0下做的工程, 换为v9.x后怎么办 ? 使用 TDO 和ACO 文件保持在 Max+Plus II vx.x下的设计

选项在何处

什么是 TDO 文件 TDO 文件实例 最底层的逻辑单元

什么是 ACO 文件 ACO 文件实例 Pin/LC 定位信息

TDO和ACO 文件的用处 Max+Plus II 的不同版本会造成不同的逻辑综合和试配算法, 将引起 不同数量的 Logic Element/Macro Cell 的使用 不同的时间延迟和不同的执行结果 TDO文件是原设计的最底层逻辑单元的转换文件 ACO 包含所有Logic Cell/Pin 的定位信息

小心使用 TDO 和ACO 不要忘记 将 TDO 改名为 TDF 将 ACO改名为 ACF 将全局工程逻辑综合改为 WYSIWYG (What you see is what you get) WYSIWYG 将不做任何逻辑综合和优化 .... 这就是所要达到的目的 – 不做任何改变. OK!

总 结 使用AHDL 与图形一样容易但更强大。 尽量使用Altera提供的LPM 而不是用你自己创建的。 层次设计方法 缩短设计周期 总 结 使用AHDL 与图形一样容易但更强大。 尽量使用Altera提供的LPM 而不是用你自己创建的。 缩短设计周期 易于适配 Altera 器件 少用 Logical Cell /Macro Cell usually higher in performance 层次设计方法 易于管理 易于应用 ASSIGN OPTION

秘诀 : TMYUTMUK T M Y U K he ore ou se now