首页资源分类PCB layout > verilog HDL

verilog HDL

已有 451217个资源

下载专区

上传者其他资源

    文档信息举报收藏

    标    签:verilog HDL

    分    享:

    文档简介

    Verilog HDL应用程序设计实例精讲.pdf

    文档预览

    xxxx x x )( X x f­ x x v h w h xxv h :x X "'嘀嘀,•.�..,a_II:'O..CII • X 只 )( X X ')( )( )C )( x )( X )( 'x X )( X X :X )( )ê x ,X x )c X )c X X x x x x )c X X )( X x X 'x x x x x xx x X ,)( x )( X X X x Xx X x xx )(' X Xx x x M A x x )( x x x x Xx V P ')( x x x x x x Xx V Ax x X xxxx X xx M Ax x Xx M A X X xx XM XX A x Xx x x x XX Xx x x Xx w h X )( X X X XM A xx X x x xxxx xxx X xx 'x X X xx X )( xX X x x x )( X X x X xx xxx V A )c X X x M Rx 沉 x X 气、 x xx - xx xx x xv h x ,电 3且 民 xxxx 刘 奇 刘渡 x x x x )( x xx xXx ‘ sc )( X X x )( X :x x )( X xxx )( )( )( X l( xxx x )( )( :x )< )( • x )c X x )( X X )( X X X ,)C x )( )( x 沉沉x比x x XW XXx Xm A X X X M x X m :x 3唱 XXXW x Xv R h X X XXx Xx XM XXxXx A X X X M R X X X M A x x v h v h 民 w h XX H 嗣x XM XM xxv X A A h X X X X x x M A X x X X XXx xXX x XXXXx xX VM R x U A R XX X AU …-… …...� lfwww. ..…1. 00. .0.. v y w � 1Iι x x x x xX X X X X :x )( - ) • • 文视点· IT出 团a团 x X )( X X xx � X �X X X ) x x X X J( X X X X X X X � X )( ) INWw.bro.d.".肌c:om.c:n 技术凝聚实力·专业创新出版 � ‘, )( X ‘, x ‘a x x� )( X x x x x x x X x x X 'X )C :X � )(MXA Mh )(X X X XMXA XX X XX X X XVA X X MA X )c x uX h )cX Mxh x x【X X ;xMxA um x VVXAm ) xxxxx xxx X X xX X X , )c X X X X X X X )c X )c X X X X � x xx x x � xx x xx X X X J x x x x x x x xX x x x x xX l lC )( X X X X x x x x x x x xX J • x x xx x xxxx x x xxx x , x x x xx xX X XX X X X X X X x : xx x x x x x x )( X X X X X x : x x x )( X X X X' X X X )c X X X • • 与 围绕氢 , 注重 ·在讲述Verilog HDL语言程序设计的基础上, x � x x )( x x x : 用和 x xX x x x x x : 统、 3可 深入地介绍了犬部 x xX X xX X x MXA .x MXA x X X : 分同类书 中很少涉及的Verilog HDL语言综合内 。 x x x x x x x X X X XX U戴 lχ x 字通倍 ·实例典型丰富,30多个实例涉及了逻辐电路、 川 ­x x 数字控制等热门领域,技术性和实践指导性强。 x xx x x x xx x X xxx x .x x x x x • 对Verilog HDL语言程序设计思路和流程进行讲解, 同时劈插介 X X 'X X :X x 绍许多设计经验与注 三的能力。 , 利于读者理解和巩固知识点, 举-T反 X x X X )( .x x x x )( X X xx x xxxx xx x x x x xxx x )( x x x )( X X X x x :x )( X X X x x x x x x - )C� - ), C . 吃 包括书伸实例的Ve巾9HPL程序代码和实例视频交 ,:: l :; x 源代码 加修改, 己的 , 物超所值。 可应用于自己的工作中或 x )( )( X X X :x X IX X X )( x X X J唱 ,电 x .x .)( :x x x X X )í X X x X )( ,)C .筑 )( X X X x x .x x x x x :x x x xlx x x x x x x x x x x x )( X X '电 x X x x x 只 x x x x x x x x :x • x x x x x xxxX xx xx xxx x 民VMhA x x X )1 x Ä x xx� x XXX � K .)C X X x X � X x x x :x. x x xxx x X )C. )( '‘ 3‘ 责任编辅: 葛 娜 责任美编: 李 玲 本书贴有激光防伪标志, 凡没有防伪标志者, 属盗版图书. 3电 ISIN 918-7-121-09548-1 ,电 xX x 我 x 〉 vwvxhnn x X MM-MAAhA x 定价: 65.∞元(舍先盒1张沪X )( )( 在 X ." ,. X X x • x x x x x x x x X � X x. x 甲、{" ... v、i_ ' Ý' 'v V 'v ''IIl V、,、,、p x 忧民 X』 h MA VF MA 只. Xu h J且 x )( )c ., x y. x )( X .J( ): X )é )( X 1( x � 3且 )( x 3电 x 'U x x x x )c x x )( M )c 2毛 x � �xx x ): )( x x )1,: 2豆 x x x ')( x 玩 Eι l( x x 军. x 'x 3毛 x 'x � x x x 只x x x )( x x x x x x x )(: x x ')(_ x x )( 3ι χ 'X x 提 >! w x N >: )! x x x '可 x x x x x )( x xxx x x x )( x x )( x )( x x 1民 冒生 � )( >: )! x x x B是 x '电 )( )C� x x l( x x x )c )Ç x B民 ,民 � ) 3町 x x x )t .x x x ,.: 3且 )( )t jlJ桶 刘渡 x x x x x u 饵 h M" h品 wu h W A MA h 宅二子三苦也兵�是生· Publishing House of Electronics Indus位y 北京.BEIJING "…. …. .. ...........由-………_..._.._…·一- 先血说明 一 ………..…一一……一 ..一 本光盘包括 内 容 如 下 : 文件(f) 罐罐恒} 董着 蚁'ω 工具ω 帽勘ω 刷。f回i]民 A.亟 E.) 挝 - 侈、EIg j)亟 栅 |辰豆豆| 园 ' 文件夹 X 光盘�材 f3 u bH 'J8擎 ..副隘因画面 ,、 圄圃 XI9凶X Lòr� " i立国特到 0' basecate t:I bid江et'tio.nεate ζl CoJILlunlllt �at 0 da'tac:ollpara 忆:l dahdu-tr孟butor d直:tuelec;tor ö tCÌlate .扁扁瓷器设计 常用细蔽嚣ii计 附瓷器玻计 自己已 第9匍11罗华蜡GF (q)熏i去器设计 d触发帽 volkdiv \:)Vpl1 计跄樨 �口'事1移0擎位寄存量E ,自11. Eì\与第四. 12C 'Iuted童 和l器 设计实两 SPI控制器设1惯例UARI收发器设才案例 存储器设计实例 团圆『 画画· 时序电脑设计实倒 触字躏率计设计实例 组合电.设计窑倒 ceíre 4 " 、, - ) 7个时很何T用磕盘空间:锦.9 GB) 60一 � IB 一 � �我的电脑一 • (1)源代码: 本光盘提供了-r� III实例的Verilog HDL程序代码。 为了方便查阑, 句,古 实例都归料在该章相应的文件夹fo 代码文件格式为: *.v, 读者可以用Quartus 11软竹必 Windows记事本进行打开和编辑。 (2)布储器文件:扩展名为MlF: 仿真波形文件:扩展名为YWF, 片J Quartus 11软 件打开。 v · · ( 3 ) 实例视频文件 : 文件格式为 .�叽, 建议读者安装暴风暴影之类 的 播放器 迸行打开 和 观看。 回.JU5啻组合咆鹤说计�例. .Y‘ 一一一 �.,..阉- •• 即-û_. n tr". "TIUOI • , ., ..,-.,- 唱1) .蝇 . 由· 阳,.. (i恤� " t_�t� 钱 DNi帽� 。 .0嗣M 二臼 回 .0问、. • JIW3 凰" � 3虱/<1.. '唱,. .. 吧。 t. le 阳"即伽酬.'100S闹剧即 ICl刷LV_ • '. 1,�, ._ 也恤 毡 , 咱 ' �r. " ....._........ ,...................... , 协.to:组=nq伽>&Ct\Ø 1%品&1,缸, :i7Ð也..,u 1r," I Inr.. Ür_..uOtV川Id… I ." �刷如 飞'啪 UJ‘鸭明、.-u,I._.�.,-U.O_.:t ..l.!U在U..., ,:H�".•.t_tI‘.I.时...,'t俨n- ‘町恤',,.'.,.._. t"l�tt.� . Þ1.:..酶_,(.,J..�• �...'_'.�( t"",-:: .��w吨'但 lnL61 U卧.a.U&I晴tt1t;ty .t_t.坦白凰 "‘"睛t� k'哩L且hBXt:lI'7 lnf.1 r�\....1:向, -- �-\t.,y ,. ‘f' ""'1'但 e� .tr俨, .Yll�J恤�.� 'J\. 111幽1 VR啊1", CØ\llI'�.'唱制.1.,. ,11ft口"ul ,t�1也.1"-'t.4且l.AlA>>.ta-..__;1且ld.bc提…lιι.Cul O..A.!�,. tJ ""bJ.I",. '咱 • 。同…-四- 羹秘费歹唰a己佛!l;l画 其他说明: 文 中实例 基本都不依赖实际共体的硬件 , 可 以在任何厂家任 何 系 列 的 FP G AlCPLD F 综合使J+J(如Altera 等, 只 要资源充足 ) , 迹可 以利 用 S ynopos y公司的 工艺陀影射到 AS1 C, 完仓可 以飞作 软 IP Core 使用 。 • • V.l • …..…· 一.. 目u …... .... ....... • 一 一 •• .....… . .......-…......………·…一一一..一一一……一一一… Verilog HDL 语 言是一门标准的硬件设计语言, 由 于 具 有 简 单 、 在观和 高 效 的 特 点 , 已经被 绝大 多 数 的 IC 设计者 所采用 。 倒是在现有的 同 类 书 籍中 , 要 么只侧重Verilog HDL 谣言教学, 要 么 只 侧 重 ED A工 具应用 . 缺少大盘的 工 程实 例 讲 解, 应用性和实 践性不强。 该书的 出版正好 可 以填补这 个 空白。 本书内容安排 全书共 分 为 2 篇 1 2 章 , 具 体去排如l 下 。 基础知识 〈第}-7章) t / _ - .- - 一 - -' _. _ ..._ 1 概要介绍了Verllog HDl的特点、 l语言蜜素与寝达式、仔为级建模、结 4掏级建镇、语甸的综合、设计与验证t .1 以及代码优化技巧.引导:读者技术入 门. .‘- - 已经具备了Ve耐。9 HDL编理基础 的读者.可以跳过比部分. 画实佛的学习。 应用编程 实例 r(第8-12章〉 通过30多个实例. 宿廖渐逃跑 介绍了Verllog HDl在逻骗电蹈、存储 l i黯、敛亨通筒、戴字控制、 筒雪测蟹 t 1领域的应用饱理技术和级6. 这些实例类型辜..全部来自于实 践并且调试通过.融合了作者多牢的设 计经验.读者通过学习可以快速实现擎 一反三, 瘦高应用篇疆的能刀, 本书优势和特色 与 同 类 书 籍相 比 , 本书主要具备如 下 的一些优势和特色。 ( 1 ) 在讲述 Verilog HDL 语言科j书设 计的基础上, 系 统 、 深入地介绍 了 大部 分同类书 籍小很少 涉及的 Verilog HDL 语 占综什内 在。 ( 2 ) 本书实例 典型 j三寓, 30 多 个实例 涉熬了 逻 辑 电 路 、 持{请器 、 数 字通信、 数 字控制 等热门 领域, 技术性和实 践指 导 性 强。 .vn . .. • ( 3 ) 本书重点对 Verilog HD L 语言程序设 计 思路和 流程进行讲 解, 同 时穿插介绍许 多 设计经验 与注意事项 , 利于 读者理解和 巩固知识点 , 提高举一反三的能力。 ( 4 ) 光盘中包含了 丰富的 实例程序代码 , 读者 稍加 修 改 , 便 可应用于 自己的 工作 中 或 者 完 成 自己的课题 〈 毕业设计 ), 物 超所值。 本书读者对象 为 : 计算机硬件、 电子与通信工程等相关专业在 校大 学生:从 事 Verilog HDL 设计的研 发 人员。 本书主 要 由刘福奇、 刘波编 写 , 另 外, 唐清善、 邱宝良、 周克足、 刘斌、 李永怀、 刘伟捷、 李亚捷、 李宁字、 黄小欢、 严剑忠、 黄小宽、 徐春林、 谢正义、 郑贞平、 张小红、 李彦坦、 付军鹏、 张 广安、 王艳波、 金平等在 资料收集、 整理和 技术支持 方 面 做 了 大量的 • 工 作 , 在此一并向他们表示感谢! 由于 时间仓促, 再加之作者的水平有 限 , 书中 难免存在一些不足之处 , 欢迎广大 读者 批评和指正, 联 系方式: jsj@phei.com.cn。 • V1U. 目录 Y�ri199 Hp�L基础知识 第1 章 Verilog HDL语言概述…….......•• 2 1.1 HDL概念与发展历史.....................2 1.2 Verilog HDL语言特点.........…......... 3 1.3 Verilog HDL语言开发流程 …......... 9 1.4 Verilog HDL程 序的基本 结构……...............………..…….......…11 1.4. 1 模块_...._...................................….. 11 1.4.2 模块调用….. ……........... ….......….20 第2章 Verilog HDL语法基础 2.1 程序格式…........................….......•.•.22 2.2 注释 …...………………………………….22 2.3 间隔符……...............................……..22 2.4 数值…….. ...….. .….... .. 23 --..• .. ••. • • . • .. ....•..... 2.5 字符串……......……......……......………25 2.6 标识符………………………………………27 2.7 系统任务和函数…;E;二-tin---1年斗…28 2.8 编译指令…...•.•.…................…......... 34 2.9 数据类型……...............….......…........ 43 2.9.1 线网(Net)和支量( Variable)43 2.9.2 标量(Scal町)与失量 (Vector) ._......._......................…...47 2.9.3 线网(Net)数据 袅型…..…........48 2.9.4 变量( Variable)批据类型 "……53 2.9.5 数组(Amly)类型.... … ………..54 2.9.6 参敬…..…..….......…..…..................!5� 2.9.7 名字空间........…._..,.......….....……59 2.10 表达式.......…….......…..………·…..… 60 2.10.1 操作符…..….......….........….......…61 2.10.2 2.10.3 2.10.4 2.10.5 操作敏.......……..….......…·…...... 72 延远在达式…................'.... … … 76 表达式的位宽………………........ 77 有符号表达式…….......……........ 80 第3章 行为级建模 3.1 行为级建模的结构…......................82 • 3.1.1 过程块结构..................……......... '84_ 3. L.2 i,niti时过程块 ….......………·…....... 85 3.1.3 always过程块….......…..….......…. 87 3.2 语句块….......…...•.•.…..….......….......90 32.1 顺序语句块(begin-end)......... 91 3.2.2 并行语句块(fork才oin)…..…… 92 32.3 顺序块和并行块的混合使用….. 94 3.3 时间控制.........………........................97 3.3. L 延时控制…..…………........…·……… 98 3.3.2 边沿触发事件控制........…………. 99 3.3.3 电乎敏感事件控制(wait 语句 )....................................-..... 106 3.4 赋值i茜句.................…..............…"108 3.4.1 过程赋值语句….......….......……. 109 3 赋值语句....... ……-…"….........…114 3.4.3 连续赋位诗句和过程连续赋位 t吾句............................................. 1 1 9 3.5 分支谓勾.............,...........…........,..13 J 3.5川.1 if-e1s e条件分立语句.……..…….,川.... 3.5.2 cωase优 分支拉 制语t岳句…….….….….川…….…川..…….…….川.….…..… 136 3.6 循环;蛇宅制涓f句1)….川…..…. .…..卢….川…….川……….川….川…….川……….……..….川.….…...… .…….川……141 • JX. 3.6.1 forever 循坏语句…….... .......................…141 3.6.2 repω 循环语句.................................143 3.6.3 while循环语句 ……................…........145 3.6.4 岛r 循环语句....………..................… …'146 3.7 任务(task)和函数 (function)… … ..................….11 .........…....... 148 3.7.1 任务(姐妹) ..…....__............... ....148 3.7.2 函数(function) …..….......……'152 第4章 结构级建模 4. ) 摸块级建模….... ". ..….... ........••••••••.•.... 160 4.1. t 棋 块 的定义 ...._... … " …"… .. ..... .--:-u .. ..l60 4.1.2 模块的端口….....................……..161 4.1.3 模块的调用H……..................…............…"164 4.1.4 在棋块调用时对参数值的 是政…….............…_.............-.......-......…"170 4.2 门级建模..•.••. …...............…-… ……. 174 4.2.1 内置基本门组元,件 ….......…..…..174 4.2.2 用户自定义基本元件 (UDP)…................................…1 87 第5章 Verilog HDL语旬的综合 5.1 综合概述….. … … … …....... …........ 198 5.1.1 综合的概念..............…·…................198 5.t.2 数值集合与数据英型…....-.. ……200 5.1.3 储值单元的综合原则….. ….......201 5.2 连续赋值语旬的综合…….......…..201 5.3 过程赋值语旬的综合. ..…202 •••t••.•••••• 5.3.1 阻塞赋佳语句………… .川 …… ...….…….………....……. .…….川.…..202倪 5.3.2 非阻塞赋佳语句…H .…川.…….…..…….. .…..…... …….… …..…...20ω3 5.4 逻辘运算符的综合…….……….马 5.5 享$算 术 运算符的综 合 .…….……….…川 .u……….…….…..川..…….….……..........205 5.5.1 元符号运算命...................�....-..........�-.....205 55.2 有符号运算…....._......………… ….206 ·x. • 5.5.3 进位与位宽… … ……….......…… 206 5.6 关系运算符的综合…..…...'........……..207 5.7 移位( shifi)运算符综合….........208 5.8 位选择综合…..…..…..… ….........…"209 5.9 条件表达式的综合…..............…........…211 5.10 always语句的综合……......'.....………212 5.11 证语句的综合… …...... … … …........215 5.12 case语句的综合….. …....... ….......2 16 5.12.1 从 cωe 语句综合出锁存器 … 217 5.四.2 case z和casex语句的综合…. 221 5.12.3 并行的case语句…….. … ……. 223 5.12.4 条件表达式使用常量的case 4岳句.............…............................…........… 225 5. 13 锁存器的综合..............'........... ….227 5.14 循环语句的综合…….......….........230 5.14.1 静态循环的综合….................... 23'1 5.14.2 非静态稿坏的综合"…..........… 233 5.15 阻塞和非阻塞赋值................…….川.234 5.1凶6 函数的综合.…….叫川……..…….……"…….,…….川.…….川.…….2刀37 5.1口7 5丘引.1山8 任务的综综、合…川 …….….…川川 …,.……….…..…吧U.忖… . 叫川 ‘ …户 雪 ….. 川..川.……. 2约3 8 .…….川 .. 任 意1 E值/高陋的综合................. …239 第6章 设计验证 6.1 后综合设计验证...............….........243 6.1.1 基于仿真的验证…........… … … 244 6.1.2 形式化验证…·…. .… 244 .…"川........ 6.2 而向验证的编码风格…·……:........244 6.2.1 功能丘确性…..气.....................… 245 6.2.2 时序JE确性....………........ . .. …… 248 6.3 定时验证….,… … ….........….......…249 6.4 1Ft序分析基础…........... 250 .................. t 6.4.1 周期与最大时钟频率….--......…. 250 6 6.4.3 时 钟保持时 间…·…….......………..25 I 6.4.4 时钟输出延时...........….......... …252 6.4.5 引脚到引脚足时........ ……..…….252 6.5 定时验证的系统任务...................252 第7章 Verilog HDL代码优化技巧 7.1 资源共享…....... …...........................….........254 7.2 公共子表达式……...............................2S7 7.3 代码调整….. …… …............... ............. ....258 7.4 公因子….................. … ................... ...…..260 7.5 触发器和锁存键的优化......... .......261 7.6 代码大小…..……..……… … …….......263 7.7 算术表达式树高度优化…..….......264 7.8 运算符强度缩减…..….......... ...............…..266 V�ril()g,;HDL应用编程实例 第8章 组合电路设计实iJq 8.1 恭本 门电路…….................….......……….268 8.2 组合门电路 ……...............……… ….271 8.3 三态门电路 …................…........................ ..273 8.4 双向门电路 …..................….............….274 8.5 数据选择器与数据分配器 ..........276 8.5.1歇据选择器…..….......…..............…......276 8.5.2 数据分配器….......…..................……..….278 8.6 数据比较器…·…................. …… ….280 8.7 各种加法器〈诫法器〉设计 ……282 8.7.1 }行波进位加法器….........…..工......282 8.7.2 进位链加法器....…........IO""....…· … …283 8.7.3 跳跃进位加法路"…..............….........286 8.8 常用乘法器设计…….......……....... 289 8.8.1 基本来法器…...……............................…"289 8.8.2 时序乘法器.........................…....291 8.8.3 阵列乘法器........……..……..…· …293 8.9 伽罗华域GF(q)乘法器设计........297 8.9.1 应用背景.................…..…...........298 8.9.2 理论界法….............….......…..…..……298 8.9.3 基于弱对偶基的有限战比特 并行来法昂建棍....….......….......30 I 8.9.4 �毒对偶基有限域乘法器程序 4昆明.......……..........……................ 304 8.10 常用除法捺设 计… … …........ ....3 ...• 07 8.10.1 二进制恢复除法器…...,.......... �()� 8.10.2 时序除法器设计…...............…. 310 8.11 本营小结……...•...….................….314 第9 章 时序电路设计实例 9.L D触发器设计......•..•......…….........315 9.2 四种计数器设计....•......…… … … … …316 9.2.1 通用二过制计敷器..o4.....…........ 316 9.2.2 Gray码计钦器…·叩.o404 317 ••••••••••••••• 9.2.3 Johnson计数器 …….......…· … … 319 9.2.4 可预直加减计数器的 设计....... 320 9.3 两种分扳揣设计…….......…...........322 9.3.1 Verilog HDL分频器…..…......... 322 9.3.2 PLL分频器 ………..... .. ……........ 324 94 . 两种移位寄存器设计…·……………32 9 9.4.1 通用移位寄存�……..…...;......... 330 9.4.2 桶形移位寄存器….._............…........ 330 9.5本市小纣1......................... … … …..…..332 第10章 存储器电路设计实例 10.1 片内ROM 的Verilog HDL m烛'·…-…........o4.… …............……......333 • Xl • • lfM.理廖设计实伊麟讲 10.2 片内ROM的LPM应用…·…….334 10.3 片上SRAM 的Verilog HDL 这模 ….............. …..... 340 •••.••.••....• .••.• 10.4 片上SRAM的LPM建模.........342 10.5 片外SRAM的LPM建模......... 347 10.5.1 IS61LV25616芯片介绍..........347 10.5.2 IS61LV25616控制模块.......…350 10.5.3 1S61LV25616控制器的测试 棋块·…..…………....................….352 10.5.4 IS61LV25616控制器的仿真 …354 10.6 同步FIFO的Verilog HDL 建模............... …......................….355 10.7 同步FIFO的LPM述模.........…360 10.8 异步FlFO的Verilog HDL 设计 …......................…..….......….364 10.8.1 FlFO "空,. I ..满"检测…….364 10.8.2 FlFO �:英块结构……...............…366 10.8.3 FlFO报代,码 说明…..……..……367 10.8.4 异步FIFO 的相关问题........…372 10.9 本章小结..................................... ��:J 第11章 数字通信与控制设计实例 11.1 时序状态机的设计..................…374 门.1.1 有限状态机(FSM)的 分类..........….................…·……..375 11.12 有眠状态机常用的描述、 开发 万‘ 法 3吗 ,『 JE 门.1.3 基于状急转移困(STG)的 设计…·…………………................376 11.1.4 基于算法 状态机(ASM) 围的设计…….......…….........……384 11.2 伪随机 序列应用设计……….......•3 88 11.2.1 应用背景……….......……......…...388 . • Xll · 11.2.2 理论知识….......…._......….......... 390 11.2.3 PN序列应用 实例…·…............ 392 11.2.4 程序说明 ….........………...�...... 393 11.3 积分梳状滤波辑 (CIC) 设计…….., .• .....…................…·……..3 95 11.3.1 应用背景........……-….........….. 395 L1.3.2 理论界法…..........….......... …… 396 11.3.3 三级αc抽取滤玻嚣建模 .... 398 11.3.4 程序说明…·….......…................. 401 11.4 CORDIC 数字计算机的设计…..402 11.4.1 应用背景…·…………......…….. 403 U.4.2 理论算法….......…..…..…..…….. 404 11.4.3 用 CORDIC计算正弦值、 命弦位实伽iU在模…..……......... 414 l1.4.4 程序说明…................….......…. 416 11.5 UART收发器设计实例 ...,••••.….. 419 U.5.1 UART界面介绍... .......... ....•... 419 11.5.2 UART传输时序…….. ……·…'420 1l.5.3 UART分频器 ............… ·….........• 421 11.5.4 UART发送模块 … …..….......... 422 11.5.5 UART接收棋块….......…........ 428 11.5.6 UART 的硬件 测试 ……........… 432 11.6 llC Master控制器设计 实例 .......................…......…........… 43 4 11.6.1 eC总线协议介绍…................ 434 11.6.2 AT24C02介绍.................……. 434 川.63 i2C M臼ter控制器代码 设计… 437 11.6.4 eC Master拉佬IJ器硬件 测试…444 J 1.7 SPI Master税制器设计 实例….......….................….......…"446 11.7.1 SPl界面介绍.........…·… ……. 446 11.7.2 SPI分频棋块........... ………….. 447 11.7.3 SPl主端发送数据部分…·…… 449 11.7.4 SPl接收数据部分…..…"�"""45S 1 1 . 8 曼彻斯特编码器、 译码器设计 实例 …..…….........….......…..…...... 460 11.8.1 曼彻斯特码介绍_..._.e".…….........46"0 11.8.2 曼彻斯特玛编码器…..……......460 11.8.3 曼彻斯特译码器…......…..….......4ω 11.9 RS编码器、 译码器设计实例.... 465 11.9. 1 RS编码器的设计................….465 11.9.2 RS{204, 188)泽码器的设计....472 11.10 本章小结…................…..…........ 499 第12章 鼓字频率测量设计实例…….. 500 12.1 频率测量的常用方法 …..………. 5∞ 12.2 直接测频法…..…..........4..........….502 12.2.1闸门产生模块….......……....... … 502 口.2.2 计数模块…........…..…………… 504 12.3 周期测频法…….......….........……..507 12.3,) 周期 计数祺块…..…..….. ……… 508 123.2 除法运算棋块…..… …………寸09 12.4 等精度测频法…..…·…….........…… 511 ... 12.4.1 预设闸门模块....•..•......• .........51 J 12.4.2 实际闸门棋块..-.:. … … …… …'5口 12.4.3 计如莫块.............….................. 514 12.4.4 频率 计 算棋块…..…..………..唱. 5t6 口.5 本章小结……..………..……..........5 ) 8 • • . JCIIl • I Ve耐。gHDL应用程序设计实例精讲 I 111 • ‘· φ第1章 Verilog HD L语言概述 φ第2章 Ve rilog HD L语法基础 φ第3章 行为级建模 令第4 4如第5章 结何级建模 /俨、 Verilog HDL 语甸的综合 φ第6章 设计验证 φ第7童 Ve rilog HD L代码优化技巧 • 第 Verilog HDL语言概述 本章 将,筒单介绍 Verilog HDL 语育的特点、 开发 流程, 以及 Verilog 程序的 基本 结 构 。 通过本章学习 , 读者将对Verilog HDL 语言有一 个入门性的 了 解和 认 识 。 1.1 HDL概念与发展历史 1. HDL 概念 硬件描述语言 ( Hardware Description Language ) 是硬件 设计'人员和 ED A < Electronic Design Automation) 工 具之 间 的 界面, 它 主要 用 于从算法级 、 门级 到开 关级 的 多 种 抽 象 设 计 层次 的 数 字系统建模。 被 建 模 的 数 字系统对象既可 以是简 单 的 门, 也 可 以 是完整 的 数 字 电子系统 。 硬件描述谣言 的主要 功能是 编写设计文件 , 建 立电子系统行为级 的仿真模型 , 然后利 用 尚性能的 计算机对用 Veri ol g HDL 或 VHDL 建模 的 复杂数 字逻辑进行仿 真 , 之 后 再对它进行自动 综合以 生成符合要 求 且在电路结 构上可 以实现的数字逻辑间表 (Netlist) , 然后 根据网表和适合某种工艺的器件自动 生成具体电路 , 最后 生成该工艺条件 下具体电路的 延时模型。 仿 真,验证无误 后 用 于制 造AS CI ( Application Speci fci lntegrated Circuit, 专用集成 电路 〉芯片或写入FP G A ( 现 场可 编程逻辑:1' J阵列 〉 和 CPLD ( 复杂可 编和逻辑器件 〉中 。 在 ED A领域, 一般把 用 HDL 语育 建立的 数 字系统模堪称为 软核 ( 80位Core ), 把 用 HDL 建模和 综合 后 生 成的网表称 为 同核 ( Hard Core )。 重复利用这均模块可以缩短开发周 期, 提 高产品开发成功 率, 并提高设计放率。 2. 为什么要使用HDL 目前电子设计的 规 模越来越大 , 复杂!变越来越高。 20 惜纪90年代末, 普通设 计 的 规 模 已经达到百万 门 的 数 垦级 , 并且有继续增加 的 趋势。 集成度达千万儿晶体管以l二的芯片 已经屡见不鲜, 为 使如此 复杂的 芯片变得易f被 人脑理 解, 很有必要用一种 高级 谣言 来 表 第 1 章 V町蜘g 达其功 能 , 隐藏 其 具 体实现的 细 节。 这也就是在大系统程序编写 中 高级程序设计语言取代 汇编语言的 原因 。 同样, 在 芯片 设计中 也不得不使用硬件描述 语 言 , 而具体实现交 出 逻辑 综合工 具 完 成 。 另 外, 电子领域的 竞争越 来越 激烈, 刚刚涉入 电子市场 的 厂商 要面对 巨大的 压力: 提 高逻辑设计的效率# 降低设计成本, 更重要 的 是 缩短设计周期。 而 多 方位 的 仿 真 可 以 在 设 计 完成之前 检测 到 其 错误, 减少设计重复的次数。 因此, 有 效 的 HDL 语言和计算机仿真 系统 布 将 错误 的 数目减少到域低 限度方面起到不可 估量 的作用 , 并使第一次投片便 能成功 实现 芯片的功能成为可能。 使用硬件描述 语言将使 检测 各 种 设计方案 变 成一种 很 容 易、 很 方便 的 事情 , 因为 对方 案 的 修改 只 需要修改 HDL 程序就行 了 , 这比修改 原理 图 要 容 易得 多 。 正是基 于 七 面这几点, 传统的用 原理 图 设计 电路 的方法正在逐渐被取代 , 硬件 描 述 语 言正被 人们 广泛接受。 3. HDL 的发展历史 HDL 最 早是 由 lverson公司 于 1962 年 提 出 的 , 这今为 止 已经 出 现 了 多种 HDL。 其1卡, 绝大 多 数 都 是 专有产品, 如 Silvar-lisco公司 的 HHDL、 Zycad公司 的 ISP , Gateway Design Automation公司 的 Verilog 以及 Mentor Graphics公司 的 BLM 等 。 还有一些高等 院校以及 科研 单位也开 发 了 数百种 产品, 比较著名 的包括 AHPL、 M IMOLA 和 SCHOLA R 等。 另 外, 一些大 型 的 计 算 机制 造商 也 都有 其 内 部使用 的 各 自 的 设 计 语 言 , 如 美国德克萨斯仪器 公司 的 ηHDL。 有 些 HDL 是从一些 已 有 的 软件程序设计语言发 展而 来 的 , 如 Silicon Compiler公司 的 M 和 Gateway公司 的 Verilog HDL 是 从 C语言发 展而 来 的 , 而 BLM 、 M IMOLA 和 SCHOLA R 是 以 PASCA L 语言 为 基础 的 。 1.2 Verilog HDL语言特点 1. Verilog HDL 简介 Verilog HDL 语言是 -1'J标准硬件设计语言 , 它适合于电 子 系统设计的所有阶段。 由 f它 容 易被机器和 人工 阅 读, 因此它支持硬件 设 计 的 开 发 、 验证、 综合反测 试 以 戊 硬件设 计数据的交 流, 便 于维护、 修改和最终硬件电路的 获得。 VeriJog HDL 语言具有简单、 直 观和 高效的特 点。 在 各种 设 计 工 具 〈 如 仿真验证、 时序 分析、 测 试 分析和 综合 〉 里 面 , 它 采用标准的文本格式, 具 有 多层次的抽象。 由于具 街 以上这些特 点 , Verilog HDL 语 言已 经被 绝大 多 数 的 r c 设计者所 采 用 。 Verilog HDL 语言包含一套 丰富的 内 建元 件 : 逻辑 t'J元 件 、 用 户 臼定 义 元 竹、 开 关 级 元件 和 连线逻辑元件。 它 也支持 设 备寻|脚到 引脚延 时 和 时 序 检测 。 Verilog HDL 通过 \3\ �刽翩勘刚- 翩雹凛耐实伊跚诩 定 义 两 种 数 据 类 型 〈 线 网 型和 寄 存器 型 〉 体现了混合的 抽 象 层 次 。 在 VeriJog HDL 中 有 两 种 基 本 语句 : 连续赋值 语 句 , 在此表达式 中 寄 荐器 和 线例都可 以连续驱动线闷, 实现 基 本 的 结 构 化 建 模 : 过 程 赋值 语 句 , 在此表达式巾 寄 存 器 和 线 网 都将运 算 结 果将入 寄 存 器 , 实现基 本 的 行 为 建 模 。 一个设计通常包含许 多 模 块 , 每一模块都有一 个 输 入/输出接 口 和 该模块相应的 功 能 描 述 。 而 该功能描述 既 可 以 采 用 结 构 化 的描 述 方式也 可 以 采 用 行 为 化的 描 述 方式, 或者'二 者 的 结 合。这些模块都 被 加 工到 一 定 的 抽 象级 别 , 然后通过线 网互连。 Verilog HDL 语言可 以通过编程 语言接 口 程 序 ( Pro gramming Language lnterface , 简称 PLl )和 Verilog 接 口 程 序 ( Verilog Procedural Interface, 简 称 VPI) 来实现扩展。 PLINPI 是一个 程J'f绽, 边过这些接 口 程 序 , 外部函 数 可 以 访问包含在 Verilog HDL 描述 中 的信息, 而 且 便 于 和 仿 真 工具动态 遇倍。 PLI/VPl 的应用 具 体包括连接 Verilog HDL 仿 真器和其他 仿真器或者 CAD 系统, 以 及对调试任务 、 延 |可计算器和注 释 客户 化。 给 予 Veri log HDL 语 育影响最为 深 刻 的 语 言 是 H ILO-2 , 它是 由英国的 Brunel 大 学 开 发的一门 语言 。 HU.O-2 语 言 是 该 大 学 为 英国国防部开发测 试激励系统 而 产生的 。 HlLO-2 成功结 合 了 l' J级 和 寄 存 苦苦传 输 级 抽 象 , 并 且 支持 仿 真 验证、 时序 分析、 错误仿 真 和 测 试 激励。 Verilog HDL 语 言最初是于 1 983年由 Gateway Design Automation公司为 其模拟器产 品开发的硬件述 模 语 言 , 当 时它只 是一种 专用 语言。 由于 GDA公司的模拟 器 、 仿 真 是基产 品的广泛使用 , Verilog HDL 作 为 一 种 材于 使 用 且 实 用 的硬件描述 语言逐渐为 众 多 设计 者 所 攘受。 1 989年, GDA公司被 Cadence公司并购。 1 990年, Cadence 公司正 式 发 布 Verilog HDL 语言, 并 成 立 了 Open Veri log lntemationaJ ( OV I) 这一促进 Verilog 发展的 国际 性 组织。 1992年, OVl 开 始 致力于 搅广 Verilog OVl 标准成为 lEEE 标准, 并 于 1 995 年使 Verilog HDL 语 占成 为 lEEE 标准, 称为 IEEE Std 1 364 1- 995o 在;标准化 完 成 之后 , 1 364 L 作组开始从 1ft界 范目的 1 364 用 户 那里寻找反馈 信息以 增强标准并 做相应修 订 。 经过 5年的努力, 即 在 2001 年,一 个 更加 完 静的 Verilog HDL 标准, 即 JEEE Std 1 364-200I 终于诞生了 。 JEEE Std 1 364-2001 成就包括: • 巩|刮 了 lEEE S 时L 364- 1 995 标准: • Verilog 生成语句: • 多维阵列: • 烟强 Verilog 文 件I/O� · 标准化 Veri1 0g 配责 : · 强化时序表达; • 强化 VPI科.序。 Verilog HDL 语言仍然 是 一 门 不 断发展的语言, 有关 其最新的发展动 态 , 读者可 以 到 /4/ 第 1 章 Ve闹。9 HDL,:语 三 lntemet 上浏览。 以 下是一 些相 关 的 网址简介: • http://comp.lang.verilog, 这是一个关于Verilog 的 新闻组 网站。 这个新阅组不时有 一些关于建校或者 Verilog 工具 的 提示。 • h忧p://comp .ωd .cadence , 这 也是一 个 新闻组 网站 , 它 存关 于 Verilog- XL 和 来自 Cadence Design Systems, lnc .公司 的一些工只 的 新闻发布 . • http://comp.cad.syn白esis- 这是一个新闻组网站, 有关于 VHDL 和 Verilog综介飞 具 的 新闻发布 。 此 外, 大 多 数 的 新闻组 网站部会 发 布 一 个关 于 Verilog 的 FA Q (Frequently Asked Questions ) , 这个 文 档会经常更新 , 而 且 列 山了 当 前关 于 Verilog 的可利阔 的 工 具 和 出 版 物。 2. VHDL 简介 VHDL 最初只是一个文 档格式 , 用 于进行项目之间 交 流, 它 源 于 L98 1 年美国国防部 的 VHSIC计划。 1 987 年 , 由 IEEE (Insütute of Electrical and Electronics Engineers ) 将 VHDL 制 定 为标准。 参考手册 为 lEEE VHDL 语言参考手册 标准草案1 076fB 版 , 于 1 987年 被批 准, 称 为 应EE 1 076- L987。 应 当注意, 起初 VHDL义是作 为 系统规范的一个标准 , 而不是 为 设计 而制 定 的 。 第二 个 版 本 是在 1 993 年 制 定 的 , 称为VHDL-93J 增加了 一 些新 的 命令 和 属 性。 虽然 有HYHDL 是一个 4 亿美元的 错误" 这 样 的 说法, fW. VHDL毕竟是 1 995 年 以 前 唯一制 定 为标准的硬件描述 语 言 , 这是它不争 的 事实和优势:但 同 时它确实 比较麻烦, 而 且 其综合库至今也 没有标 准 化 , 不 能 很好地描 述 门 级 ( Gate Level ) 和 晶体管开 关 级 (Transistor Leve1 ) 电路, 也不具有模拟设 计 的 捎述 能 力, 而 且i再育本身也 不 支持 时 芋j 信息。 因此 , 尽管得到 了 多 方的 支持 , VHDL 在 �Jl!件描述悟言领域仍然没能 占据主 要地位。 H前 的看法是, 对于特大 烈 的 系统级数乎也路 设 计 , VHDL足较为 合 适 的 。 实质上, 存底层 的 VHDL 设 计 环境走出Verilog HDL 描述 的 器 件库支持 的 。 闲此 , 它 们之间的 E 操作性 十分键要:0 目前, Verilog 和 VDHL 的两个 国 际纠织 OVl 、 VI íE{j:筹划 这一 工作 , 准备成 立专 门 的 工作组来协调 VHDL 和 Verilog HDL 语言的 丘 操作性。 QY l 也 支持 不需要翻 译 , 由VHDL 到 Verilog 的 向 由 表达。 Verilog HDL、 VHDL 和 C这 三种 语 育部属 于高级 混序 谓言 , 易r为 人们所阅 读和 理 解。 前 两 种 语言是日前是常 用 的硬件 捎淫 语 言, 同 时 也 都是 JEEE 标 准 化 的 HDL 语 言 , 它 们 被广泛应 用 于 数 字 电 路 系统 涩辑 设 计领域, 最终Ff;际 都是要 实 现破!件也路. 而 C 语 言 可 以 说 是 日前世界 上 被最广泛采 闷 的 软件 语 言 , 它被广泛应用 在各个不同 的 领域 , 已 经 发 展 山 足够 可 掘 的 编 译环境, 而 且 自 身 语法完备。 下面具体 介 绍 这 飞种 谣 言 的 区 别 与 联 系。 \5\ 随翩陶· 刷. 应酶脐部十实倒制 3. Ve时109 HDL与C语言比较 Verilog HDL 源 于C, 两者的语法 极为相似, 但是 Verilog HDL 毕竟是一种硬 竹描述 谓 言 , 要 受 到 具体硬件电路 的 诸 多 限 制 , 它们的 区 别 如下。 ( 1 ) 在 Verilog HDL 中不能使用 C语言中 很 抽象的 表示语法, 如 法 代表示法 、 指针 ( C 语言最 具特 点 的 语法 〉 、 不确定 的循环及动态卢明等等。 ( 2 ) C语言的 理 念是一行一行 执行 下去 , J顺序的语法 : 而 Verilog HDL 描述的是 破件, 可 以 在 向一时 间 内 有 很 多硬件电路一起 并 行动作 , 这两 者之 间 有冲突 , 糟糕的 是 Verilog 仿 真 然也 是 顺序 执行的 软件, 在时序关系 的处理 上 , 会 有思考上的 死角。 ( 3 ) C 语 育的输入/输出 面数 丰富, 而 Verilog HDL 能 用 的 输入/输 出 函数 很 少 , 在程序 修改过程巾会 遇到输入/输 山的 闲难。 (4 ) C语言无时间延迟指定。 (5) C语 言 中 函 数 的 调 用 是唯一的 , 每一个 都 是相 同 的 , 可 以 无限制调用 。 而 Verilog HDL 对模块的每一次调用都必须 赋 予一个不同的 另IJ名 , 虽 然 调 用 的 是!司一模块 , 倒不 同的 别 名代 表 不 同的模块, 即 生 成 了 新 的 硬件电路模块。 肉此 Verilog HDL 中 模块的 调用次数 受硬件也路 资源 的 限 制 , 不能无限制调用 。 这一点 与C 谓育仨较 大区 别 。 ( 6 ) 与 C 谣言相比, Veri log HDL 描述语法较 死, 限制 很 多 , 能用的 判断叙述有 限 。 ( 7 ) 勺C语言相比, Verilog HDL 仿 真 速度 馁, f主错工只茬, 错误信息不完整 。 ( 8 ) Veri log HDL 提供程 序 界 面的仿真工只软件, 通常'都是 价格昂此, 而且可靠性不明确。 ( 9 ) VeriJog HDL 中 的 延时语句只能用于仿 真 , 不能被 综合士具 所 综合 。 ( 1 0 ) 表 l - l 所示为常用 C 活言 与 Ve时 log HDL 中 相 对应 的 关键字 或控制描 述 。 sob-function i仁then-c1sc Case {. ) For Wbile Br回k defmc Int p由uf .,且' •- C mod时e. funClion. task ii二thcn-else case begin. end for while disablc ddine . lßt mom•tor• dísplay Verilog ( 1 1 ) 表 1 -2 所示为 C i苔,可与 Veri 1 0g HDL 对应的运�符。 / 6/ 第 1 章 V创Iog HDL 表 1 -2 C语言与Verilog HDL运算符对照衰 • J如 C • + • % && 11 〉 〈 弛rik略 • + . % && 11 〉 〈 • 功 能 乘 除 )JU 碱 取余 逻刺�I� 逻钊l-; ��tl.现 人1'' IJ、i >= >:: kr等1 <= <- 小J-悍f """ 一 吗j !- f= -1';哼j二 由 - 战位作 & & 极价与 披{命战 A A 报位异成 ...1、 J、 怯位拧成非 》 》 迦纳,.(1将 《 ?.. •• \\û\\ ..., \\//\\/,r\' 《U • 。. 飞I((ì\1(("'J11门 逻辑A移 条件.ikff. , . .‘ . �• •, 4. Verilog HDL与 VHDL比较 尽管 VeriJog HDL 与 VHDL 两种 诺言 都在努力争取 能 捎述 所 有的硬件层次, 但是任何 事情都不是完美的 , 它们 捎述 科层的能 力各有下秋o Verilog HDL 千年f 捎述;更低 层设计, 包指 结构级 ( 门 级和 晶体管开关级 〉 和1物 王电级c*器件 、 平 面 规划): r市 VHDL 拌于描述一 些 商店的 设计, 包括系统级 〈 算法 、 数据通路、 控制〉 和行为级 ( 奇存器传输等 〉。 VHDL 和 Verilog 对 比就像 C和汇编刘比。 VHDL的 语法描述 吏规范, 高级诺言特性 较 多 , 适 合千大型的政件 逻辑设计。 Verilog 则豆接近硬件 , i吾法史只活, 适什于激励、 仿 县、 硬件 也模。 VHDL J工有很多 高级 谣言的特性: 数据类 1咀应义 、 常 最 定 义 、 的数 和过但比义。 以k 这些定 义都可集中 写在 一个 PA CKA GE小 (炎似 C的..H 文 件 ) . 任何 个 子模块中只rlti JJO 句 话引剧该 PA CKA GE np可 . 从总体 设 计t这些特性使得模块化设计和 TOP -DOWN设 计 可 以 比较方便地进 行 。 从局 部 设 计七,吁以很方便地写出 可 读性很强的状态机约构。 VHDL \7\ 刀:再向H队 应用程廖酣实伊j精制 是正向逻辑 设 计 的必然趋势, 这方面 Verilog 吁Î 定 是 比 不过的 。 现在已经有专门 的 VHDL 的 开 发环境, 如 SUMM1T 的 Vîsual VHDLø你 可 以画状态 机 、 流程图、 原理图, 由 SUMMlT 自动生成 VHDLø Verilog 语法比 VHDL更灵活。 从谱法核心仨 Verilog 完全是一种事 件触次 的模式 。 它 的描述 能力实际是超过f硬 件能实现的范 围 。 比如 Verilog 语法可 以很 容 易 的 描述一个 多 时钟 的触发 器 。 Verilog 非常适合于写激励和器件建模 , 这些℃ 作很难用 VHDL来 完成。 目前所有的半导体厂家 的 器件j辈 都 是 用 Verilog 来 描述 的 。 SlNG O FF 的平台也是基于 Verilog 的 。 VHDL 的新标准里 一直试图加入一些这方面的特性, 但是很 不成功 。 日前 EDA 设 计 以综合为界, 综 合 前 的 设 计 用 VHDL , 综合 出 的间表就是 Verilog 的 {o 布 局 布 线 , I时延提取 , 带o-t仿真, 测 试 设 计 都是基于 Verilog。 和 Verilog 相 关 的 步 骤虽 多 , 但是现在 的 设 计方法是在 VHDL 设 计阶段做较 多 约束, 从综合开始就是机器自 己去运行了。 日前 , 在关国、 H本和、IE洲大 多 数 的工和.师在使用 Verilog HDL , 而在欧洲 VHDL 的 用户要 多 于 Ve时log HDL, 这可 能与欧洲严讳 的 作风有关, 因为 VHDL 是一种语法 比较严 格 的语th 表 1 -3 所示 为 对两种 HDL语言 所 作 比较 的一个简单汇总 。 表 1-3 VHDL与Verilog HDL比较 开在J飞 标准 情?了J.!.刷1 功能 VHDL 美国唯Ji 11写在E1076 (1987. 1993) [1 P部由1.A曲 l飞 lf飞 斤气\•|, 、·、 r J级币j.tlVITAL +先型. �.Jò�1111 �.也帧 , V阳ilog HDL GOA公司 四l:.EI3b4 (1995) C •, ,r' "'ú(r-\-. I'f 拍电侧'1也梅01自�!ir毕PLI. '轩 内边的l' J级棋也 +表示优 VHDL VèriJoa HDL = - 地i1" 1�J个义1'1只能旬 个实体( Enlil)' ) 精i制在粮代码的响Ii! + 放据交咱 世汁,]i川 i'r多白4|;农1111户定义的必抓挠哑, 严临失 险制央J因而巾, 他J-盹1'1-也缺: '目检:ï!f(吁政岐111 rn般比坡陈凯). 功J tt 剧提明险茧: Jtl户尤i1.定义敬1�� 中 11\铅i尖 提咆 Itl Pllckagc l挺儿?两散、 H挝、英I�Hllffl ft (Componenl) t确姐和l.l.:.t再必却lfr问 肉, 叫他用 include Module + 协学fl l'劫"户, ,..J一也附自�种也陆Ih� )1.惊l 8aekward 在他tl向JtJ工Jl'I' �nJ以使111 SDF AnnOlDlion) n�容易i常.握. 编i手嚣的Direclive ,.. ,ftl PLI会地刷I!J.边�N 本身就立忡SDF "'" =< 与J{{血咐,丁的H� ftlfj Jù$t� forcl毡n u 白Verilog :fU快rilog杭('1 J Ul tl f'E1IJ PLI L一 / 8/ 第 1 章 Ve时问 HDL 唱 唱丰' 『‘•』�ι.. 1 ' 飞 • ,• 库 低}二结构 大哥'-设计能力 操作符 参烛化隅型 过在:和任务 可浊性 结构虫复 测试4L台 、- 2• 、-� F咽 气 • I a V8DL 、I � 一回 d .、 1• • • 续衰 电 r飞 4 ' 且, 、阳ilog HDL r r . a】 +表示优 f 'VHDL V旨诅嗨 HDL 存储偏i罪过的 Enlity、 Archileclure 、 Package 没{f悍的概念 刷 ConfiguralÎon 没有门级原型 ( Primiùve): 闸 V叮AL i7f;'r f J级j鼠哥1. 采用 UDP 和 目肘dI旨 +γ 来定义l鼠型 对原型建棋 Package、 Configuraùoo、 G 、 �eratc Gc:neric 无 没 有缩耐运 算 符 4¥缩硕运贸.衍 { 卸1& ) 中+ -r 宽度、 姐.iß等 '应J豆、 锺忠等 - - 允许Jt�立l 阳训j刮 尤 T 烦琐, 更像句子 简峰, 熟恶 C 的 人 冉戏 + 使 用 G te enern 尤 + 英属 (Generic) t� {jJfl . configumtion iä 义{中讪问央似硬iH放竹 ? 句很有m 1 .3 Verilog HDL语言开发流程 1 . 关于 自顶向下的系统设计方法 传统的电路设计方法都是 向 底 向 上 ( Bonom-Up ) 的, 即首先确定可用的元器件, 然后根 据这些器件进行逻辑 设计, 完成各模块后地行连接, 最后形成系统。 基 J': EDA 技术的所谓 向 顶向下 C Top-Dowo ) 的 设计'方法正好相反, 其基本步骤就是采用可完全独立于 问 标部件芯片 物理结构的硬 件描述 语言 , 如 Verilog HDL, 在系统的裴本功能成行为级 仁对设计的产品进行 描述 和 定 义 , 结合 多层次的仿n.技术, 在确保设计的可行性与 1日角性的前提下, 完成功 能确 认。 然后利用 EDA 工具的逻辑综合功能, 把功能描述转换成某 -共体 日标芯片的网表文件, 输U\给该器件厂商 的布局布线适 配器, 进行逻辑映射及布局布线, r耳利用产生的仿真文件进 行包括功能和时序的验证, 以确保实际系统的性能。 白 顶 向下设 计方法的优磁性表现在: ( 1 ) 山 于 顶层 的功 能 描述 可 以完全独立F 问 标继件的纺构 , ,(1: 设 计的段初阶段, 设 计 人员 可以不受芯片结构的约 束, 集中精力对产品进行最适阳市场丙求的设计, 从而应免了 传统 设 计方法中 的 再 设 计风除 , 缩短 了 产 品 的 l: 市 周 期 。 (2) 设计成果的再利m仰到{末,证。 就这方面|而言, 单片机系统的设计成果难 以得剑丙利用。 现代屯子应用系统以及 电 f产品的开发与牛.产.tE (aîJ模块化方向发 展, 或者说|句软硬 恢组合的方 向发 展。 对于以往成功 的 设 计成果稍做修改、 组合就能投入商利 川 , 从而产生全新的必派生的 设 计樵块, 同时正可以以一种 lP ( lnteUectual Property , 知 识产权〉 极的方式进行有·档。 ( 3 ) 由 于采 用 的 是结构化的 开发 手段, - �工1. -F: 系统基本功能结构 衔,如j确 认 . 即 叮实现 多 人 多 任 务 的 并 行 工 作 方式 , 使系统的 设 计'刷模和效率大 幅皮提肉。 \9\ V \drt型|I!I霉IJ, 事设计实伊到麟 ( 4 ) 在选择实现系 统的 目 标 器件 的 类 型 、 规模和硬 件结构等方面具有更 大 的自 由 度 。 目 标器件可 以 是 FPGAlCPLD 或者是大批量生产时 的 ICo 2. Verilog HDL 开发流程 用 Verilog HDL 语 言 开 发 CPLD/FPGA 的完整流程如图 1 - 1 所示。 ( 1 ) 设计规范: 制定设计规格书 , 在任何设计中 都是首先被完成的。 主要是抽象描述 待 设 计 数 字 电路 的 功 能 、 接 口 和整体结 构 。 在此, 并不需要 考虑结构将如何 由 具体硬 件 电 路来 实现。 ( 2 ) 文本编辑: 用任何 文本编辑器都 可 以进行, 也可以用专用 的 HDL 编辑环境。 编 辑完成后的文件保存为.V 文件。 ( 3 ) 功能仿真: 将.V 源 文件调入 HDL 仿真软件进行功能仿真, 检查逻辑功能是否正 确 〈 也叫前仿真), 对简单的设计可 以跳过这一步 , 只在布线完成 以 后 , 进行时序仿真。 如 果 发现错误 , 则 返 回 第 2 步 , 进行除错处理, 直到正确为止。 ( 4 ) 逻辑综合: 将.V 源文件调 入逻辑综合软件进行综合 , 即 把语言综合成最简 的 布 尔 表达式和信号 的连接 关 系 。 逻辑综合软件会生成edf (ed证〉 的 EDA 工业标准文件。 ( 5 ) 布局布线: 将.edf 文 件 调 入 CPLDfFPGA 厂家 提供的软件中进行布线 , 即 把 设 计 好的逻辑安放到 CPLD应PGA 内 。 ( 6 ) 时序仿真: 需要利用在布局布线中 获得的精确 参 数 , 用 仿真软件验证电路的时序 〈 也 叫 后 仿 真 〉 。 如 果发现错误则返回第 5 步 , 或者第 2 步进行除错处理 , 直到验证结 果正 确为止a 这样的过程可能需要反复多次, 才能将错误完全排除。 ( 7 ) 编程下载: 确 认 仿 真无误后 , 将文件下载到芯片 中 。 设计班班 文本蝙辅 功能侦真 埋辑踪合 布局布线 时F'f!仿真 辅相下载 图 J -1 Verilog HDL 开发流程 通常, 以 上过程可 以 都 在 CPLD/FPGA 厂家 提 供 的 开 发工 具 ( 如 M以plusll 、 Quartusl l 、 Foundation 、 ISE ) 中 完成, 但许多 集成的 EDA 开发软件只支持 VHDLNerilog 的 子 集, 可 / 10 元 能造成少数语法不能编 译 , 如 果采 用 专用 HDL 工具分开执行, 效果会更好, 否 则 这 么 多 出 售专用 HDL 开发工具的公司 就没有存在的理 由 了 。 1.4 Verilog HDL 程序 的基本结构 本节将通过几个比较简单的设计实例, 力图使读者迅速地从整体上把握 Verilog HDL 程序 的基本结构和设计特点, 达到快速入门 的 目 的 , 为 以后各章节的学习提供一个 良好的开端 。 1 .4.1 模块 1 . 模块的概念和结构 和其他高级语言 一 样 t Verilog HDL 语言 也是模块化 的 。 它 以 模块集合的 形式来 描述 数 字 电 路 系 统 。 模块 ( Module ) 是 Verilog HDL 语言的基本 单元, 它 用 于描述 某个设计的 功能或结构及其与其他模块通信的外部端 口 。 一个模块可以是一个元件或者是一个更低层 设 计模块的集合。 典型地, 元件被组合成一个个的模块, 以提供通 用 的 函 数性, 从 而 可 以 在整个系统设计的 许 多 地方 被重复调用 。 一个模块通过它的端 口 接 口 〈 输入/输出 端 口 〉 为 更 高 层 的 设 计模块提供必要 的 函 数性 , 但是又隐 藏 了 其 内 部 的 具体实现。 这样设计者存修 改其模块 的 内 部 结构时 不会对尊重个设计的其 余 部 分造成影响 。 模 块 的基本语 法 如 下 : Module<模块 名 > ( <端 口 歹IJ表》 端 口 说明 ( input. output. inouζ〉 参数定义 数据类型定义 连续赋值语句 (ass�gn) 过程块 ( initial 和 always ) -行为描述语句 低层楼块实例 任务和函数 延时说明块 endmodule 其 中 , <模块名>是模块唯 一的标识符 , <端 口 列表>是 由 模块各个输入 、 输 出 和 双 向 端 口 组成的一个端 口 列 衰 , 这些端 口 用来 与 其他模块进行通信 : 数据 类 型定 义部 分用来 指定 模块 内 甩 到 的 数据对象为寄存器型、 存储器型述是连线 型 : 过程块包括 inÎtial 过程块和 aJways 过程块两种 , 行为描述 语 句 凡 能 出 现在这两种过程块 内 : 延时 说明块用来 对模,块各 个输入和输出 端 口 问 的路径延时进行说明。 下 面 以 一个 2 选 1 多路选择器为例来 说 明模块。 如图 1 -2 所示为 该多路 选择 器 的 电路 示意图。 ?、 1 1 \ lfII擅自院设计实例糟讲 a sel αa b 图 1 -2 m以2 1 模块电路示意图 用 Veri log HDL 语言实现上述 电路的模块如 下 : E例 1-1 】 一个 2 选 l 多路选择器实例。 τ 4 modu1e mux2 l ( out, a , b , sel ) ; 吨吨,ι output out ; 。 input a , b , se 1 i F户AhMdB not í5 (5e1 n , se l ) ; 。 吁 and i6 (se1 a , a , sel) ; , 白 and i7 ( se1 b , sel n , b ) i 。 or i B (out , sel a , sel b) ; JHn end.module 1/峭 口定义 //输入输出列表 //结构描述 在 Verilog HDL 语言编辑、 编译环境下, 上 例 巾 的 行 号 应 当 去 掉 , 在此只 是 为 了便于 说明。 下面将逐行解释上例每一条语句的含义。 第 1 行: 声明模块名及其端 口 列表。 第 2 行 : 指定端 口 out 的方向为输出 (output ) , output 是用 f声明端 口方向的一个 Verilog 关键字. 第 3 行 : 指定端 口 a, b , sel 的方向 为输入 ( input ) , 同样 input 也是用于声明端 口 方 向 的一个 Verilog 关键字。 第 5 行 : 生成一个 Verilog 内 建基本 门级元件 not 的实例 〈 也叫做模块的 调 用 , 在下一 节 中 将做介 绍 , 类似于 C 语言 中 的 函 数 调 用 ) , 该 实例 名 为 洁 。 第一个端 口 sei-n 是输 出 端 口 , 信 号 sel 连接到该 nOl 元件的输入端 口 。 第 6 行 和 第 7 行 : 促成 Verilog 内建 基 本 门 级元件 and 的两个 实例 , 实 例 名 分 别 是 i6 和 i70 第 8 行 : 生成 Verilog 内 建基本 门级元件 。r 的实例 i8。 第 9 行: 用 关键 字 endmodule 示意模块 结 束 。 2. 模块的描述方式 模块的描述 方式又称为建模方式。 Verilog 既 是 一 门 行 为 化又是一门结构化的 HDL 语 言 。 根 据 设 计 的 需 要 , 每个模块的 内 部可 以 分 为 四 种抽 象级 别来 进行描述 。 模块在外部环 境中 的表现都是同 等 的 , 而 与 其 内 部 具体描述的抽象级别无关。 因此校块的 内 部 共体描述 / 12 元 • 第 1 章 Ver批啕 相对于 外部环境来 说是 隐 藏 的 。 改变一个模块内 部描述 的抽象级 别 , 可 以 不用对其外部环 境做任 何 的 改动。 模块大致可 以 按 以 下 四 类抽 象 级 别来 进行描述 。 ( 1 ) 行为级或算法级 的描述 方式 ( 行为级建模 〉 这是 Verilog HDL 最高 抽象级别的描述 方式 。 一个模块可 以按照要求的设计算法来 实 现 , 而 不 用 关心具体硬 件实现的细节。 在这种抽象级 别描述 方式上的 设计非常类似 C 编程 。 行 为描述 是通过行 为 语句来 实现 的 , 行为 功能可使用 下述 过程语句结构描述 。 • initial 语句 : 此语句只 执行一 次 。 • always 语 句 : 此语句循环执行。 只 有寄存器类型数据能够在这两种 语句 中 被赋值 。 寄 非器型数据在被赋新值前保持原 有 值 不 变 。 所有的 initial 语句和 创ways 语旬在零时刻并发执行。 下 面 以一个 4bit 的二进制行波计 数 器 〈 带进 位 〉 为例来 说 明 行 为 级 的 捕述 方式 。 如1图 1-3 所示为该计数器的电路示意阁。 。 q2 q3 1-- - - - - - - 圃. , … … … … E -…….… ……回画 ……… ……… ' ' 、 clωk 1 q 〉 T-q }T-q T回1fF 1『、 FF 1 tfl2 ' FF ←- IfD t t t · · ' ' ' c1ear ' ' ‘--------------……-- ------------- 图 1 -3 4bit 二进制行被计敬器电路示 意图 该 计 数 器 由 4 个 T触发器级联而 成 , 每一级 T触发器的输 出 作 为 下一级 T触发器的时 钟 输入 。 下例是用 行 为 描述 方式来 实现计数器的一个例子。 E 例 1-2] 用 行 为 描述 方式来 实现行波计数器。 module cnt_4bit (q, clear, clock ) i output ( 3 : 0 ] q; input clear , clocki reg ( 3 : 0 ] q i always @ ( posedge clear or negedge clock) begin if (clear) • q=4 ' dOi else q罩 ( q+ l ) 屯 1 6 ; end endmodule -\ 1 3 \ • • 模块 cnL4bit 的输出端 口 q 是一个 4bit 的位矢量 , 代表 4 根输 出 端 口 线 q[3J 、 q[2] 、 q[ l ] 、 q[O]。 由于 该输 出 端 口 要在 always 语句中被赋值, 所以它被定义为 reg 型 〈 寄存 器型 ) 数据。 clear 和 clock 是两个输入端 口 。 Always 语句中包含一个或事 件控制 〈 紧跟在字符@后 面的表 达式 ) , 以及相关联的顺序过程 (begin-end 对 λ 此或事 件控制的作用 是 当输入端 口 clear、 clock 上发生事 件 , 即 clear、 clωk 中 某一个值发生变化时, 就执行下面的顺序过程。 在顺序 过程中的语句顺序执行, 并在j顺序过程执行结束后被挂起 , 程序指针返回到或事 件控制语句, always 语句再次等待 cle缸、 clock 的值发生变化。 这种机制与 CtI 中 的 消 息循环 决似。 本例用 非 常抽 象 的 方式描述 了 模块要实现的功 能 , 而没有直接指明或者涉及实现该功 能 的 硬 件结 构 , 即 具体硬 件 电路的连接结构 、 逻辑 门 的组成结构 、 元件等。 行为描述 方芳、 是 Verilog 这种高级硬 件描述 语言的一大 特色, 可 以 说没有行为 级描述 就没有 Verilog, 请 读者在以后的学 习 中 仔细体会。 ( 2 ) 数据流描述 方式 〈 数据流级建 模 〉 数据流描述 方 式 , 也称为 RTL ( 寄荐器传输级 〉 描述 方式。 在这种描述 方式下, 设 计 者需要知道数据是如何在寄存器之间传输的 以及将被如何处理。 数据流描述 方式类似于布 尔方程 , 它能够 比较宦观地表达底层逻辑 行为 。 在 Verilog 中 数据流描述 方式主要用来 描 述 组合逻辑 , 具体由 连续赋值语句 "assign "来 实现。 下面仍然 以 国 1-3 的 4b让 二边制行 波计数 器 为 例 , 根据 自 顶 向 下 ( Top-Down ) 的 设 计方法, 用 数据流描述 的方式来 实现它。 E 例 1 -3 1 用数据流描述 方式来 实现行波 计 数 器 。 第一步, 设计顶层模块 cnL4biL L 代码包含 了 4 个 T触发器模块 T-fT 实例 〈 模块调用 〉。 zn。duie cnt-4b itL-1 ( q , clea主 , clock) ; output [ 3 : 0 ] q; input �lear , cloc k ; T ff 一 T ff 一 T ff tffO ( q [ O ] , clear, clock) i t f f l ( g [ l ] , clear, q [O ] ) i tff2 (q [2] , clear, q [ l ] ) ; T f f tff3 (q [ 3 J , clear, q [ 2 J ) i endmodule 第 -三步 , 设 计 tE触发器模块 , 该模块 内 又包含 了 其下一层的 D触发镣模块 edge_dff 实例。 • module T,-EZ {q, clea立, clock) ; ou巳put q; input clear, clocki edçe_d f f f 主 l (q, , -q , clea玄 , clock) ; end.module / 1 4 /� 第 1 章 Verilog HDL s 在代码 中 用 数据沈操作符 ‘J 对.1t� q 取反, 而 不是用 V创1ó8 内 建基本 门 银 元 件 E 剧 , 但 是 两 者 最 佟 实 现 的 功 能 完 全 相 同 - z 语I 句 " edp-dftì m也 确.c)铺r.cIωkl中 的 空 格在参默认调 用 y 但是 r ? , " 分隔符不能少 . 第 =之步 , 运用 数据流描述 语句设计最底层模块负边沿触发 D触发器 edge_djf.。 如图 1 -4 所示为该 D触发器的基本 门级结构。 module edge-df f { q , qbar , d, clea z , clock ) : 。utput q, qba r i input d, clear, clocki wire s , sbar , r , rbar, cbari assign cbar=-clear; 1 1输入锁存捺 : 锁布据是电+敏感的. 而一个边沿敏感的触发器需 要使用 3 个 RS 锁存器来实现 assign sbar=- ( rbaI & s ) , s=- ( sbar&cbar&-cloc k ) , r=� { rbar&-clock& s ) , rbar=- ( r &cbar&d) ; 1 1输出锁存 assign q=- ( s &qbar } , qbar-- (q&r&cbar) ; encimodule i u: lT cleer clk hri q qbar d L一一!一…---L----一-j 阁 1 -4 负iIl评与触发 D 触发黯 在这一步的模块 edge_dff 中 , s 、 sbar、 r、 rbar、 cbar 被 定 义 为 wire ( 连线 〉 型数据 , wire 也 是 Verilog 的关键字。 征其后 的代码中使用 as到gn 语句对模块的输入、 输 出 端 U 和l i主线型数据之间的 数据流传输关系3tt行 了 描述 。 这就是 Verilog 巾 的数据流捕达方式。 ( 3 ) f J级描述 方式 〈 门级建模 〉 在这种描述 方式下 , 模块是按照逻辑门 和它们之 间 的 互 连来 实现的。 化这种抽象级别 \ 15 \ 应用程摩设计实伊精讲 下 的 设 计与 按 照 门 级逻辑图来 描述 一 个 设 计类似。 具体地 讲 , 门级描述 方式就是指调用 Verilog 内 建的 基 本 门 级元件来 对硬 件 电路进行结 构 设 计。 这些基本 的 门 级元件是一类特殊 的模块, 共有 1 4 种 , 分 为 四 类 , 它 们 是 由 Verilog HDL 语言 自 身 提 供 的 , 不需要用 户 事先 定 义 就 可 以在设计中 被直接调 用 。 下 面仍然以例 1-3 中 的 行波计数 器 为 例 , 其第三步 的模块 edge_dff 的设计可 以 采用 门 级描述 的 方式来 实现。 根据图 1 -4 所示的逻辑图, 以 门 级描述 的 方 式来 实现它 , 具体如 下 例所示。 E 例 1-41 用 门 级描述 方式来 实现负边沿触发 D触发器 。 TTI。duLe edqe-dff-l ( q , qbaz , d , clear , c lock) J 。utput q , qb a r i input d, clea r , clock; wire cbar, clkbar, sbar, s , 主 I rbari not Nl ( cbar, clear) , N2 ( clkba r , clock) ; nand NAl ( sbarI rbar, s ) , NA2 ( s , sbar, cbar, clkbar) , NA3 ( 汇 , 5, C1 kbar , rbar) , NA4 ( rbar , 主 , cbar, d ) , NA5 (q, s , qbar ) , NA6 (qba r , q , cbar , r ) i endmodu le 由 本 例 与 例 1 -3 第三步对 D触发器的两种 不 阳风格的描述来 看 , 数据流风格的描述 就 像是在列逻辑方程式, 而门 级描述 就像是在画 电路原理图, 它们都非常直观地表达 了 D触 发器的 底层逻辑行 为 , 它们母终实现的 D触发器模块的逻辑功 能完仓相 同 。 ( 4 ) 开关级描述 方式 〈 开关级 建模 〉 开关级描述 方式也称为 晶体管级描述 方式, 是 Verilog 最低抽象级别 的描述 方式。 在 这种描述 方式下, 模块是按照开关级元件和存储节 点 以及它们之 间 的 E.边来 实现 的 。 具体 来 说 , 是指调用 Verilog 内 边 的 基 本 开 关级元件来 对硬件电路进行约 构 设 计 。 与 f J 级 元件 类 似 , 这些基 本 的 开关级元件也是一类特殊的股块, 共有 1 2 种 , 它们也是由 Verilog HDL 语 言 自 身 提 供 的 , 不 需 要 用户事先 定 义 就 可 以 在 设 计中 被 直接调用 。 由 于 有 了 这一级 别 的 描述 方式 , 使得用 户 在 MOS ( Metal-Oxide Semicooductor, 金属氧化物半导体〉 品体管级 进 行设计成为 可 能 。 这一点 也 正 是 Verilog HDL 谓言的一大 优点 , 而要在其他的 HDL 语言 比 如 VHDL 中 进行晶体管级设计是非常困难 的 。 然 而 , 随着电路规模 的 日 渐庞大 〈 七百 万 门 晶体管 〉 和 EDA 工 具 的 高速发展, 在极少数情况下 , 设计者 才 可 能选择在晶体管级进 行 电 路 设 计。 下 面 以一个简单 的 例 子 对 开关级描述 方式进行介绍 。 尽管 Verilog 有 内 建 的基本门级元件 , 比如 nor 门 , 但是现在我们 可 以 使用 CMOS ( 互 第 1 章 V审批精 补金属氧化物半导体〉 开 关元件设计我们 自 己 的 nor 门 。 nor 门 的 门 级 和 开关级逻辑示意 图如图 1 -5 所示。 • - 。ut b my_nor 图 1 -5 nor 门 的 门 级 和开关级逻辑示意图 E 例 1-5) 用 开关级元件描述方式设计 nor 门 。 , m 。 d U 『e 牛 my- n 。r'1。 u +」 a b ., . 。utput 。u-L, ·主nput a , b J W­- z e c ; supp1yl pwz., supp1yo qndJ pm。s{c'pwx'b.,-‘ J pm。s{。ut'c'a.,‘. J nm。s(。ut'qnd•.. a n mos(。ut'q nd•, b 邮 e n d ul e 程序中 的 supply l 、 supplyO 是 Verilog 的 关键字 , 分 别 定 义 电路 的 电源和地。 pmos、 nmos 都是 Verilog 的基本开关级元件。 (5) 描述方式总 结 以上介绍 了 Verilog 四种抽象级别 的描述方式。 事实上, 设计者可以在一个设计中混合 使用这四种描述方式 。 如 果一个设 计包含四个模块, 那么每一个模块可 以 分 别 用 不 同抽象级 别 的描述方式来 实现。 从设计的成熟性上考虑, 大 多数模块都可以转化为门 级描述来 实现。 通常, 描述方式越抽 象 , 设 计的 灵 活性和技术独立性也越强。 而路靠近开关级的描 述 方式, 对技术的依赖性也越强 , 设计本身 也就越不灵活, 一个小改动就可能导致整个设计 的大 改变。 这一点与周 C 语言和汇编编程相 似: 用 更高级的语言 〈 比 如 C ) 进行编程更容 易 , 而且也更 容 易 移 植 到 不 同 的机器上 : 相 反 , 如 果 用汇编 语言编程 , 那 么 程序是针对某 应题霉廖设计实伊鹏消 种 特 定 的 机 器 , 要移植到其他机器上则很 困难 。 对于数据流级 描述 方式 ( RTL 级描述 方式 ) , 从本质上说, 它 是 对 线 网 型变量的行为 进行 了描述 , 肉 此 本书将这种 数据流描述 方式归类子行为 级描述 方式。 对 于 门 级 和 开 关级 描述 方式, 出 f它们都是根据电路的硬件结构特点进行 设 计 , 因此本书将这两种描述 方式 归 类 子 结 构级描述 方式。 至此, Verilog 语言分为三大类描述 方式 , 即 行 为 级描述 方 式 、 结 构级描述 方式以及它们之 间 的 混合描述 方式。 本 书后续章节将结合具体的 Verilog 程序语 句对行为 级描述 方式和结构描述 方式做详 细 介 绍 。 3. 设计的仿真与测试 一个 设计一旦完成就应 当对它进行测试 。 通过编写激励块, 输入激励信号然后检测结 果 可 以检测一个 设 计功能的 正确性。 将激励块和设计块分离开来 是 设 计者应该养成 的一个 好 习 惯 。 通常测试 块也被称 为测试 凳 ( Test Bench ) , 应用 不 同 的 测 试 凳 可 以 对一个设计块 进行全方位的测试 。 激励信号的应用 方式大致被分 为两种 。 第一种 , 在激励块 内 调用 设 计 块 , 并且 直接驱动设计块的 信号 。 在图 1 -6 中 , 激励块 成 为 顶层模块 , 对输入信号 clk 和 reset 进行操作 , 检测并显示输 山 信 号 q。 (Stlffiulus block) clk r巳SCI (Design Block) Ripple Carry Counter q 因 1 -6 激励块调月1设计块示崽图 第 二 种 , 在 顶 层 的 假模块 内 同时调 用激励块和 设计块, 激励块和设计块仅通过接 n 相 可: 作 用 , 如图 1 -7 所示。 激励模块驱动信 号 dJik 和 d-reset, 这两个信 号 与 设计块的两个 端 口 cLk 和 reset 分 别 相 连 。 它也检测 并 思示输 出 信 号 c_q , 该信 号 与 设 计 块 的 输 出 端 口 q 相连。 顶层假模块的功能仅仅是 为 了 调用 设计块和激励块。 Top_u:vel 91优k Ed clk Stimulus - Block d reset c_q c1k kj D四ign Bloc 」 resel Ripple Carry Counler q / 18 / 因 1 -7 顶层假模块调用设计块和lj激励块示意图 第 1 章 Ver蜘g 下面我们将对例 ] -2 的行波计数器进行仿真测试 。 将例 1-2 设 计模块科序重写如 F 。 module cnt-4bit (q, clear , cl。ck} J output ( 3 : 0 J qi input clear , clock; reg [ 3 : 0) q; always @ ( posedge clear or negedge clock) begin if (clear) q=4 ' dO i else q= (q+l) 辛 1 6 i end endmodule 现在必须写 出激励块 以检测行波 计数器功能是否 正 确 。在此,必须控制信号 clk 和 reset 以检测行 波计数器的 计数功能和异步复位机制是否都正确 。 我们将使 H:j 如 图 ] -8 所示的被 形来 检 测 设 计 块 。 图 中 显 示 了 输 入 信 号 clk, reset 以 及 4bit 的 输 出 信 号 q0 111 钟信 号 clk 的 时 钟 周 期 为 10 个时间单位 : 复位信号 reset 从 0 到 1 5 保持 为 高 , 然后变低, 直到 1 95 再 次 变 高 , 至 205 后 变 低 : 输 出 信 号 q 的 范围 是 从 0 到 1 5 。 clk · reset -E·zaE‘•--,也•••, 忖 '1(3;创 nu 图 1 -8 激励和输出被形示意图 I I 下面就准备 写 出 激励块 , 生成图 1-8 中 的 波形。 我们将使用 如 图 1 -6 所示 的激励方式。 在此不要过 多 考 虑 Verilog 的语法, 将精力集中 在激励模块是 如 何 调 用 设计模块 L E 例 1-6】 编写激励块。 module stimulus l ; reg cl ki reg reset; wire ( 3 : 0 ] qi cnt 4bit rl 间, reset , clk) ; //调用设计块 cnL4bit 生成实例 rl 1/控制情 号 cl k 以驱动设计块, 时钟周期设为 10 个时间单位 主nitial \ 19 \ clk=.工 ' bO ; • always //设键 clk 到 0 15 clk="'cl k; / /ol k 每 隔 5 个 时 间单位反转一 次 //控制复位信号 xeset 以驱动设计块, 。-15 为商, 15-195 为低, 195-205 为高. 然后变低 initial begin reset=1 ' b1 ; ' 1 5 reset=l ' b O ; 1 1 80 reset=l ' bl ; 4 1 0 reset= l ' b O ; 120 $finish; end / / 监视输出 in丰t主al $monitor ( $tirne, " output q=毛d" , q) : endmodule 下面就可 以运行仿真棒 了 , 以检测设计块功能的正确性。 仿真的输出结 果如图 1 -9 所示。 。 ow:put: q • 。 20 Out:put q • 1 30 ou_cput cl • 2 .0 ou.t.院,t q • 3 SO Ol.1tpuC q • 4 60 CMt.pUt q .. s • 70 Oltl pUt. q - 6 80 Outp恤t q • 7 90 Ou.t:put q • ' 100 OIJtPU且 q • 9 110 队lClpuC q 霉 10 120 OU�put q • 11 130 OIAtpllt q .. 12 1.0 Output: q • 13 150 Outþ\lt q 事 l' 160 αJtput q a 且5 170 OUtPIlt. q • 。 180 OUt'Put q • L 190 OIAtgut. q � 2 195 Outl'ut q • 。 210 Ou.eput q • 1 22() Output q - 2 图 1-9 仿真的输出结果示意图 关于模块的仿真与测试 , 本书后面的章节将会对其进行更加详细的介绍。 1 .4.2 在上一节对模块概念和结构的介绍举例中 已经 多 次运用 了 模块的调用 - 所谓模块的调 用 , 是指从模块模板生成实际的 电路结构对象的操作 , 这样的 电路结构对象被称为模块实 例 , 模块调用也被称 为 实 例 化 。 每一个实例都有它 自 己 的 名 字 、 变晕、 参数和 1/0 接 口 。 一个 Verilog 模块可以被任意 多 个其他模块调用 。 模块调用和 函 数调用非常 相 似 , 但是在 本质上又有很大 差别 : 一个模块代表拥有特定功能的一个 电路块, 每 当一个模块在其他模 第 1 章 V町i问 块 内 被调用一次, 被调用模块所表示的电路结构就会在调用模块代表的 电路 内 部被复制一 次 ( 即 生成被调用模块的一个实例 ); 但是模块调用 不能像函数调用一样具有 " 退 出 调 用 " 的操作 , 因 为 硬件 电路结构不会随着时间而发生变化, 被复制的 电路块将一直存在 下 去 。 需要注意 的 是 , 在 Verilog 巾 , 模块不能被嵌套定义 , 即在一个模块的定 义 内 不能包 含另 一模块的定义. 但是却可 以 包含其他模块的拷 贝 , 即调用 其他模块的实例 。 模块的定 义和模块的实例是两个不 同 的 概念 , 在一个设计 当 中 , 只有通过模块调 用 ( 实例化〉 才能 使用 一个模块。 模块调用语旬的 基本格式如 下 : 〈模块名> <参数值列表> <实例名> ( < 端 口 连接表> ) : 在上面的格式 中 : • <模块名〉是指模块定义时为 被调用 模块指定的模块名 。 • <参数值 列 表〉是可选项 , 它 是 由 一些参数值组成的一张有序列 表 , 这些参数值将 被传递给被调 用 模块实例 内 的各个参数。 • <实例名〉是为模块调 用 后所生成的模块实例 所取的一个名字, 它是模块实例 的唯 一标志。 在某一模块 内 可以对 同一模块多次调 用 , 但是每次调用 生成的模块实例 名 不能重复。 实例名和模块名 的区别是, 模块名表示不同的模块, 即用来区分电 路单元的不同种类: 而实例名 则表示不同的模块实例 , 用 来区分电路系统中的不 同硬件电路单元。 • <端 口 连接表〉是 由外 部信 号端子组成的一张有序列 衰 , 这些外部信号端子代表着 与模块实例各端 口 相连 的 外 部信 号 。 所 以〈端 口 连接表〉指 明 了 模块实例端 口 与外 部电路的连接情况。 在例 ] - 1 中 , 语句: not i5 (5e1 D, sel ) ; and i6 (sel a , a , sel) ; and i7 ( sel b , sel n , b ) ; 。r i8 (。uu selj, selJh 以及在例 1-3 中 , 语句: T ff T_ff T-ff T ff tffO (q[O ] , clear, clock ) ; tffl {q[ l ) , clear, q[O] ) j tf f2 ( q { 2 ] , clear , q [ 1 1 ) J tff3 {q (3 ] , clear, q[2] ) ; 都是模块调用 的一些例子。 关于模块 调 用 的具体细节, 将在本书后面的 4. 1 节 " 模块 级 建 模 " 中做详细介绍, 这里先不讲述。 • 队 21 \ • 第 Verilog HDL语法基础 . 与其他高级语言一样J Verilog HDL 语言也具 有 自 身 固 有的 语法格式。 本 章将对 Verilog 的 语法基础知识进行详细 说 明 。 2.1 程序格式 _. Verilog HDL 程序是 由模块构成的 , 每个模块 的 内 容都包含有 module 和 endmodule 两 个语句之 间 。 每个模块都要进行端 口 定 义 、 端 口 声 明 。 Verilog HDL 程序的书写 与 C 语言 类似, 一行可以写多条语句, 也可以一条语句分成多行书写 , 每条语旬 以分号结束, endmodule 语句后 可 不 加 分 号 。 每个文 件 内 可 以包含多个模块 定 义 , 但只能有一个顶层模 块。 每个 Verilog HDL 程序源文件都 以.V 作 为文件扩展 名 。 2.2 注释 Verilog HDL 有两种方式引 入注释 。 其一是单行注释 , 起 始 于双斜杠 11 //", 结束于新 的一行 的 开始。 其二 是 多 行注释 , 或者叫 做块注释 , 以符号单斜杠星号 " J* 7J 作 为 开始标 志 , 以星 号单斜杠 " */" 作 为 结束标志。 块注释不能嵌 套。 单行注释符 号 (1// " 在块注释语 句 内 并 无特 定 含 义 。 2.3 间隔符 间 隔 符包括宅格 ( \b ) 、 tab ( 川 、 挟行符 (\n ) 反换页符。 若 间 隔 符并非出现在字符串 中 , 则该间隔符应当被忽略 。 问 隔 符除起 到 分 阔 的 作 用 外 , 在必要的地方插入相应的宅格 或换行符 , 可 以 使文本错落有致, 方使用 户 |商 i卖与修改。 • 第 2 章 Vertlog 2.4 数值 Verilog HDL 中 的数值可以驭下面的四类值。 • 0: 逻辑 0 或假状态。 • 1 : 逻辑 1 或真状态。 • x (X): 未知状态, x 对大小写不敏感。 • z (Z): 高阻状态, z 对大小写不敏感。 Verilog HDL 中 有两类数值常 量 : 整数也常慧和实数型常量。 1 . 整数型常 整数型常盘有两种表示方法: ( 1 ) 简单的十进制格扩 这种格式是由 O斗 的数字串组成的 十边制数, 可 以在数值前面加上符号 " + " 或 " - " 来表示数的正或负. (2) 指定位宽的基数格式 这种格式 由三部分组成: 〈SUe〉 dbase-format〉 〈number〉 • : 指 定 数的二进制位 宽 的 参 数 . 该参数应该是一个非苓: 的 无符 号 十进制常扯。 例 如 , 两位十 六迸制数的位 宽为 8, 因 为一位十六进 倍。数要求位觉为 4。 • <'bωe fOIluat> : 单引 号 < ' ) 是 指 定 位 宽 格 式 表 示 法 的 固 有 字 符 , 不 能 省 略 。 base fonnat 是用 于指定数的 基数格式 ( 进制 格 式 〉 的一个字母 . 对大小 写 不敏感。 在 base format 之前 ( elJ单引 号 ( 寸 之后 〉 可 以 加 }二字母 s ( S ), 表示该数为有符 号数。 合法的基数格式字母有 d ( 0)、 h (H)、 o (0)、 b ( B), 分别对应于 |进 制 、 十六进制、 八进 制 、 士进制数 。 单弓| 号 ( ' ) 和 base-iormat 之间不能有空格 。 • 参数默认 ), 那么默认的位宽至少是 32 位。 二进 制 的 一个 x 旦旦 z 表示一位 处 于' X 或 Z, 八进制的一 个 x 或 z 友示 3 位二 进 制 部 处 于 x 或 z, 1 "六 进 制 的 一 个 x 成 z 表示 4 位气 进制位都处 于 x 成 z。 此外, Verilog HDL 中 的 z 可 以用 问 号 ( ? ) 来 代 拌 , 在 1- 六 进制 、 八进制、 二j桂制 荣立 中 的 一位 " ? " 分 别 友 示 4 1"V: z 、 3 位 z、 l 位 Zo 闷 亏 ( ? ) 也 则 在 用 户 自 定 义 基 元 的 状 态 农 中 J f.:j" 关 细 节 泊 参 见本书后面的章节。 简 单 的 卡迸钻u格式表示的数被作为 有符号 楼数处理: 而在某数格式表示的数l-j-I , 如 果: " 23 \ 在 base-format 之前有字母 S ( S ) , 那 么 该数被作为有符号数处理, 否 则 作 为无符号数处理。 在基数格式表示法中 , 可 以 在 sue 之前加上 " + " 或 "J 表 示 数 的 正或 负 , 但是不能在 base-format 和 number 之间加 川" 或 " · ", 因 为 这违 背 了 Verilog HDL 的语法规则。 值得 一提 的 是 , 在 Verilog HDL 中 负 数都按二进制补码形式存储和处理。 下画线符号 ( ) 除了 不能放在数值的首位以外, 可 以放在整数型和实数型内 任何地 方。 它们对数值没有任何影响, 在编译时会被忽略, 只 是 为 了 将长的数值分段, 以提高可 读性。 下面举几例 说明整数型常量的表示, E例 2-1 1 未指定位宽 的 整数常量表示。 659 ' h 837FF '07460 4af // 简单卜进制数格式 / / 默认位宽十六进制数 // 默认位宽八进制数 // 非法的整数表示 〈 十六进制数要求格式 ' h ) E 例 2-2) 指定位 宽 的整 数常量表 示。 4 'b1001 5 '0 3 3 ' b01x 12 ' hx 16 'hz // 一个 4 位二进制数 / / 一个 5 位十进制数 // 一个 3 位二进制数, 是低位状态未知 // 一个 12 位十六进制致, 状态未知 / 1 一个 16 位十六进制数, 状态为高阻 E 例 2-3 ) 有符号 整数常量的表示。 8 'd -6 -8 ' d 6 If 4 I shf � -4 'sd15 / / 非法格式, base format 和 number 之何不能有 " + " 或 " J / / 定义正整数 6 的补码, 占 8 位, 相当于- ( 8 ' d 6) / / 表示 4 位二进制数 ' 1 1 1 1 ' , 作为 1 的补码数或者i ' -1 ' , 相当于-4 ' h 1 // 相当于 - ( 斗 ' d 1 ) 或者 ' 0001 ' E例 2-4 】 自 动在填充。 reg [ 1 1 : 0 ] a , b , c, d i initial begin a = ' h x; / /生成 xxx b = ' b 3x; //生成 03x c = ' b z3; / / 1:.成 z z 3 d = ' h Oz3; //生成 Oz3 end 主eg [ 8 4 : 0 ) e, f , g; e = ' h5; //坐成 { 82 { 1 ' bO } , 3 ' bl01 } f = ' 以 ; / / 坐成 { 8 5 { 1 ' hx } } 9 = ' hz : / / 生成 { 85 { 1 ' hz } } / 24 !A 第2章 E 例 2-5】 使用下面线 ( )。 27 195 000 工 6 ' b0011 0101 0001 1111 32 ' h 12ab f001 2. 实数型常 Veri log HDL 中 的实数型常量可 以 用十进制和科学计数法两种格式来表示。 如果采用 十进制格式, 则 小 数 点 的 两边至少都有一个数字 , 否 则 为 非法表示。 下面举例 说 明 实数 型 常量的表示。 E例 2-6J 实数型常量的表示。 1.2 0.1 2394 . 26331 1 . 2E12 1 . 30e-2 O . le-O 23EIO 2 9E-2 236 . 123 763 e-12 - - . 12 9. o1 . E 3 . 2e-7 / / 十进制数 / / 十进制数 / / 十进制数 1/科学计数法, 指数符号 E 对大小写不敏感 //科学计数法 / / 科学计数法 / /科学计数法 / /科学计数法 1 / 科学计数法, 下面线被忽略 / 1 非法表示 / 1 非法表示 1 1 非法表示 // 非法表示 3. 两种常量的转换 实数型常量可 以通过对小数四舍五入 , 转换为最靠近的整数型常量, 而不是直接将小 数舍弃, 从而得到整数。 当一个实数常量被赋给一个整数变量时, 一种隐式的转换就发生 了 。 例 如 , 实数 35.7 和 35.5 转换为整数都得到 36, 而实数 35.2 转换为 整数得到 35。 实数 -1.5 转换为 整数得到-2; 实数 1.5 转换为整数得到 20 2.5 字 符 串 字符串 是用双引 号 (" ") 括起来的字符序列, 它必须包含在一行内 ? 不能分成 多行 书 写 。 如 果 字 符 串 被用 做 Verilog 表达式或赋值语 旬 的 操 作 数 , 则 字 符 串 被 看 做 无 符 号 整 数 序 列 。 每一整数代表一个 8 位的 ASCU 字 符 值 , 即 每一整数对应字 符 串 中 的一 个 字符。 1. 字符 串 变量声明 字 符 串 变量 是 寄 存器炎-型 〈 参见后面章节 〉 的变囊, 该字符串 变量 的位数要大于等于 字符串 的最大长度。 E例 2-7] 字符串变量的声明 。 存储一个 1 2 字符的字符帘' HeUo world!"需要一个 8叫 2=96 位的寄存器变量。 reg ( 8 世 1 2 : 1 ] s t r i ngva r ; initia1 begin stringvar = "8e110 wor1d ! " ; end 2. 字符串操作 可 以 使用 Verilog HDL 的操作符对字符 串 进 行 操 作 , 被操作的 值是一个 8 位 Ascn 值序列。 在操作过程中 , 如果声明 的字符串 变量位数大于字符 串实际长度, 则在赋值操 作 后 , 字符串变莹的左端 〈 即 离位 〉 补 0。 这一点与非字符串 值的赋值操作是一致的。 如 果卢明的字符串变量位数小于字符 串 实 际 氏度, 那么字符串 的左端被截去, 这些高位 于二符 就 丢 失 了 。 E 例 2-8] 字 符 串 操 作。 module String-test ; reg [ 8 食 1 4 : 1 ] stringvar; initial begin strìngva主 =i " Hell。 w。z ld" ; $disp1ay ( " 毡 s is stored as 毡h n , stringva r, stringvar) ; strinqvar = (s tringvar, " ! ! ! " . ; $display ( " 毛s is stored as 屯h " , stringva r , str1ngva r ) ; end endmodu1e 输山结果为: Hello world is stored as 00000048656c6c6f2077 6f726c64 He 1 10 world ! ! ! 1s stored as 4 8 656c6c6f20 7 7 6 f7 2 6 c 6 4 2 1 2 1 2 1 3. 特殊字符 在某些字符之前加上一个引 导性的字符 〈转义字符), 这样的字符只能剧f字符串中。 农 2-1 列 出 了 这些特殊字符的表示和意义。 / 26 反 第2章 飞n 飞1 飞飞 飞" \dd 表 2-1 俨 ‘铮攘' 精褒萦 JE "飞 特殊字符的表示和意义 a 换行符 LS • 四岛 " 叉,_ 且 ' ' 且 也 , 丁、b 键 符号飞 符号" 3 位八迸制数表示自:J ASCU 值 • (0 �d �7) 同 .咱. ‘�.. •-. 电- l 、 , 2.6 标识符 标识符是赋予一个对象唯一的名字, 通过标识符该对象就可以被引用。 标识符分为简 单标识符 、 转义标识符、 生成标识符、 关键字。 1 . 简单标识符 简单标识符是由字母、 数字、 货币符号 <$)、 下画线 〈-〉 构成的任意序列 。 简单标 识符的第一个符号不 能是数字或$符号 。 简 单标识符对大小写敏感。 下例是一个简单标识 符定义的例子。 E 例 2-9 1 简单标识符定义 。 sh-l bus aFιt ­ l-芷enqde-ax error condition merge_ab bus3 n$657 , 具体实现-个标识符 " 时候, 应 当 放到巳--个标识符 的 最大长成限制 ,- 4aak 大itL不能小�. 1024 个字F 符- 如呆-个标识待的 长底越过,τ 注定的lE实现长成."­ 制" 则r会有铺溪报告产 生 . 2. 转义标识符 转义标识符 以反斜杠 (\) 作为起始, 以 空 向 〈 空格、 Tab、 换 行 〉 作 为结束。 在转义 标识符电 丽 可 以 包含任意可 印刷 Ascn 字 符 〈 十进制值为 33- 1 2.6 , 对内十六进制值为 2 1 -7E )。 转 义标 识符的起始标志反斜杠 C\) 和 结 束 的 空 肉 都 不 作 为标识符的一部分来处 理, 因此转义标识符 \cpu3 被作为 非转 义标识符 cpu3 处理。 以下是一个转义标识符定义 的例子。 队 27 \ ..." 第 2 章 Ver捕。, 1 . 标准输出任务 在 Verilog HDL 中 有两种主要 的标准输 出 任 务 : $display 和$write。 这两种标准输 出任 务 的格式相 同 , 区 别在于$display 任务在将特定信息输 出到标准输 出 设 备时 , 具 有 自 动换 行的功能, 而$write 不带有行结束符 。 下面 以$display 任 务 为 例 进 行 说 明 . $display 可 以 用 来输 出 字符 串 、 表达式及变量值, 其语法格式与 C 语言 中 的 printf 函 数相同, 可表示如下: $display (,signal�signa1, . . . . . . ) ; 其 中用 来指定输出格式。 表 2-2 给 出 了 各种 不 同 的输出格式。 、 严 2.正 _ 【 I :lI"i..j输 _ • ...,. 栩 ..... .!F... 栩 ��� %d 或%D �I�... ..... l � 表 2-2 输出格式符说明 臼 �- - 十进制格式 l _ , 凰 格式符说明 •PE • , 币. fd ..� J - K [[]] �u -F j %b 或%8 -二.ut制格式 %h �%H 1-;飞边帘j格式 %m 戚%M 棋块分组名 %。 或%0 八耻如j格式 %t 或%T 时间格式 %e 或%E 椭般格式输出实撒 %f或%F 得点格式输出实敬 %g 或%G 以 上 述 两 种 格 式 中 较 短 的 输 出 在· 放 %e 或%C ASCU 字符格式 %s �%S %v 或%V 飞n 飞t \\\,,�/n\"1/厅\\ C', 圃 ,f厅\\yIlff .\a{1 丁 / 川 字 符 :tl 格 式 输出地雏型数据的震动强皮 rRR', 1: II II 换行 ,�J 11 11 11 n \. . 、 . 丁、b 键 飞飞 飞· 飞ddd 半衍飞 字符· 3 位八挂i 制撒在示tJ指 定 被 打 开 的 文 件 名 及其路径, 如 果路径与文件名 正 确 , 则 返 回一个 32 位 的 句柄描述符〈缸e handJe>, 且 其 中 只 有一位为 高 电平 , 否 则 返 回 出 错信息。 因 为 标准 输 出 具有 自 己 的 最低 位 设置 , 所 以 当 第一次使用$fopen 时 , 返 回 的 32 位句柄描述符 中 将 次低位设 置 为 高 电平。 每一次调用 $fopen 都会返回一个新的句柄 , 且高 电平依次左移。 下 面举例 说 明 。 E例 2-ul 打开文件。 integer handleA, handleBi ll定义两个 32 位整数 工nitial begin hand工eA=$ fopen ( "myfile . out " ) ; / / handleA=0000 O O GO--0000-0000-0000-0000-0000-0010 handleB=$ fopen ( " anotherfile . out " ) ; / / handleBZO000-oo oo--0000一0000-o o o o--00σo-00 00-0 1 00 end (2) 输出到文件 Verilog HDL 中 用来将信息输 出 到 文 件 的 系 统任 务有$fdispl町、 $如民te、 $缸lOnitOfo 它 们 具 有 如 下 相 同 的语法格式: 〈tas k-name〉 (< fileJ1andles〉 , 〈 f。rma℃-speci fiem〉 } J 其 中 〈Usk-name〉是上 述三种 系 统 任务 中 的一 种 。 〈muhmdies〉是文件句柄描述符 , 与 打 开文件所不 同 的 是 , 可 以 对句柄进行 多 位 设 置 〈 见下 例 ) 0 用 来指定输 出格式, 格式说明符可 参照表 2-20 E 例 2-13 1 输 出 到 文件 。 11利用例 2-12 的旬柄 integer channelsA; initial / 30 � 第 2 章 V审伽啕 begin channel sA=handleA l l i $ fdisplay (channelsA, "hello" ) ; end 本 例 中 的 hand1eA 为例 2- 1 2 的句柄输 出 。 (3) 关闭文件 系 统 函 数$fclose 能 够 用 于 关 闭 文 件 , 其语法格式 如 下 : $fclose ( < file handle>) ; 当 使 用 多 个文件时 , 为 了 提 高法度 , 可 以将一些不再使用 的 文 件关 闭 。 一旦某个文件 关闭, 则不能再向它写入信息, 但其他文件可以使用该文件的句柄。 (4) 从文件 中 读 出数据到存储器 VeriJog HDL 中有 两个 系统任务$readmemb 和 $rω缸lemh , 它们能够把一个数据文件中 的数据 内 容读入到一个指定的存储器中 。 这两个系统任务的区别在子 , 前者要求以二进制 数据格式存放数据文件 , 而后者要求 以十六进制数据格式存放数据文件 。 它们具有相 同 的 语法格式: 〈task-name 〉 { 〈 f ile-name〉, 〈汇egister_array > , ) ; 其 中 〈task-nme〉 用 来 指 定 系统任 务 , 可取上述任 务 中 的一个。 die-mme>是读 出 数据 的 _ 文件名 。 为要读入数据的存储器。 分别为荐储器 的起始地址 和 结 束地址. 现有一数据文件 mem.dat, 可 以 通过下面的例子将其读入到存储 器 中 。 E 例 2-14 】 从文件中读出数据到存储器。 module testmemo:rry ; reg [ 7 : 0 ] memory [ 9 : 0 ] ; integer indexi initial begin $readmemb ( 咱四 . dat" , memory) ; for (i ndex=O; index,sigr时,signal,. . . . . .); 可 以 看 出 $monitor 与 $display 的 语 法 格 式 相 同 , 因 而 $monitor 的 参 数 说 明 可 参 照 $ctisplay 的 参 数说 明 。 该任务可用 来连续监控指定的信号 参 数 , 如 果发现其 中 的任一信号 发生变化, 则 系 统按照调用$monitor 时规定的格式, 在时间 步 结 束 时 显示整个信号衰。 可 以通 过 系 统任 务$monitoron 打开监控任务, 通过系统任务$monitoroff 关 闭 监控任务。 E 例 2-15 ] 系 统任 务$monitor。 ,. m 。 d u -e mytes t -lnteqer a,. hu ,. initi al beqin a=2; b=4 i forever begin 15 a=a+b; .5 b=a+ l; end end initial 140 $ finishi initial begin $monitor ( $time, " ac::毛d, b=奄d" , a , b ) • , end end.rnodule 输出结果为: ι 骨 品 骨 晶 霄 品"品·'"" a'' ι ' 0 a= 5 a= 10 4 a= 吨吨吨飞l''串』』5050 d a= a= a= a= 、5 d a= L b= ι bz ι, b= AA叮MMZr万 143, b= 7 、43, b= 吨吨F,,Dι』775, , , b= b= b= --AaME - 2n o 2n o (2) 仿真结束任务 Verilog HDL 中 有两个系统任务可 以 用 来结束仿真: $finish 和$stop。 $finish 用 来终止仿真榕的运行, 结束仿真过辑返回到操作 系 统 。 $stop 暂时挂起仿真 器 , 进入 Verilog 界面 , 可 以通过输入相应命令使仿 真继续运行。 第 2 章 V町胁g E 例 2-16) 仿真结束任务 。 --nit- a l beq-­ a cl 。 c bh B 唱·­ b nu h ..品斟..'_.肉q.,ιn内unnu u 霄 d ν u 户户hRvVCaMLtin。pi·'s ., end /1需要完成的任务 / / 暂停仿真并进入交互方式 / / 结束仿真,任务 4. 时间函蚊 ( I ) 时间标度函数 Verilog HDL 提供 了 两 种 时 间 标 度 函 数 : $timefonnat 和$printtimescale。 $timefonnat 用 于控制%t 格式如何显示时间信息, 语法格式 为 : $timef。zmat (〈unit〉, 〈pzeci si。n〉 , 〈suffix〉, 〈min-f ield-wid℃h〉} J 其 中 , 用 于指定时间单位, 其取值 范 围 为 0- - 1 5 , 各值所代表的时间单位如表 2-3 所示。 褒 2-3 的取值所代表的时间单位 tfrJJ 取 :J J镰亏』飞 " ,咱 电 '1 '章"单位 , I 町 4 • I- 。 ls ,';J�'y*�- 咱 .一 取L‘ 门』 也: .� 飞-� �_ ". �r r .. "… . 时--: "- 单-缸�!. � -8 lOns 1∞ms -9 Ins -2 lOms -10 n 1∞m -3 4 -s \\\"/n\'1/"\\\d l ms 1 ∞间 J/F | 10μs • , 飞 h\ ( -1 ) 'J\:_.!i"\: -J2 -13 「,r, � La • :ltF u �夕�i lOps I 1阳 l ∞fs -() l jlS -14 10fs -1 l∞ns -15 1 fs 指定所要显示时间信息的精度, 是诸如 " m "、 " ns " 之 类 的 字符 , ; 其 中 为 一大 于 0 的 整 数 , 用 来 指 定 所 产 生 随 机数 的 范 围 , flP -+ 1 到 - l o E 例 2-18) 系统函数$randomo Reg [ 7 : 0 ] 玄andoπLdata J always 1 1 00 random data=$random毛50 ; (2) 转换函数 有时需要将整数转换成实数 , 或将实数转换成整数, 或者用向盘形式来表示实数等。 Verilog HDL 提 供 了 许 多转 换 函 数 可 以方便实现上述功能。 • $rtio 通过 截断小 数 部 分 , 将实数转换成整 数 。 • $itor 将整数转换成实数。 • $realtobits 将实数转换成 64 位 的 实 数 向 量表示。 • $bitstoreal 将位模式转换 为 实 数 。 2.8 编译指令 与 C 语 言 中 的 编 译预处理指令一样, Verilog HDL 也提供 了 大量编译指令 。 通过这些 编 译指令, EDA 工 具 开 发 商 使得用他们的工具解释 Verilog HDL 模型变得相当 容 易 。 值得 注意的儿点是: · 所有的 Verilog 编 译 指 令 都 以 符号 ( ' ) 开 头 , 它也叫做重音符 号 。 • Verilog 编译指令的末尾不需要加分 号 ( : ) 。 • Verilog 编译指令对所有被编译 的 文件都有 效 , 直到有另外 的编译指令取代它 , 或 者 是整 个编 译 结 束 。 Verilog HDL 提 供 了 以下大致 9 种编译指令。 • 第 2 章 VeriI啕 HDι ‘铺睛 1. 单元模块定义指令 • 单元模块 定义指令包括两条指令: 'celldefme 和'endcelJdefmeo 这两条指令 用于将模块定 义 为 单 元模块 , 一般是成对 出 现 的 , 后 者 用 于 结 束 定 义 。 单 元模块 ( ceU ) 向用 于某些 PLI 程序 中 。 在一个单一源文件描述中 , 可 以 出 现多 对这样的 指 令 对 。 'celldefine 和'endcelldefme 指令对可以 出现在源文件描述中 的任何地方, i日 推荐的 做法是将这些语句放在校块定义的外面。 注意z 指令'resetall ,( 后 面将会详述 ) 包含了 tenl也elldefine 指令的 功 能. 2. 默认线网类型声 明指令 默认线 网 类 型 声 明 指令'default-nettype 为 隐 含 线 网 类型 的模块指定 线 附 类 型 。 '已· 只 能 放在模块定 义 的 外面 。 如 果一个源文件描述内 只有一条'default_nettype 指令, 那 么 该指令 指 定 的 线 网 类型对其后面的所有源程序都有效 。 当然 Veri10g HDL 允许在一个源文件描述 内 有 多 条 'defhulLnettype 指 令 , 此 时 每 一 段 源 程 序 的 默 认 线 网 类 型 受 其 前 面 段 近 的 'default-newpe 指令控制 。 'dehulLnetqpe 指令的 语法格 式 为 : ' de fau l t-nettype 〈net-type〉 参数 为 线 网 类 型 wire、 川 、 triO、 wand、 triand、 wor、 trior、 ireg、 none 巾 的 一种。 如 果源程序没有使用'default_nettype 指令或者使用 了 'resetall 指令, 那 么 隐含 的 线 网 类 型默认为 wireb 如 果选择 none , 那么所有的线 网类型都需要显示声明 , 如 果没 有显示声明 则会有错误产生。 3. 宏编译指令 宏编译指令包括两条指令'defioe 军U'undefo 一个文本宏 替换可 以非 常方便地代替经常使用 的一个文本块 。 例 如 , 1-E 整篇源程序描 述 的 多 个地方如 果频繁使用 某一数字常萃, 而要对该数字常 旦-进行修改是 比较烦琐 的 , 但 是如果使用文本宏代替该常虫, 那么只需要在一个地方对文本宏逊行修改就可以[, 非常 方便 。 一 个文本宏不会受指令'resetaJl 影 响 . ( 1 ) 'de'fine 指令 〈 宏 定 义 指令 〉 'define 指令生成一个 文本宏 (macro )。 该指令既可 以放在模块 定 义 内 部 , 也 可 以 放.(1: 模块定 义之外 。 如 果 已经 定 义 了 一个文本宏 , 那 么 在 它 的 宏 名 ( macro-name 〉 之前加上 珩 音符号 〈寸, 就可 以在源程序 巾 引 用 该文本宏。 编译器编译时将会 自 动 用 相应文本块代铃 字 符 串 'macr。一nameo Verilog HDL 中 的 所有编译指令部被看做预定 义 的 宏 么 , 粟,将一个编 译指令震新 立主 义 为一个宏名 是非法的 。 一 个文本宏定义可以带有参数, 这样就允许 为 每一 \ 35 \ 应用程摩设计实伊跚讲 个单独的应用也制文本宏。 文本宏定义的语法格式如下: ' de f ine < text macro name> < text macro name> : 宏 名 , 其语法格式 为 : text-IIlacr。-identi fiex [ 〈 list-。E-f。口na1_argumen巳s > ] text-macro-identifier: 宏 标 识 符 , 要 求 是 简 单 标 识 符 , < List_of_formal_arguments > 为形参列表。 一旦一个宏名被定义, 它就可 以在源程序的任何地方被使用 , 没有范围 限制。 : 宏 文 本 , 可 以 是 与 宏 名 同行 的任意指定 文 本 。 如 果指 定 的 文本翅过一 行, 那 么 新 的一行需要 以反斜杠 (\) 作为起始。 这样反斜杠后面的文本也将作为宏文本的 一部分, 参与宏替换。 否则, 如果新 的一行不是以反斜杠开始, 那 么 该行的文本就不属于 宏文本, 而宏文 本在上一行就结 束 了 。 反斜杠并不参与宏替换 , 编译时, 它将被忽略。 如 果宏文 本包含 了一个 单行注释语句 ( 以 " 1/ " 开 始 的注释语句 ), 那 么 该注释语句并不属于 替换文本, 编 译时不参与替换。 宏文本可以是空 白 , 在这种情况下, 文本宏被定义为空, 当这样的宏被使用 时 , 没有文本参与替换。 当形式参数被用 来 定 义文本 宏 时 , 该形参 的 作 用 范 围 将 货 穿 整 个 宏 文 本。 宏 文 本 巾 的 形式参数可 以放 与标识符同样的方式来使用 。 文本宏调用 的语法格式如下: ' text macro LdentiZ Ler { 〈 l ist-。f-actua l-Ja zgurnents 〉 ] 注意 : 与 宏 定义不 同 的定, 在· 岳王LMuo-i伽ntifier 之前加占了 ( 吟, 而且参数JI) 农 由 < list_of_forma1_arguments >改为〈 lisLbLacωal_arguments >, 即 由 形 参 列 表 改为 实 参 列表. 这样在编译 过后 , 如果宏文本带有参数, 那 么 所有 的 形 参都被相 应 的 实 参值所代替. 宏文本不能作为下列词法标记的一部分进行宏 替换, 也就是不能用 宏文本分割下列词 法标记。 . 注释 ( Comment臼s )沁: . 数值 (Num . 字 符 串 〈ωStr悦in鸣gsω ); · 标以符 ( Identifiers ); · 关键宇 ( Keywords ); · 操作符 ( Operators )。 下面举例 说 明 宏 指 令'defineo / 36 � 第 2 章 Verflog HD,也 E 例 2- 1 9 】 宏指令'define。 ' define wordsize 8 reg [ l : ' wordsize] data; / /def主ne a nand with variable delay ' define var nand (dly) nand tdly ' va r_nand ( 2 ) g121 ( q2 1 , n 1 0 , n 1 1 ) ; ' va r_nand ( 5 ) g122 (q22, n10, n1 1 ) ; 下面是非法的宏指令使用。 ' define first ha1f tlstart o f string $display ( ' first_half end of string " ) ; 下 面 有 几 点 是 需 要 读 者注 意 的 。 · 编译时每一个实 参是照字 面意义逐字取代形参 的 。 因此 当一个表达式被用做实 参 时, 该表达式将按照它的完整形式取代形参。 如果一个形参在宏文本里被多 次使用 , 将会导致该形参对应的表达式实参被 多 次计算。 下面是表达式实参应 用 的例子。 E 例 2-20 1 表达式实参。 ' de fine my-square {X} ( ( X } 曹 (x) ) n = ' my_square (a+b) 进行宏替换后, 相应的宏将扩展为: n .: ( (a+b) * (a+b) ) ; 在此, 表达式 a+b 将被计算两次。 如果将宏定义修改为: - define my-square { x ) ( X 青 x ) n 嚣 ' my-squaze (a+b ) J 进行宏替换后, 相应的宏将扩展为: n = ( a+b舍a+b ) ; 由此得到的宏替换可能与用户 需要得剑的结果大相径庭。 因此当使用表达式作为实参 时 , 为避免产生歧义, 最好是在 宏 定 义 的 宏 文 本 中 为形参加上括号 ct o 飞 · 字11 deftne "是一个编译指令关键字 , 但它 并 不属于标准关键字集 , 因此 Verilog HDL 源程序 中 的标准标识符可 以使用编译指令关键字 同 样 的 名 字 〈 当 然并不推将读者 这样做〉。 下 面 的 几 个 问 题值得读 者 考 虑 : 》 宏 名 不 能取与编译指令关键字 相 同 的 名 字 : 》 宏 名 可 以 被再用 做普通标识符。 例如 signaLname 与'signal..n. ame 是 不 同 的 : .\ 37 \ �绿洲崎 刷. 舰郎郎十实伊跚诩 》 文本宏可 以被重复定 义 。 如 果在源文本中对同一宏名进行 了 多 次定义 , 编译 时如遇到该宏 名 , 将会使用藏近一次定 义的宏文本做宏替换。 · 与 C 民 数一样 , Veri10g HDL 允许宏嵌套, 即在一 个宏 定 义 的 宏 文 本 巾 可 以包含其 他的文本宏。 但是该被包含 的宏儿有在包含它的宏被调用后才会进行宏替换, 而 不 是在包含它的宏被定义的 时候进行宏替换。 宏不 允许递归调用 , 即 宏 文 本 内 不 能包含它 自 己本身。 ( 2 ) 'undef 指令 ( 取消 宏 定 义指令 〉 指令'undef 用 来 取 消 先 前 二主 义 的 宏 。 如 果 先 前并没使用 指令'define 进行宏 定 义 , 那 么 现在使用 'undef 指令将会导 致一个警 告 。 'undef 指令 的 语法格式如下 : ' undef text macro �dentifier 一个 取 消 了 的宏没有值, 就像它未被做定 义一样。 4. 条件编译指令 条件编译指令包括'ifdef、 'else、 'elsif、 'endif、 'ifndef.。 这些指令用来控制 VeriJog HDL 的源程序代码行是 否 参 与 编 译 。 'ifdef指令用 来检测一个宏 名 桂否被定 义过。 如 果 宏 名 已经 被 定 义过 , 那 么跟在'ifdef 指令后的代码行就被包含 参 与 编 译 。 如 果一个宏名 未 曾 被定 义 , 而 且存在一个'else 指令, 那 么'else 指令后面 的代码行将 参 与 编 译 。 'ifndef 指令也是 用来检 测 宏 名 是否被定义过。 如 果 宏 名 术 曾 被 定 义 过 冒 那么跟在'凶ldef 指令后 的代码行就被包含 参 与 编 译 。 如 果一个宏 名 已经被定 义过, 而且存在一个'else 指令, 那么'else 指令后面的代 码行将参与编译。 如果再征'elsif 指令 〈 注意不是'else), 编译器将会检测宏名是否被定义过。 如果宏 名 已经 被定义, 那 么跟在'elsjf 后面的代码行将参与编译c 'elsif指令等效 I二'else 'ifdef …. 'endif指令序列, 但是它不需要一条成对出现的'endif 指令 。 这条指令之前必必、须有一条'i剧阳ef且或立者 以上这生些些指令可 以 出 现在源程序【中护 的任何地方。 以 下 几种情况可能需要使用 条件编译 指令。 · 选择一 个模块不 同 的 描述法 , 比如行 为 级 、 结 构级或者 开 关级描述: · 选择 不同的时序必结构信息: • 为一个仿真选择不同的激励 。 条件编译指令有如下的语法格式。 'ifde f 指 令 : ' ifdef text macro identifler 主 fdef-g roup-。f-ll nes { - e l si f tex℃-rnacr。-ident i E Ler elsi f-qr。up-of-l ines } { ' else el se_group一。 f-lines l ' endif / 38 泛 第 2 章 V町tk啕 tifndef 指令: ' ifndef text macro identifier ifndef二group一。f lines { ' el s i f text-tTtacr。-i dentifier els i f-group-。f-lines } { ' else e lse-qroup-。f-lines ] ' endif texLmacro-identiner 是 Verilog HDL 的 简单标识符 。 ifdef_group_of_ lines、 eLsif_group_ otlines、 e�e�oup_of_lines、 ilhdef�oup_of_lines 都 是 Verilog HDL 源程序描述语句。 'else 和'els证编译指令及跟在它们 后 面 的 源程序描述语句都是可选项 。 此外, 'i阳ef、 'ifndef、 'else、 'elsif 和'endif 这些指令还允许嵌套使 用 。 下面是一些条件编译指令使用 的 例 子 。 E例 2-21 】 'ifdef 指 令 的 简 单使 用 。 module and_op 俑 , b , c) i output a i input b, Ci ' ifdef behavio乞al wire a = b & Ci ' else and al ( a , b , c ) ; ' endif endmodu l e E 例 2-22 ) 条件编译指令嵌套 。 module testl (out) i 。utput out i ' define wow 。 define nest一one ' define second nest ' de fine nest 巳w。 - ' ifdef wow initial Sdisplay ( rlwow is defined" ) i ' i fdef nest one initial $display ( " nest_one is defined" ) ; ' ifdef nest tw。 initial $display ( H nest-tw。 is def ined,. } ; ' else initial $diSPLay { ··nest-tw。 is not defined-- ) ; ' endif ' else init.ial Sdisplay ( " nest_one 1s not defined" ) ; ' endif 队 39 \ ' else initial $display ( "wow i5 not defined" ) ; ' ifdef second nest - initial $display { e-nest-two is defined,, ) ; ' else initial $display { "nest-two is n。t defined" ) ; , endi f ' end1f endmodule 仿 真结 果 为 : i wow i 5 defined 排 nest one 1s defined i ne5t two i 5 defined - E 例 2-23 1 条件编译指令链的嵌套。 module test; ' ifdef first block ' i fndef second nest - initial $display ( " first少lock i 5 defined" ) ; ' e 1 5e initial $display v- f i xst-block and sec。nd-nest defined,. ) ; ' endif ' el s i f second-block init主al $display { " second-block defined, fiESt-block i s not" } J ' else ' i fnde f last-result initial $display ( " f ixst-bl。ck, sec。nd-bL。ck, last result n。℃ defined . " ) i ' elsif real last - initial $display { " fiESt-bl。ck, second-bl。ck n。t defined, last-result and real-last defined . " ) i 'else initial $display ( "Only last_result defined ! " ) ; ' end1f ' endif endmodu l e 仿真输 出 结 果 为 : i first-block, second block, last result not defined. 一 第 2 章 Ve时l句 HDI.J 5. 文件包含指令 Verilog HDL 中 的 文件包 含指令'include 与 C 语言中 的预编译指令#include 类似, 在编 译 时 , 将其他文件 中 的源程序 的 完整 内 容插 入 当 前的源文件 。 这样做的结 果也就相 当 于将 其他文件中 的螺程序 内 容复制到 当 前 文 件 中 出 现指令'incIude 的地方。 'include 编 译指令可 以将一些全局通用 的 定 义或任务包含进文件 中 , 而不用为每一个文件都编写一段重复的代 码 〈 指这些全局通 用 的 定 义或任 务 〉 。 使用'include 指令的好处是: · 提供了 一个完整的配置管理: · 改善 了 Verilog HDL 源程序 的组织结 构 : · 便于 Veri log HDL 源程序的维护 。 'include 指令语法格式如下: ' include " file name" 'include 指 令 可 以 放 在 Verilog HDL 源程序 中任何地方。 nie-name 是被包含 进 当 前 源 文件的其他文件名 。 该文件名可以是完全的或者相对的路径名 。 只有空白或者注释可以出 现在'include 指令的 同一行. 一个被包 含 的 文 件 内 部也可 以使用'ínclude 指令包含其他的文 件, 这就叫做包含嵌套。 嵌套的层数是有限制的 , 这样的限制层数最小为 15。 下例是文件包含的例 子。 【 例 2-24) 文件包含指令. //文件 f�leA . v 的 内 容 ' de f i ne WORDS IZE 8 function [WORDSIZE- l : O l mul l ( inputl , input 2 ) ; 一.. endfunction / / 文件 fileB . v 的内容 rnodule f i leB ( i n l , in2 , ou t ) i ' i nclude " f ileA . V " wire ( 2 肯WORDS IZE- l : 0 ] t臼np; assign temp=rnul l ( inl, 主n2) ; •••••• endrnodule • 6. 复位编译指令'resetall 在编 译 过程中一 国L 遇到'resetall 复位编译指令 , 所 有的编译 指 令 部 被 设 营垒IJ默认倪。 这 在编译一个特定的源文件, 只要求激活某吨指令时是非常有用的 。 推荐的做法 是妃'rese创1 指令放在每个源文件的开始, 而 让 需 要 的 编 译指令紧随其后。 \ 41 \ /f建制洒泪」 应用邵阳则刷 7. 行号编译指令'Iine 行号编译指令'Line 用 来 重 置 当 前文件的 当 前行号和 文件名 。 如果 当 前的文件已经被修 改 ( 如添加或缩减代码行 ) , 那么指令'Iine 就可 以用 来映射原始文件中 的位置。 一旦指定 了 新的行号和文件名 , 编 译器就可以根据新的行号和文件 名 查 阅到原始源文件中 的位置。 例 如 , 源代码调试中的错误信息能够提示用 户实际的原始行号。 行号编译指令'Iine 的语法 格式如 下 : ' line number n f i l e n田ne" level 行 号编 译指令'line 可 以 放 在 Verilog HDL 源程序 中 任何地方。 参数 number ( 行 号 〉 是 指令'Line 下一行代码的新行号 。 参数 目leJme ( 文件名 〉 是文件的 新名 字 , 文件名 可 以 是 一个完全或者相对路径名 。 参 数 level 指示进入一个被包含文件 ( leveJ 值 为 1 ) , 退 出一个 被包含文件 C level 值为 刀 , 或者这两者都不是 ( level 值为 0 ) 。 行 号编译指令'line 的结果 并 不受指令'而何时1 影响 。 当 编 译 器 处理文件的其余部分或新文 件 时 , 每读一行 , 行 号应 当 远 加 1 , 文 件 名 也应 当 更 新 为 当 前被处理的文件名 。 当 开始读 include 包含文件时, 应 当 保 存 当 前的 行 号 和 文 件名 , 以便在读完 include 包含文件时恢复行弯和文件名 。 被吏新的行 号 和 文 件 名 信息可 以通过 PLI 程序接 口 访 问 。 当 然库搜索 机制并不受fline 编 译指令的影响。 8. 时间标度指令 'timescale 时 间 标度指令'timescale 用 于指定其后模块的 时 间 单位 和 时 间 精度 。 时 间单位是诸如仿 真和 延迟时间值的度量单位。 在 同一个设计 中 , 有可能要使用 不同时间单位的模块, 而下 列 的时间标度编译指令是非常有用 的。 · 编 译 指令'timescale 在 设 计 中 用 于指定筷块的时间 单 位和 精度 : • 系统任务$printtimescale 显示模块 的 时 间 单位和精度: • 系统函 数$time 、 $realtime, 以 及 系 统任务$timefonnat 和%t 格式规范用于指定时间 信息如何被汇报。 时 间 标度指 令'timescale 对跟随其后的所有模块都生效 , 直 到 有 另 一 条指令'timescale 出 现 为 止 。 如 果 没有使用 指令'timescale 或者 已经被'resetall 指令复位, 那 么 时 间 单位和精 度就由 仿 真器指定 。 如果某些模块使用 指令ltimescale, 而 另 外一些模块不使用 , 贝IJ会有错 误发生。 指令'timescale 的语法格式如 下 : ' timescale time_unit I tì.me_:precision 时间单位参数 time unit 时旨定 时 间 和 延迟的度量单位。 时间精 度参数 time_precìsion 指定 延迟时间值被用 于仿真之前 如 何 舍 入 。 在, 设 计 中 共 有最 小 时 间 精度参数 的'timescale 指令, 决定仿真 的时间单位精度。 需要注意的是时间精度 参 数的精确度不能小于 时 间 单位 参数 的 精 确度 , 也就是参数 time_precision 不能指定一 个 比参数 time-unit 更氏的时间单位 。 / 42 1 第 2 章 VerUog HDL 时间单位参数和时间精度参数都出整数和度重单位两部分构成。 整数指定值的数虽级 大 小 , 合法的整数只能取 l 、 1 0 .!.或 1 00。 度量单位 由 字符 串 构 成 , 合 法 的 字 符 串 有 s、 ms、 闷 、 ns、 ps 旦旦 缸 , 它们代表 的 时 间度量单位分 别 是 在þ 、 毫秒、 微 秒 、 纳 在j、 、 皮秒或飞秒。 下面举例说明指令'timescale 的 用 法 。 E 例 2-25】 时间标度指令'timescaJe。 ' timescale 1 0 n s / 1 ns module test ; reg seti parameter d = 1 . 5 5 ; initial b e q .A n 一 nu #d set 一­ #d set 咱 牛 end endmodule 指令'timescaJe 1 0 ns I 1 ns 指 定 了 模 块的测试时间单位 为 1 0凶 , 时间精度�J l ns。 因此 模 块 内 的 时间值都是 1 0ns 的 倍 数 , 对 小 子 1 05 的 部 分进行四舍五入。 根 据 时 间 精度 ( 1 ns ) 将 参 数 d 的值四 舍在入 , 即 由 1 .55 变 为 1 .6 。 荐信者在参数 d 巾 的 时 间 延i总值也就被换算成 1 60s ( 1 .6x 10 ns)。 所 以程序仿贞运行的结 果 是在仿真时刻 16ns 处 , 给寄存苦苦变革 set 赋值 0 , 在仿真时刻 32ns 处给 set 赋值 1 。 无 论时间标度 是 否 生效 , 参数 d 的值都保持不变。 9. 驱动编译指令·unconnected-drive 和'nounconnected」drive 所 有 出 现在指令'unconnected drive 不n'nounconnected 创刊 之 间 的 未连接的模块输入端 口 都被上拉到电源或在下拉到地而非标准的默认值。 指令'unconnected-drive 俯 有 参 数 , 口J在 pulll ( 上拉 〉 和 pullO ( 下 拉 〉 两 省 之 间 任选 一个。 'nounconnected-dEive 不 惜 参 数 t Jt 作 剧 是取消'mcomected-drive 的 ;主 义 。 这两条指 令应当成对出现, 而且只能放在楼块卢明之 外。 一般是将'uncomected-drive 放在模块声明 之前. 而将'nounconnecled drive 放在校块卢i归 之 后 。 2.9 数据类型 在 Verilog HDL 中 , 数据类垠.被 设计剧 来表示数字硬件也路中数据的存储和传输。 2.9. 1 线网 ( Net ) 和 ( Variable ) 在 Verilog HDL 中 , 根据赋{贞不1 对值的保持方式不同, 可将数据 类 啊 1:要分为两大类: 线 同 ( Net ) 和变量 ( Variable ) 。 这两类数据 山代 表 了 不 同 的 硬件约 构 。 \ 43 \ 1 . 线网 C Net) 声 明 线 网 数据类型体现 了 结构实体 ( 比如门级元件〉 之 间 的物理连接 关 系 。 除 了 trireg net, 其他的线网类型都不能保存值。 相 反 , 线网类型数据的值是由它的驱动器 ( 比如一个连续 赋值或者是一个 门级元件〉 的值决定的 。 如 果 没有任何驱动器连接到线 网 上 , 那么它的值 就 为 高 阻 (z)o 只有一种情况例 外 , 那 就 是 当 线 网 为 trireg net 型 时 , 它将保持先前的驱动 值 。 Verilog HDL 禁止对 已经声明过的线网 、 变盘或参数再次声 明 。 线网 ( Net ) 声 明 的语 法格式如下 : net decLarati o n : : :::l net_type [ signed 1 r de工ay ] 工ist of一ηet identifiers ; 1 net-type [ d汇ive_strength J [ sì gned ] [ delay ] net_decl_assignments ; I net_type ( veçtored I scalared ] [ siqTIed ] ranqe [ delay I 工ist-o f一 L i s t-OE- ne� identifiers ; | net-type I drive-stzerlgth ] { vectored | scalared I I siqned I range [ delay j list-of-net-deel--assignments J I trireg [ charge_strength ] [ signed ) [ delay ) lis t二。 f-net-ident i f iers J l trizeg { drive-strenqUI ] [ signed ] [ delay ] l ist-。f- n e t-dec l-as siqnments ! tri zeq i charge-streng℃h ] [ vectored I scalared ] [ signed ] range • 〔 delay ] l i s L。 EJet identi f主ers ; I trireg [ d主ive strength ] [ vectored I scalared ) [ signed 1 range [ delay I li st-ofJ1et-deel-assiqnments net-type : : = supplyO I supplyl l tr主 , triand I trior I triO I tri l l wire 1 wand I wo主 dr主ve_strength : : = ( st主enqthO , st主ength1 ) I ( s trengthl , strengthO ) I ( strengthO , highzl ) I ( streng乞hl I hìghzO ) 1 ( highzO , strengthl ) 1 ( higbzl , strengthO ) strengthO : : = supplyO I s t rongO I pullO , weakO strengthl : : = supplyl I strongl I pul l l I weakl charqe-strenqth : : = ( small ) I ( medium ) I ( large ) delay : : = # delay-value | # ( delay-va lue [ , delay-value [ , delay-value ] ] ) delay_value : : = 11rlsiqTIed-numbez l pa汇ameter-identifier | specpazanLidentifier i mb1typmaxexpression l i st-。f-net-dec1-assignmerE℃ s : : E /ωA 第 2 章 Verilog net-decl-ass丰qEERIertt { , net-deel-as s iqEIITIer1ζ } list 。主 net identifiers : : = net identi f i e r [ dimension { dirnension } J { , net ident:i f i e r [ di.mension ( dimension ) J ) Elet-deel-as s i gnment : : = net-identi f iez = expression climension : : = [ dimension_constant_expressìon ; dimensi on_constant_expression ] range : : = { ITtsb c。astaRt-expzesslon : isb-constant-expression ] 针对上述声明做以下儿点说明。 ( 1 ) 符号 " ::= " 表示某项的定义: 方括号 " 口 " 表示该项为 可选项: 花括号 U { } " 表 示列表中 的 同类项: 符 号 lt l " 表示该项 的 另 外一种定 义形式。 ( 2 ) net_type 表示线闷型数据的类型。 ( 3 ) delay 指定仿真延迟 时 间 。 ( 4 ) drive_strength 指定线 网 型数据赋值时的驱动强度。 ( 5 ) strengthO 可 以取关键字 supplyO 、 strongO 、 pullO、 weakO 中 的 任何一个 ; S位ength l 可以取关键字 supply l 、 strong l 、 pull l 、 wωkl 中 的任何一个。 ( 6 ) charge_strength 用 来 指 定 所 保 持 电 荷 容 量 的 大 小 , 可 以 取 关 键 字 ( small ) 、 ( medium ) 、 ( l缸ge ) 中 的任一个。 ( 7 ) dimension 用 来指定数组的维度 。 ( 8 ) range 用 来指定数据 为 标盘或矢量。 若该项默认 , 表示数据类型 为 l 位的标量: 反之, 由 该项指定数据的 矢量形式。 有关线附声明的关键词较多 , 在后缕的章节将会详细讲述. 2 . 变量 ( Varíable ) 声 明 变量是数据存储元件的抽象 。 从一次赋值到下一次赋值之前, 变应;应当保持一个值不 变 。 程序 中 的 赋值语句将触发存储在数据元件 中 的值改变。 对 于 reg, time 和 ioteger 这些 变量型数据 类 型 , 它 们 的 初始值应当 是未知 ( x ) 的 e 对 于 rea1 和1 rea1time 变量型数据类型, 默 认 的 初始值是 0.0。 如 果使 用 变垦声明 赋值语旬 , 那 么变量将采用 这 个 卢 明 赋值语句所 赋的值作 为 初 值 , 这与 initiaJ 结构中 对变量的赋值等效。 ( 1 ) 整理变量声明 整型变盘常用 于对循环控制变量 的说明, 在算术运算巾被视为气进制补码形式的有符 号数。 整 型 数据 与 32 位 的 寄 有,器型数据在实际意 义上相 同 , 只是寄 ff器翻数据被当作无 符号数来处理。 整型变量的声明格式如下: 入 45 \ lfII1程席由?实倒糟说 i11℃eqer-deClarati。n : : = inte9ez l i s t--。f-mvaziable-identifierS J l i s t of variable identifiers : : = variable-type { , vaziable-type } vaEiable-type : : = variabl e-identi fiex { = c。nstant-express主。n ] I variable iden t i fier dimension { dimension } dimension : : ::; [ d imer1s ion-c。nstant-expression : dimension-c。nstant-expxessi。rl ] (2) 实数型变量声明 实数型数据在机器码表示法中 是浮点型数值, 可 用 于对延迟时 间 的 计算。 实数型变量 声 明 的格式如下 : real declaration : : = real l i s t of real iden t i f iers ; 1ist of real identifiers : : = zeal-type { , real-type ) zeal-t ype : : = zea l--identi fier [ = cons℃ant-expxess i。r1 1 I rea1 identi fier dimension { dimension } ( 3 ) 实时时间型变量:声明 实时时间型变量声明的格式如下: realLLrne declaration : : = realtime list o f rea1 identifiers ; _ ... - (4) 寄存器型变量声明 寄存器型变量对应的是具有状态保持作用 的硬件电路, 如触发器、 锁存器等。 寄存器 型变量与线 网 费1 数 据 的 区 别 主 要 在 于: 寄 存 器 型变量保持最后一次的赋值 , 而 线 网 型 数据 诺要有连续的驱动。 寄存器型变量声明的格式如下: reg_declaration : : = reg { s igned ] [ ranqe ] l i s t-。f-variable-identi EiexS J range : : = [ InsbECOTIStant-expressi。n : l sb-c。ns tant-express i。n ] ( 5 ) 时间型变量; 声 明 时间 型变量;与整型变量类似, 只是它是 64 位的无符号数。 时 间 型变量主要用于对仿 真时 间 的存储 与 计算处理 , 常 与 系统函 数$time 一起使用 。 时间 型变量声明 的格式如 下 : • 巳ime declaration : : = 一 - time l i s t o f variable-identifiers ; / 46 h 第 2 章 Vertlog HDL 有关变ill ( Variable) 声 明 , (f:后续 的主主节将会详细讲述。 2.9.2 ( Scalar ) 与 ( Vector ) 在一个 net 或 reg 型声 明 中 , 如 果没街指定范 围 , 就被看傲是 1 bit 位 宽 , 也就是通常 所说的标量 ( Scalar)。 边过指定 范 围 来声 明 多位 的 net 或 reg 型 数据 , 则称为 矢 盘 ( Vector )。 下 面着重讲述矢虽 ( Vector )。 1 . 矢量说明 矢 量 范 t自 由 常 量 表 达 式 来 说 明 。 [msb_constant_expression ( 最 高 位 常 量 表 达 到� ) : lsb_constant_expression ( 母低位常 盘表达式 ) ) 。 msb_constant_expression ( 最 高 位 常 盘 表 达 式 〉 代 表 范 围 的 左 侧 值 , 1sb一constanL expression ( 1&低位常量表达式〉 代表范围 的右侧值。 右 侧表达式的值可 以 大 于 、 等 于 、 d f左侧表达式的值。 net 和 reg 型 矢 盘遵循 以 2 为 棋 。n ) 的 乘右手算术运算法则 , 此处的 n 值 是 矢 盘 的 位 宽 。 net 和 reg 型 矢 量如 果没有被卢明 为有符号量或者连接到 一个 己卢l列 为 有 符号的数据端 n , 那么该矢虽被隐含当作无符号的量. 下例是有关矢姐:说明 的例 子。 E例 2-26 】 矢 虽 说 明 。 wand Wi / /标'段线阙'W (wand) tri ( 1 5 : Q ) busa ; / / 二 ,态 1 6 位总线 trireg ( smal l ) store i t i / / 一个小强度 ( sma l l ) 的电荷存储节点 reg a ; r / I 一个事jt庭寄存摇型变111 req [ 3 : 0 ) V i / / 一个 4 位的矢 盘寄存端变量, 出 v ( 3 ] , v [ 2 ] , v [ 汀 , v [ Q ) 构成 reg s igned [ 3 : 0 ] signed_regi //一个 4 位的有符号-矢虫型奇仔格变应. 其取值范围为 -8 到 7 reg [ - 1 : 4 ] b i // .个 6 位的矢哇型寄布黯变hl wire w 1 , W2 i // 卢明两个 net (wire 坐〉 数据 reg [ 4 : 0 ) x , y, z ; / / 卢 叨 3 个 5 忱的矢量却抒器�变 2. 矢量线网型数据的可访问性 vectored 和 sca]ared 是矢盐线 网 型或矢;最寄存器型数据声 明 巾 的 可边择关键字 。 如 果 这些关键字被使用 , 那 么 矢 量 的 某些操作就会受约 束 。 如 果:使用 关键字 vectored , 那 么 矢 蠢的位选择或部分位选择以及强度指定就被禁止, 而 PLI 就会认为数据对象未被展开。 如 果使用 关键字 scalared, 那 么 矢莹 的位或部分位选择就被 允 许 , PLl 认 为 数据对象将被展开 。 ;:i,IJ是使用关键字 vectored 和 scalared 的 例 子 。 E 例 2-27 ] 关键字 vectored 和 scaLared 。 tri scalared [ 63 : 0 ] bus 6 4 ; 1 /一个将被展 开 的数据总线 tri vectored [ 3 1 : 0 ] datai / /一个未被展开的鼓据总线 \ 47 \ 应用程廖由愤伊跚说 2.9.3 线网 ( Net ) 数据类型 1 . 强度 ( s甘'ength ) 在一个线网 型数据类 型 声 明 中 , 可 以指定两类强度 : 电荷毒: 强度 (charge strengtb ) 和 驱动强度 〈 由lve strength ) 0 • charge strength : 只 有 町ireg 线 闷 类 型 的 声 明 中 , 才 可 以使用该强度。 • drive strength : 只 有在一个线网 型数据 的 声 明 语句 中 对 数据对象进行 了 连续赋值 , 才可使用 该强度。 门级元件的声明 只能指定 由ive strengtho ( 1 ) 电荷量强度 ( ch缸ge streng也〉 一个 trireg 线网 型数据用子模拟电荷存储。 电荷量强度 可 由 下 面的关键字来指定 电容 量的相对大小: • small • medium .' Large 默认的 电衔强度为 mediumo 一个 EKeg 线 网 型 数据能够模拟一 个电荷存储节 点 , 该节点的 电荷量将随时间而逐渐 衰减。 对于一个 trireg 线 网 型数据在仿真时, 其 电荷衰减时 间 应 当 指 定 为 延迟时 间 。 下例 说 明 charge strength 的使用 。 E 例 2-281 cha鸣e strength 的 使 用 。 uizeq a J 「 nh F 「h [ 【 r- / / 芦明 一个 trireg 型线|吨数据 , 其电荷强度为 medium tri reg (large) #; ( 0 , 0 , 50) capl ; / / 声 明一个 EEireg 型线闷数据, 其电荷强度 为 large. // 电荷衰减时间为 50 个时间单位 trireg (smal l ) sìgn�d 曰 : 0 ) cap2 i 1 / 一 个 4 位有符 号 tri.reg 型线网 矢量数据声明 , 1 1 电荷强度 为 small ( 2 ) 驱动强度 ( drive strength ) 在一个线网型数据的声明语句中如果对数据对象进行了 连续赋值, 就可为声明 的 数据 对象指定驱动强度 。 关于驱动强庶的详细 说 明 , 请参阅 <<3.3 . 1 连续赋值 与过程赋值》。 2. 线网型数据的隐式声 明 如 果没有显式声明 , 那么在以下情况巾 , 一个默认线网型数据类型就被指定。 · 在一个端口 表达式的 声 明 中 , 如 果没有对端 口 的数据类型进行显式 说明 , 那 么默 认的端口 数据类型 就 为 阳e 型 , 同.默认的 wire 型矢茧的位宽 与矢雏型端 口 声 明 的 位宽相同。 · 在基本元件例化、 模块例 化 的端 口 列 表 l 卡 , 如 果 先前没有对端 口 的数据类型进行 / 48 h 第 2 章 Verilog HDL 显示说明 , 那么默认的端口 数据类型为线网型标盘。 · 如果一个标识符 出现在连续赋值 语旬 的左侧 , 而该标识符先 前 未 曾 被声 明 , 那么 该标识符的数据类型就被隐式声明为线网型标 盘 。 3. 线网型数据的初始化 线网 型数据的默认初始化值为 Zo 带有驱动的线网型数据应吗为它们的驱动输出指定 默认值。 町keg 线 网 型 数据是一个例外。 它的默认 初始化值为 X, 而且在声明语句 中 应 当 为 其指定 电荷量强度 ( small 、 medium 或 large )0 4. 线网型数据的类型 线 网 型数据的类型 如表 2-4 所示。 wire wand wor 表 2-4 线网型数据类型 时 lriand tnor 肘。 时l trtreg supplyO supply 1 ( 1 ) wire 和 创 wire 和 tri 都用 于连接电路元件。 wire 和 创 有相同 的语法和功能。 wire 型数据可 以被 单个的门级 元件或连续赋值所驱动 。 住i 型数据 可 以 被 多 个驱动源所驱动 。 一个 We 型数据或者一个 tri 型 数据 被 多 个 相 同 强度的驱动源驱动 时所导致的逻辑冲 突是产生一个未知量 ( x ) 。 表 2-5 是 wim 型数据和 tri 型数据 被 多 个驱动源驱动 时 的 真 值 表。 此处假定两个驱动源的强度 相 同 。 � ifì\ 4 飞N\',// 飞�'�JI 衰 2-5 线网型鼓据类型 wlre 和 tri 的真值表 wireltri 。 R z 。 。 且 " 。 x it x x x 且 x. z 。 x 2巳 ( 2 ) wand 、 triand 、 wor 和 trior wand 、 triand 、 wor 和 出or 都 用 于连线型逻辑约构建模。 当 有 多 个驱动源驱动 wand 和 triand 型数据 时 , 将产 生线与结构 。 如果: 驱动源中 任 - 个 为 0 , 那么线网 型数据 的 值将 为 0。 同 样 , 当 有 多 个驱动源驱动 wor 和 时or 型数据时, 将产生线或结 构。 如 果驱动源中任一个 为 1 , 那 么 线 网 型数据的值将 为 ] 0 wand 和 triand 有相同 的语法和功能, 而 wor 和 的or 也 有相同 的语法 和i功能。 表 2-6 和 表 2-7 分 别 为 具有 多 重驱动源驱动 时1 wand 和 triand 以 及 wor 和 trior 的 真 值 表 。 此处都假定两个驱动源的强度 相 同 。 .\ 49 \ ái丽白HDL 应睡廖设计跚跚到 褒 2-6 线网型蚊据类型 wand 和 triand 的真值亵 wandltriand 。 x ι 。 。 。 。 。 。 λ x 。 x 吨 x z 。 x ι 表 2-7 钱网型数据类型 wor 和 悦。r 的真值表 worJtrior 。 。 。 x 1. 3、 。 x J( z 。 、 h x z ( 3 ) 创reg trireg 线 网 也数据用 r存储一个值 , 以及 电荷仔储节点建模。 一个 trireg 线 网 J�l数据可 以处于驱动和电容性两种状态之一。 · 驱动状态 : 当军, 少被一 个驱动源驱动时 , trireg 线 网 型数据有 ·个值 ( 1 、 0 或 x )。 判决值 被 导 入 町ireg 型数据, 也就是 trireg 骂骂线网 的驱动值。 • 电容性状态: 如 果 所有驱动源 部处于高阻状态 ( z ) , 因reg 线 网 组数据贝Ij保持它最 后 的 驱动值。 高阻值不会从驱动源 导 入 tr让eg 线 网 型 数据。 根据 trireg 线 网 型数据声 明 语 句 巾 的指定 , 位img 线 网 型数据处于 电容性状态 时其电荷 最强度 可 以 是 small、 medium � largeo 同 样 , 住keg 线网 型数据处于驱动状 态 时 , 丰良据驱 动源的强度F 其驱动强度 可 以 是 supply 、 strong、 pull 或 weako 如 剧 2-] J开示为包含一个 出reg 线网型数据 〈 驱动强度为 medium ) 、 驱动源和仿真结 果(l'..r示意 图 。 wirc a wirt: b SimulatJon lImc 。 nmo&J 、�.H 'C C - ‘ 日回QG T 时吨 d wuea wire b wlre c stntO g I d trireg strong 1 10 。 H1Z medium I 阁 2- 1 一 个 trireg 的 仿真值和它的驱动说 针对上图做两点说明。 · 在仿真时刻 0, wire a 和 wire b 值 部 为 1 , 开关管 nmos 1 :和 nmos2 部导通, 同 时 被 wire c 瓦连 , 一 个强度为 stTOJ屯 的{t1 1 从 l:j 门传送到 lrireg do · 在仿 页,时 刻 1 0, wire a 值变为 0 , nmos l 关 断 了 与 门 和I wire c 的连梭, 从 而 wire c 的 值 变 为 高 阻 ( z ) o wire b 保持为 1 , nmos2 继续导j函, 因此 wire c 保持和 的reg d / 50 / • 第 2 章 Verilog 刚到L 的连接。 但是高阻值 ( z ) 不会从 wire c 传送到 trireg d。 相 反 , trireg d 进入 电 容 性状态, 存储它最后的驱动值 1 t 该驱动值 1 的强度为 medium。 ① 电容性线网 一个 电容性线网是两个或更多 个 trireg 之 间 的互连线 网 。 如 果 电容性线 网 中 的每一个 trireg 都处于 电容性状态, 那 么 在 时reg 之 间 可 以 互 相 传递逻辑和 强!支值。 如 图 2-2 所示为 一个电容性线 网 的示意阁 , 在该线网 '1' , 某些 trireg 的逻辑值改变 了 其他|司等或更小强度 trireg 的逻辑值。 线网型数据 trireg_la 电荷盐强度为 恼兽, 回reg_me l 、 trireg_me2 电荷 1il 强度 为 medium, trireg_sm 电荷最强度为 smal1。 仿真结 果按事件发生的顺序排列 如 下 : • WlJ可� a w irc b W.U"e C wire d Simulalion 由ne 。 10 20 30 40 50 I nmos -』 1l 位缸ún 1 τ - •• •• t trireg_la 町四可:g_sm nmos 2 幅� Wlre ß wlre b τ τ traniO 2 lDreg_me l trireg_m2e Wlre c WlCCI d trire&.Ja trueg_sm trircg_mel 时reg_m2 • ,' \ 回 。 J"t(.·(-lJJ\ I 回 /:!飞((\.,J")1. 1 :'1 rl' II 1 。 。 LJU 。 。 回 。 。 。 。 。 。 囚 。 。 。 回囚 囚 图 2-2 也容性线网的仿真结果 · 在仿真时刻 0, wire a 和 wire b 值 为 1 , wire c 驱动值 1 剑 trireg_la 和 trir鸣-srn; wire d 驱动值 l 到 trireg_me l 和 trireg_me2。 · 在仿真时刻 1 0, wire b 的值变为 O. 将 trireg_SID 和 的reg_me2 与它们的驱动源断 开, 这两个 的reg 进入 电容性状态, 并且保持它们最后 的驱动值 l 。 · 在仿真时刻 20, wire c 驱动值 0 到 时reg_lao · 在仿真时刻 30, wire d 驱动值 0 剑 创reg_me l 。 · 在仿真时刻 40, wire a 的值变为 0, 将 回reg_ta 和 trireg_me l 与它们的驱动源断开, 这两个 国reg 进 入 电容性状态 , 并 且保持它们最后 的驱动值 00 · 在仿真时刻 50, wire b 的 值变为 I , 将 时reg_sm 和 住ireg_la 连接, 这两个 trireg \ 51 \ /己制蝙胞 回瞿附f实例糯诩 有 不 同 的 电荷量强度并且保存不同的值。 这个连接将 导致电荷量强度更小的 trireg 保存电荷量强度更大的 住img 的值, 从而使 时reg_Stn 保存值 00 wire b 值 由 O 变为 1 也将 trireg_me 1 :和 trireg_me2 连接, 这两个 trireg 有 相 同 的 电荷量强度而保存不 同 的值。 该连接将导致 时eg_me l 和 trireιme2 的值都变为未知 ( x ) 。 在电容性线 网 中 , 电荷盘强度将会从较大强度的 住img 传递到较小强度 的 trireg。 图 2-3 显示 了 一个电容性网络和它 的 仿 真结 果 。 在该图 中 , 时reg一La 电荷量强度为 large, trireg_sm 电荷量强度为 small, 仿 真结 果 如 下 : · 在 仿 真时刻 0, wire a , wire b 和 wire c 值为 L wire a 驱动值 1 ( 驱动强度为 strong) 到 回reg_la 和 廿keg-sm。 • 在仿真时刻 10, wire b 的值变为 0. 将 trireg_la 和 trireg_sm 与 wire a 断 开 , trireg_)a 和 阳eg_srn 都进入 电容性状态 , 因 为它们仍然通过 mMnj 保持连接, 所 以两个 trireg 共享 町ireg_la 的 电荷量强度 largeo • 在仿真时刻 20, wire c 变 为 0, 断 开 创reg_Ja 和 trtea-sm, 町ireLSIn 不再共事 时reg_la 的 电荷量强度 !町ge , 而 是保持一个 small 的 电荷量强度。 • 在仿真时刻 30, wire c 变 为 1 , 连接 trireg_la 和 trireg_sm, 从而它们 应 当 共享电荷 量强度 1a电eo • 在仿真时刻 40, wire c 再次变为 0, 断开 trireg_la 和 trireg_sm。 因reg_sm 不再共 享 町甘eg_la 的 电荷量强度 large , 而是保持一个 small 的 电荷;最强度。 一L j_ WI.I'e Ð- 厂I 旦旦旦 l 一τL I1 b:Îre� 理豆.!l Ja 2 主 T ' Simu larion ûme wire a 。 stJ:ong 1 -4 nM- strong I hυ冉,ι·· - strong 1 nu、龟, strong 1 40 stroog I wirc b 。 。 。 。 wire c 。 。 trires_1a stlong 1 IMge 1 targe 1 largo 1 large 1 时reg_sm 叫 一峙 一 叫 一些 叫 图 2�3 电荷其亭的仿真结果 ② 理想电容性状态和 电荷衰减 一个 町ireg 线 网 可能不确定保持它的值, 或者电荷量会随着时间而衰减。 电荷量衰减 • 的 仿 真 时 间 是 在 trireg 线 网 声 明 语 句 中 的 延迟时 间 中 指 定 的 。 有关 电荷量衰减的详细 说 明 , 请参见后续章节。 / 52 J儿 第 2 章 Ve闹。g HDL 〉队 (4) 创0 和 创l trÎO 和 lri l 用 于带有上拉或下拉电阻的设备建棋 。 当 没有驱动源驱动一个 triO 线网时 , 该线网值为 0: 同样 , 没有驱动源驱动一个 时l 线 网 时 , 该线网值 为 l 。 线网值 的驱动强 度 都 为 pull。 而0 等效 r这样一个 wire ��i线 网 : 何一个强度为 pull 的 O 值连续驱动该 wm。 同样, 的 i 等效于这样一个 wire 型线 网 : 有一个强度为 pull 的 l 值连续驱动该 wire, 关于 triO 和 时 1 的 真值表分别如表 2-8 和表 2-9 所示。 表 2-8 时O 真值亵 时0 。 x ι 。 。 x x 。 可t x x .� x 3、 x z 。 x 。 表 2-9 tri1 真值表 时l 。 x z 。 。 x x 。 x x x x 其 x x z 。 x ( 5 ) supplyO 矛日 supply l supplyO 和 supply l 线 网 用 于 电路中 的 电源建锁。 它们的驱动强度 都为 supplyo 2.9.4 变量! ( Variable ) 数据类型 1 . 寄存器型变量 在 Verilog HDL 巾 , 寄 存 器 型 ( reg) 变髦的赋但是 由 过程赋值语句j实现的 。 由 于 寄 存 吉普型变堡'能够在两次赋值操作之间 保排一个值不变, 因此它 可 以 用 于硬件寄仔器建模o ill 沿敏感 〈 如触发器 〉 和 电 平敏感 ( 如 RS 和l透明锁得器 〉 的 行,储元件部可 以 用 寄 存器型变 ι来建模 。 11斗然 寄 存 器 型 变;在也不一定就用来描述有储元件 , 它也可以描述组合逻辑 。 有 关 reg 的 共体应用将会在 3.4 节 " 赋值语句 " 巾详细| 阐述。 2. 整型、 实型、 时 间 型和实时时间型变 关 于寄存器型 (reg )、 整型 ( integer) 、 实型 (real ) 、 时间到 (time ) 和实时时间 翻 ( realtime ) 变量的声明语法格式 己在 2.9. 1 节中详细说明。 整型变量是一个处理数值的通用 变 匠 , fq它并 不对应任何硬件寄存器。 时间型变量用 J二存储和处理仿真时间缸, 因为在仿真时往往需要枪测 时序和对程序进行调试。 时间 型变盘通常是和系统函 数$time 联合使用 的。 整型和时间型变坠 的赋值方式与寄存器型变量的赋值方式相问, 即对这几种变盐的赋值都应当 采用过程赋值语 \ 53 \ 应用霍廖设计实伊腾讲 句 。 时间型变量与一个 64 位的寄存器矢量 〈最低位为 0) 等效, 都属于无符号量: 应当使用 无符号算术运算对它们进行操作。 相 反 , 整型交盈被作为一个有符号数, 当然在形式上与 32 位的寄存器矢量相 同 , 其最低位为 0: 对整地变量应当使用二进制补码形式的算术运算操作 。 实型变茧可以用在与整型或时间型变最同样的地方, 只是以下几点限制是需要读者注意的。 · 并 不是所有的 Verilog HDL 操作符都可以用 于实型变量。 至于哪些操作符可以用 于实数或实型变髦, 请参见后面的宣言节。 · 实 型变;且在声 明 时不能指定范围 。 · 实 型 变量有一个默认的初 始化值 00 实时时间型变量与实型变垦在声明时意义相 间 , 可以在使用 时 qJ矢。 下 例 是 这儿种变;茧 的 声 明 举 例 甸 E 例 2-29 1 变量的 声 明 。 integer a; time last_chng; real float ; realtirne rtirne ; / /鞭tt'1变量 11时间 型变茧 1 / 实 里变豆 / /实时时间交量 ( 1 ) 操作符和实数 对实数和实 型变最进行逻辑或关系运算得到的纠果 将是一个一 位 的 标茧值。 并 不 是所 有 的 Verilog HDL 操作符都可 以在表沾式巾 对实数和 实型变量进行操作。 在下列情况 下 , 实型常量和实型变量是被祭止的. - i在沿描述符 ( posedge 、 negedge ) 不 能应用 于实型变量 。 · 变量被声 明 为 实型时 , 不能使用 位选择战部 分 位选择 。 • 对 矢 结进行位选择或部分1�L选择 时 , 索 引 表达2飞不能为实数。 ( 2 ) 实数和!程数的转换 实却{转换 为 整 数 应 当 对 实 数 的 小 数 部 分进行 四 合 有, 入 , 而不 是在接将小数部分去押。 当实数被赋给一个 整数变屋时 , 将产生一个隐式的类型转换。 如 果实 数 的 小 数 部 分恰好是 0.5 , 那么经过四舍五入, 它应当成为 1 。 当一个表达式被赋给实数变盘 时 , 也将产生一个 |稳式转换, 在转换时, 线 同 或变 量 各个只J x 或 z 的忧郁将被看做 00 2.9.5 数组 ( Array ) 类型 一个钱闷型数织或变量型 数组的 声 明 定 义 了 每一个数组元素 的数据类型 , 要么是标 量 � 么是矢量, 即 数组的类型就是数组元索的类型。 数生f-l可以将,己声 明过类型的元素组合成多维 的数据对象。 数组声明时, 应 当在卢叨 的数组标识符后 面指定元素的地址范围。 每←个维皮 代表一个地址范围 。 数组可 以是一维数组 t 一个地址范围 〉 也可以是多维数组 ( 多雪史上也Jll:范 围 〉 。 数组的索引表达式 应 当 是常髦表达式, 该常 是表达式的值应 当 是 正 鞍数、 负 整数或者 0。 一个数组元素可以通过一 条单独的赋值语 句被赋假 , 何是整个数织或数组的一部分不能 / 54 / 用一条单独的赋值语句被赋值。 整个数组或数组的一部分也不能 为一个表达式赋值。 要给 ­ 个数组元素赋值 , 需要 为 该数组元索指定索引 。 数组索 引 可 以 是一个表达式, 这就为数组元 素的选择提供 了 一种机制, 即 依靠对该数组索 引 表达式中其他的线网 数据或变革2值的运笋,纣 果来定位数组元素。 例如一个程序 计 数寄存器变盘可 以 用 做 RAM ( 随机有取存储 器 〉 的数 组索引 。 具体实现的时候, 数组元索的数 目 是被限制的, {且该数 口 最小应为 16 777 2 1 6 ( 224 )0 1 . 线网型数组 线 闷 tt�数组主 要 用 于 模块例化 〈 模块调用 〉 时 的端口 映射。 线网型数组的每一个元京 都可按线网标量或线网矢量相同的方式使用 。 2. 寄存器 与 变 量 型敖组 数织元素 的类 型可 以是变量 ( reg、 mteger 、 time、 陀al 、 realtime ) 中 的任一种 。 3. 存储器 如 果一个一维数组的元素类也只J reg 型, 那 么 这样的一维数组也称为有储器。 有·储器可 用于 ROM ( 只读存储 器 〉 、 RAM ( 随机存取存储器 〉 和得有·器组建模。 数组巾 的每一个奇 蒋器也叫做元索或字, 并且是通过单一的索引来寻址的。 一个 n 位的寄存器可以边过一条单 独的赋倪语句被赋值, 但是整个存储器不能通过这样的一条语句被赋值。 为 了 对存储器的某 个字赋值, 需 要 为 该字指定数组索 引 。 该索 引 也可 以 是一个表达式, 该表达式中含有其他的 变量或线 网 数据, 迎过对该表达式的运绊, 得到 ·个结 果值, 从而 定仪存储器的字。 4. 数组举例 ( 1 ) 敛组声明 E 例 2-30 ) 数组声 明 。 reg [7 : 0 ) mema [ 0 : 2 5 5 ] i reg arrayb [ 7 : 0 ] ( 0 : 2 55] ; wize w-array i 7 : 0 } [ 5 : 0 ] ; integer inta [ l : 64 1 i time cTIng-his t [ 工 : 1 00 0 ] ; 主nteger t_indexi //声明 一个存储器 m自旧 , i在仔们告器有 2 5 6 个 8 位 的 奇 仔 �I . /1絮们是从 0 剑 255 I I PJ明一个 2 维 数组 arrayb. I / ì在数细的 兀 亲 是一位的将布榕 1 / 111 明一个 wize 型的 2 tfJ:数组 / / 声 明 · 个 理 型 数组 , 主i 教tl-L包含 64 个幌裂变冠 / 1 卢 明 一 个 时 间 但 数组. 该敬织包含 10 00 个时间1ft 变 rjt (2) 数组元素的赋值 E 例 2-3 1 】 数组元'崇的赋值 。 本例 的赋值语句是 以例 2-30 巾 的 敛组 声 明 作 为 前提的。 merna = 0 ; arrayb [ l ] = 0 ; / 1 I七泌的赋的i苦句. 试阁)(.J' 幌个 数组�{J'( 1 / 作法的t!at值语句 , 试副 对放组元素 / / [ 1 ] [ 0 ] . . [ 1 ] [255] 队也 \ 55 \ arrayb [ l ] [ 12 : 31 ] = 0; // 非法的赋值语句 , 试图对数组元素 / / ( 1 ] [ 1 2 1. . . [ 1 ] [ 3 1 ] 默值 mema ( 1 ] = 0 ; 1 / 对数组 mema 的第 2 个元素贼值 。 arrayb 口 ] [ 0 ] = 0 ; 1 / 边过索引 { l ] [ 0 1 对数组 a r rayb 的元素 / 1 ( 1 ] [ 0 ] 赋值 。 inta [4J = 33559; 1/ 对数组的元素 [ 4 ] 赋一个十进制值 ch_ng_hist [t_index] ... ♀time; / 1 根据整数索引 t-index 寻址, 将当前的仿真 /1 时间值赋值到数组元素 (3) 存储器的区别 本例 说明一个包含 n 个 1 位寄存榕的存储器与一个 n 位寄存器矢蠢的区别。 E 例 2-32 ) 存 储 器 的 区 别 。 reg [ 工 : n ] regai reg mema [ 1 : n ] ; 11一个 n 位的寄存错矢盘 / 1一个存储器, 含有 n 个元素, 每 个 元素 为 1 位的每存器标;虽 2.9.6 参数 Verilog HDL 中 的参数既不属于变盘类 型 , 也不属于线网类型范畴。 参数不是变量, 而是常量。 有两类参数: 模块参数和延时参数。 为一个已经声明为线网、 变盘或参数的标 识符重 新 声 明 一 个 名 字, 是违反语法规 则 的 操 作 。 两种类型的参数都可 以 为 其指定 范 围 。 如 果 没有指定 范 围 , 默认情况下的模块参数和延时参数位宽 都应该能够容纳常运:值。 1 . 模块参数 模块参数声明的语法格式如下: parameter_declaration : : = pararneter [ siqned ] [ Iange ) 工 l s t-of-param-assignments J I parameter integer l is t_of_pa ram_assí gnmenl:s i I parameter rea1 l i st_of一pa ram_a s signments ; I parameter real time 1 i st一。 f_param_ass 立gnments ; I parameter time lis t_of_param_asS ignments ; l i s t-of-param-a s si9nment s : : = param-assignment { , pazamJassLqnment } paxam-ass ignITIerIt : : = parameter_identifier = constant_9xpress io只 range : : = [ πlsb-constant-expressi。EI : 1 3b-constant-exp主essìon ] 针对上述语法格式 做 以 下 儿点 说 明 。 ( 1 ) list_of_param_:部sigmen也 l也 均是一个用 逗 号 ( ,) 分|箱 的赋值语句列表, 在赋值语 句的右侧应当是一个常旦:表达式: 也就是说. 该表达式只能包含常数和先前定义过的参数。 。 ) List_of_param_assignments 可 以 出 现在模块r扫 描述情句的位1置, 9)( 者模块声 明 时 模 块端 口 参敛列表的位贺。 如 果参数赋值语句出现在模块瑞 口 参数列表中 , 那 么这样的参数 / 56 / 第 2 章 Ve而句 HDι 就成为局部参数, 不能用任何方法修改它。 ( 3 ) 模块参数表示常茧, 因此在运行时修改它的值是非法的。 然而, 模块参数可以在编译 时被修改为不同于声明时所赋的值。 这就允许模块的调用客户化。 模块参数可以使用 def阳'3JIl 语句修改, 或者在模块调用语句中被修改。 模块参数远常用于指定变量'的时间延迟或者优宽。 ( 4 ) 可 以 为 模块参数指定类型和 范 围 。 这需要按照下述规则: · 如果模块参数的 声明 中没有指定参数的数据类型和范围 , 那么该参数的默认数据 类型和范围将是该参数最终所赋值的数据类型和 范围。 · 如果参数的声明中只指定了 范围而没指定数据类型 , 那么该参数的范围将是声明 巾 所指定 的 范 围 , 而数据类型为无符号型。 即参数的范围和数据类型不受所赋值 的 范 围 和数据类 型 的 影 响 。 · 如 果: 参 数声 明 中 指定 了 数据类型而没指定范围 , 那 么 该参数 的 范 围将是最终所赋 值的数据范围e · 如 果参数声 明 中 指定的 数据类型为有符号型, 而且也指定 了 范围 , 那么该参数的 符号和范围不受所赋值数据的符号和范阁的影响。 · 如果参数声 明中没有指定范围 , 并且要么指定参数的类型为有符 号裂, 或者没有 指定数据类型, 而 且该参数最终所赋值指定 了位宽, 那 么 该参数默认 的位宽等于 最终所赋值的位觉。 • 如果参数声明 中没有指定数据范围, 并且要么指定参数的类型为有符 号型, 妥么 没指定数据类型, 而且该参数最终所赋值没有指定位宽, 那 么该参数默认的数据 范围位宽至少为 32 位 。 至于实数和整数的转换规则在 2.9.4 中 已有阐述。 下面是参数的声明举例。 E 例 2-33 】 参数声 明 。 parameter msb = 7 i // 定义 msb 为常址 7 par剖neter e = 25, 主 = 9 ; / / 定 义两个常 !û:数值 parameter r = 5 . 7 ; // 定义 z 为实数参数 parametez byte-s i ze z 8 , byte-mask zz byte-si ze ·· l J parameter average-delay z ( E + f ) / 2 J parameter s iqned 1 3 : 0 } Inux-selec巳or = 0 ; parameter real rl = 3 . 5e17 ; pa玄amete主 pl = 1 3 ' h7ei paramete汇 { 3 1 : 0 〕 dec-const = 1 · b 1 J / / 将数值转换 为 32 位的矢 pa.ramete主 oewconst = 3 ' h4 ; / / 隐含参数范1b1 ( 2 : 0 J parameter newconst = 4 ; // 隐含参敛范围 [ 3 1 : 0 ] 2. 局部参数 局部参数 与模块参数大致相 间 , 唯一不 同 的 是 用 部 参数值不能直接 山 defparam 语11)!或 者 由 模块调用语句所修改 。 局部参数可由包含其他参数的常益表达式所赋饱, 而该所包含 \ 57 \ ·实侧麟 参数可由 defparam 语句或者 白 棋块调用语句所修 改 。 局部参数声 明 的 语法格式如下: 工。cal_paramete主-declarati。n : : = 工。calparam ( signed ] [ range ] lis t_of_par田TI_assignments ; I localpararn 1nteger l i st_of_param_assignments ; I localparam real l i st_of_param_assignments ; localpa:r::am rea工time list-。E-param-a s s i gnments J localpa汇am time l i s t_of_param_as s ignments ; 该语法格式 中 的 range 和 list_of_param_assignments 己在模块参 数声明语法格式中阐述。 3. 延时参数 延时参数是一类特殊的参数类 型 , 由 关键字 specp缸am 卢 明 , 它仅用于时序和延迟值。 延时参数除了 不能出现在为 其他参数赋值的表达式中或者声明 语句 的 范 围指定部分外 , 它 可 以 出 现在任意表达式 中 。 在最初的 Verilog HDL 语言版本中 延 时参数仪能出现在 specify 语句块中 ( 延时说明语句块, 将在后面的章节介 绍 ) , 现在延 时参数既可 出现在 speci。 语 句块中 又可 出现在模块 的主体语句 内 。 出 现在 specify 语句块之外的延 时参数在被 引 用 之 前应 当 先对其声 明 . 延时参数可 以被任意常最表达式赋值, 延时参数也可以用做其后 另一 延时参数声 明 中 常重赋值表达式的 一 部分 : 与此相反的 是模块参数声 明 巾 常盘赋值表达买1 不能包括任何的延时参数。 与模块参数不 同 , 声 明 了 的 延 时参数在程序中不能再使用任何 语句修改它 , 但是却可以通过 SDF ( 标准延迟格式〉 标注对它进行修改。 如表 2- 1 0 所示 为 关于模块参数和延时参数的区别总结。 表 2-10 延时参戴和模块参曼史的区别 斤飞 斤寸1\l fn l'叮叮1 岛lèI俨唱'叫�(延时,戴》 使用关键宇 Sf肌肉ram 飞\ iJ、 11\ ‘ ,. 应 当 在模块肉 或 specify 语句块肉声明 \"'; \ • h幽 〈蟆拽"戴〉 r使用 关键字 阳ameter . 飞KJUK汇,k应 当 在 spec均 语句J.k外件明少 L lJ U F' 电 【 只能。战块内� s附ify 语句块肉使用 不能在 spec江y 语句块肉使用 赋他衣i在式可以包含延时参敢旦旦换块参披 使用 SOP 际n:修战参数缸 时值占总式小能 包 含 延 时 参 数 使用 defparam 语句或者缺块阴附悟1lJ来修改参放假 延时参敛声 明 的语法格式 虫rJ 下 : specpa tarn-deClarati。n : : = specparam [ range ) 1 i s 巳一。f_specparam_a s s ignments ; l i s t_o f_specparam_a s signments : : = specpaEarn-assi gnment { , specpaxam-as si9nmenE } specpa ram_ass ignment : : = specpazam-identl f ie x z c。nstant-mLntypmax-express立。n • I pulse_conζIol_specparam pulse_conζ玄。L-specparam : : = PATHPUZSE$ = ( xej ect-lirnl℃-va工ue [ , ezxox-limit-value } } ; l PATHPULSE$speclfy-input-te口ninal-descriptor$speciEy-。utput-texminal _descrJ.ptor / 58 h 第 2 章 Ve时Iog = ( rej ect-luni t-value [ , err。r limit-value } ) ; error 1im主t value : : = 1imit value reject limit value : : = limit value 1irnit value : : = c。nstant-mint ypmax-expressi。rI range : : = { rnsb-cons℃ant-expressi。n : l sb-c。nstant-exp ressi。n ] 按照如下规则 可 以 为 延 时参数指定一个数据范围。 · 如 果 在 延 时 参 数声 明 语句 中 没有指定数据 范 围 , 那么将最终为 参数所赋值的 数据 范围默认为该延时参数的数据范围。 · 如 果 在 延 时参 数卢 明 语 句 中 指定 了 数 据范 围 , 则参数 的 数据 范 围 不 受 为 其所 赋值 的数据范 围 的影响。 【例 2-34 ) 延时参数 声 明 。 1/在 specify 语句块中延时参敬的卢明 spec i f y specparam tRise_c工k-q = 150, EFall-clk-q z 2 0 0 1 speepazam tRise-c。ntr。l = 4 0 , tFal l-contz。l = 50 J enåspec i f y 11在模块内 的延时参数声明 module RAM16GEN ( DOUT, DIN, ADR, WE, CE) specparam dhold = 1 . 0 ; specparam ddly = 1 . 0 ; parameter width = 1 ; parameter regsize = dhold + 1 . 0 ; /1 非法的参数严明语句, 不能将短时参数献倪给模块参数 endmodule 2.9.7 名字空间 在 Verilog HDL 中有 7 类名字空间: 其中两决为全局名字空间 , 其余 5 类为局部名字空间。 1 . 全局名字空间 仓 用 名 字 空 间 包括定 义 和 文 本 宏 。 ( ) ) 定 义 名 字 空 间 包括所有 module ( 模 块 〉 、 marcomodule ( 宏模 块 〉 、 primitive ( 搭 本元件 〉 的 定 义 。 一且某个名 字被用 f定 义一个模块、 宏模块旦旦基本元件时 , 它将不能再 用 于声明 其他的模块、 宏模块或基本元件, 也就是这个名字在定 义名字空间 具有唯一性。 ( 2 ) 文本宏名 字唁间也是全 局 的 。 由 于文 本 宏 名 由 重 EE符号 ( ' ) 引 导 , 因此它 与 别 的 名 字� 问 有 明 显 的 区 别 。 文本宏 织 的 定义逐行出现在设计 单元源程序巾 , 它 可 以 被t重复定 义 . 也就 是 同一宏 名 后 面 的 定 义将辙 盖其先前的 定 义 。 \ 59 \ 应用程摩设计实伊臆讲 2. 局部名字空间 局部名 字空间包括: block ( 语句 块 ) 、 module ( 模块 〉 、 port ( 端 口 〉、 speci岛, block ( 延 时 说 明 块 〉 和 attribute ( 属 性 〉。 一旦某个名 字在这 5 个 名 字空间 中 的任意一个空 间 内 被定 义, 它就不能在该空间中被重复定 义 , 即具有唯一性。 ( 1 ) 语句块名字空间包括 : 语句块名 、 函数名 、 任务名 、 参数名 、 事件名何 。 其中变量类型声明包括: reg, integer、 time、 real 束I realti:me 声 明 , 这在前面的章节介绍过。 ( 2 ) 模块名字空间包括: 函 数 名 、 任 务 名 、 例化名 ( 模块调用 名 〉、 参数名 、 事件名 和 线 网 类 型 声 明 与变量类型声明 。 其 中线网 类型声明包括: wire、 wor、 wand、 时、 国or、 时and、 triO、 时 l 、 创reg、 supplyO 和 suppLyl , 这在 前 面 的 宣言 节 已经介绍过。 ( 3 ) 端 口 名 字兹在 问 用 于连接两个 不 同 名 字空 间 中 的数据对象 。 连接可 以是单 向 的 ( input 或 output) 或双向 的 ( inout ) 0 端 口 名字空间是模块名 字空间 与 语句块名 字空间的交集。 从 本质上说, 端 口 名 字空间规定 了不 同空间中两个名 字的连接类型。 端 口 的类 型 声 明 包括 in.put 、 output、 inout。 在瑞 口 名字 空 间 中 定 义 的 端 口 名 可以在模块名 字 空 间 中 被 再 次引 用 , 这只需要在模块名 字空间 中 声明一个与端 口 名 同 名 的变盘或 wire 型数据 就可 以 了 。 ( 4 ) 延时说明块名 字空间将在 speci句 块结构中介绍 〈 见后面的章节 〉 。 ( 5 ) 属性是 由 符 号 ( * . ) 包括的语言结构。 属性名只能在属性名 字空间 中 被定义和使 用 , 而其他任何名 字都不能在属性名 字空间中被定义, 2.1 0 表达式 表达式是将操作符和操作数联合起来使用 的一种 Verilog HDL 语育结构 , 通过运算得 到一个 结 果 : 从语义上说 , 这 个 结 果值也可 以 看 做操作数的 函 数值 。 一 个合法的操作数, 例如一个线网 型矢垦 的优选挣, 尽管没有操作符参与 , 但是它也被看做表达式 。 表达式可 以用在 VeriJog HDL 语句 中 任何一个需要值的地方。 某些语 句结构要求 表达式是一个常量表达式。 常重表达式中 的操作数只能是常数数 值 、 参数 、 参 数 的 某一位、 参 数 的 部分位、 常最函数调用 , 而 且操作符只能使剧 表 2-l L 巾 定 义的操作符。 标量表达式是一个对标EZ求值的表达式。 如果 标最表达式对矢盘求值, 那 么所求 结 果 的最低位被用 做标量结 果 倍 。 表达式的操作数可以是下述类型之一: • 常'最数值 〈 包括实数 ); • 线网型数据: · 变量类型 : · 线 网 矢髦的某一位: · 线网矢景的某儿价: • reg、 integer 和 time 型数据 的 某一 位 : / 60 / 第 2 章 Ve时1句 HDt .' reg、 integer 和 time 型数据 的某几位: · 数组元素: • 用 户 函 数 或系统函数调 用 , 其返回值是上述类 型 中 的任意一 个 。 2.10.1 操作符 Verílog HDL 中 的操作符符号与 C 语言中 的类似。 表 2- 1 1 列 出 了 这些操作符。 � 【 - 气 .., õ(' p ' " _ •• , , .• 操作持费型 算术运算符 袤 2-11 Verilog HDL 中的操作符及功能说明 也 符号 中 +. -. · . /,·· 同 算术运贸 % 取报 简单说明 逻辑非 逻辑运算符 && 理辑与 11 逻羁!íIt 相等操作符 t虫 也 运 算 符 ζ 司 . .;;. = = =:._ !;;-.:; 〉 ,〉=, 〈,〈= - & • 逻辑柑等 瞿j 躺习、等 全得 |拉金等 关系 放仪廿 4安位与 按位或 ���/\队:y d11 A 1 -^or"- • & rn'l俨| tl'l -& 工剑\七岁、工�'U (J (J • 技 位 .w 成 按住异�非 V--1量可 勺 11'ì\ 归约 与 非 U L 归约运贸饨· 归约4 归约骂�i卡 A ι〈。户E 归约异成 归的并�非 《 逻创i丘移 移位操作符 条 件豆i 挥符 遥J幸运贷利 》 <<< >>> '.).. n. 理�It右路 11 术 丘 格 贸�,fì格 条1/1' 血战 Lj赋的 , ‘F与、 3 1 . 实型操你数的操作符 表 2-12 列 出 了适用 于实现操作数的合法操作符, 而其他操作符对 于实数来说则被认为 是非法的。 \ 61 \ 表 2.12 实型操作颤的合法操作符 ·、 镰作符费型 符号 I'(t 日 运算得 算术运算付 +一 ' + . -, · . /" 2.. 逻辑运算仲 ! . &&. 11 相等操作得 关系i主算符 最-f1 l主挥符 〉 严气 气 〈皇 ?: 对实型数使用逻辑或关 系操作符得到的约果将是一个标量值。 表 2- 1 3 列 出 了 关于实电 操作数的非法操作符。 算术运算得 相等操作符 掠位运算符 归约运钝符 移位操作忖 操作符提型 表 2-13 实型操作数的非法操作符 ι -- - 气 』 % 特号 - , & . 1 . ^ . -^o户可 &. -&. j, 斗. ^, -"0.-. <<. >>, <<<, >>> 2. 操作符的优先级 表 2- 1 4 是 Verilog HDL 中 的操作符优先级 列 表 。 表 2-14 操作符的优先级 操作精 f气 +, •• ! - . . - ( 申 目J.�.算符〉 ...' '-' 1,飞iia JD ·t·/aJi\iJp . 、J"Jf、 优先组 1t� if.lI 优先组 工./ U U μ . P 、三!1f�r �II.\ I( U ìl竹 UL *. 1. % 飞 - (_二元忌饵付1 <<, >>. <<< . >>> <. <=. > . ><; = =. !罩, = = z , !EZ & . -&: A - JO俨- 1, -1 && 11 ? Mf民优先在随 1 62 卢 第 2 章 Verilog HDL 在表 2- 1 4 中 , 按照箭头指示的方向 , 操作符的优先级从高 到低 降序排列 , 同一行的操 作符有相同的优先级。 例 如 , 气 / 、 %有相 同 的 优先级 , 二元运算符+、 -也有相同的优先 级 , 而事、 /、 %的优先级高 于二元运算符+、 -。 结 合 性指 出 了 表达 式 中 J1 有 相 同 优 先 级 的操 作 符 求 值 的 先 后 顺序 。 除 了 条 件操作符 ( ? : ) , 其余操作符都具有丘结合性, 而 条件操作符其街右结合性。 例如在下 式 '1=1 由 fjJn ( + ) 号和减 ( -) 号 , 具有相 同优先级 , 而它们的综合性为左综合, 所以求值的顺序足这样 的 : 式中 B 首先被加歪IJ A, 得 到 结 果 A+B; 然 后 再 从 结 果 A+B 中 减 去 C。 A+B-C; 当操作符处于不同优先级时, 更高优先级的操作符应 当被首先结合。 例如下式巾 , 除 (/) 号的优先级高 f加 ( + ) 号 , 而求值的顺序是这样的: 首先计算 B 除以 C, 得到约果 B/C: 然后 再将此结果加到 Ao A+B/C ; 因括号可 以改变操作符优先级。 如下式, 求值j顺序是: 首先计算 A+B, 得到一个约果 值: 然 后 再将此结 果值除以 C。 式中加 ( + ) 号的优先级变得高于除 (/) 号 , 这都是因为 加 上 了 国l 括 号的缘故。 (A+B)/C: 3. 表达式中整数数值的使用 整数数值可以用做表达式中 的操作敛。 一个整数数值可以按下述方式表示: · 简 单 的 十进制格式 〈 如 1 2 ): • 未指定位宽, 基 数 格式 〈 如 ,d J 2. 'sd 1 2 ); · 指定位宽 , 基数格式 〈 如 1 6'd 1 2, 1 6'sd 1 2 )。 在表达式中一个十进制格式的 负辈革数与基数格式的负 整数在被机器编译后是不同 的 。 一个十迸制格式的负整数在表达式中被编译成有符号的二进制补同格式, 一个无符号 基数 格式的 负 哥在数在表达式1护 被编译成无符 号 数 。 E 例 2-35】 负整数在表达式'1 ' 的 区 别 。 本 例 用 四 种方式表达- ) 2 除 以 3 , 以 说 明 负整数 在表达式 中 的 区 别 。 integer IntAi 工ntA = -12 / 3; 工 n tA = - ' d 1 2 1 3 ; IntA = - ' sd 12 / 3 ; IntA = -4 ' sd 12 / 3i /1 结果为-4 /1 结果为 1431655761 1/ 结果为-4 1 1 -4 ' sd12 是 4 位 的 负 放 . 等r- 1 1 0 0 , / / - {-4 ) 罩 4 . 国此�终纣 呆头.; 1 也就足-4 : - 1 2 和-'dI2 被求值后 有 相 同 的二进制格式, 即都是二进制补码格式, 但 是在表达式中 , -'d 1 2 失去 了 它 的 负 号 , 变成元符号数. \ 63 \ 应用疆靡设计实偶糟诩 • 4. 表达式的求值顺序 求一个表达式的值时, 操作符应当遵照前述 "操作符的优先级 " 中的结合性划则. 然 而如果表达式的最终值可 以被提前决定 , 那么就没有必要对整个表达式进行求值. 这也叫 做短路表达式的求值 , 如下例所示: E例 2-36) 短路表达式求值。 reg regA. regB, regC, result ; result = regA & (regB I regC) ; 如果事先知道 regA 的值为 0, 那么鹦个表达式的值就被确定 为 0 , 而不必对后面的regB I regC 再做计算. 5. 算术运算操作符 二元的算术运算操作符如我 2- 15 所示。 a+b a-b aOb rJb 的也b 80.b 褒 2-15 二元"术逞.�集作符 a 1JI1 b a减b a采以b a除以b a l球以 b 取余 a 的 b 'ð:,)j 整数除法的结果应当截去小数部分. 对于除法或取余操作符, 如果 第二个操作数为 0, 那么整个的结果{血肉当为米知 ( x )。 在取余操作中 , 如 果第一个操作撤恰好能被第气个操 作数辈革除, 那么最终的结果 〈 即取得的余数 〉 为 0: 取余操作结果值的符号果用与第一个 操作数相同的符号. 在乘万运算中, 如果街任意一个操作数为实数 、 整数或者有符号数, 那么最终的结果用当为实数: 如果两个操作数都为无符号数, 那么结果为无符号数: 如果 第一个操作数为 0 第二个操作数为非正敛, 或者·第一个操作数是负数, 第二个 为非整数值, 那么乘方运算的结果为未知 (x). 一元算术运算操作符的优先级高于=元算术运算操作符. 一元算术运算操作符如表 2-16所示. 噜咀3 -叮' 褒 篝柏 算镶 符 一 F m- - ­ ­ 川一 对于算术运算操作符, 如果任何一个操作数的某一位的值为未知 (x) 或者高阻 (z), 那么最终的结果值为米知 (x)。 如表 2-17 所示为关于取余操作的例子. 1 64 � E例 2-37 】 取余操作. 取余表达式 10"/03 11%3 12%3 . 1 伪� 11%.3 -4'dl2%3 鲸果值 z 。 2 袋 2-17 取余镰作举例 说明 10除 以 3, 余l'i为 l 11 除以3, 余敛且I 2 12 除以 3, 刷Ilt�.�全. 余敷且� 0 纺织的符号取m-操作放符巧 纺织创符号骂U\-�量作敏衍巧 -4'd12 ?t表达Ä中被机缝制品i挚成无符号敏. 所以求达式的盖章终约��JïE值 6. 含有寄存铺型或整蚊型黯据的算术运算表达式 寄存器型数据如果没有显武声明为有符号数, 则应当被看做无符号数值. 而整型变量 则被看做有符号数. 有符号的值在机器中以二进制补码形式表示. 有符号数和无符号数之 间的转换在二进制农示形式上相同, 只是在机器编译后才有所啤变. 表 2- 1 8 列 出 了 算术运 fl 操 作 符 娃 如 何 编 译 每 一 种 数 据 类 型 的 . 量己符号线间也 钉符号线问M .f符号ViHl械� H符号�m量型 rHl! IH币1M •. Il , 1比m.fll�革时时向M 型是 2-18 算术运算操作符对数据类型的编译 f,(:键盘睡型 A己 11 1} .. 部 {ìf.吁 吁 . -4iii制外/if\形式 k利t} F 飞4 i l lla.J M守吁, 一i丘制补码形式 白'符号. 一草 i 制补何形式 一 x?串13 {t.符号. f手点明 1呵� 11 、 寸,、 1: 下例说明如何在表达式寸'使用整型和寄存器型数据。 E例 2-38) 在表达式中使用整型和寄存器型数据. integer intA; reg [ 1 5 : 0 ) regA.; reg signed ( 1 5 : 0 ) regS; intA - -4 'd12; regA - intA / 3 ; //表达式纣i 果为 - 4. intA 为'宣刑数据. 其中 regA 为 65532 regA = - 4 ' d 1 2 ; / / regA 为 65524 intA = regA / 3; intA = -4'd12 1 3 ; regA - -12 / 3; / /表达式结果为 21841. 其中 regA 为寄存苦苦型量�lli //表达式约来为 1431655761. 只小-4'd12 足一个 32 似的将有精盟数据 //表达式结巢为-4, 其中-12 � .个#奥地放据. regA 为 65532 regS - -12 / 3 ; //表达式结果为- 4. 其中 regS 是一个钉符号的部仔器警数据 regS = 斗 ' sd12 / 3 ; /1表达式结果为 1 . 其中-4 ' sd12 实际 k等于 4 . 报然! 整数除法的规则 / / 有 4 / 3--1 队 65 \ 7. 关系操作符 表 2-19 列 出 了 关系操作符. ab a<--b a>-b 褒 2-19 关系镰作符 a 小子 b a 大 f- b a 小手续等 JO b a 大于ïilt等J'" b 使用关系操作符的表达式结果为标监值 , 如果指庭的关系为 It -fI>!l ". 则结果为但 O. 反 之. 指定的关系为 " 真飞 则结果为值 ) . 如果关系操作符两端的任意一个操作数包含一个 未知 ( x ) 或打高阻 (z) 值, 贝IJ表达式的结果为 l 位的未知 (x) 值. 如果两个操作数有不同的位宽 , 其q.一个或两个操作数为无符 号 数 , 那么应当 在位宽 较小的操作数的高位补 0, 将其位宽扩展剑较大位宽的操作数位宽. 所有的关系操作符有相同的优先级, 们关系操作符的优先级低于算术运算操作符. 下面举例说明这个优先级规则. E 例 2-39】 关 系操作符与算术运算操作符的优先级. a < foo - 1 (1) a < ( foo - 1 ) (2) foo - ( 1 < a ) (3) foo - 1 < a (4) 表达式 ( ) ) 等同于表达式 ( 2 ) . �吨衣沾式 ( 3 ) 不同于表达式 (4). 在表达式 ( 3 ) 巾 , 首先对关系在达式 ) < a 求值, 得到 o ClG ) , 然后再将该值 从 foo 巾减去. 而在表达式 (4) 巾 , 首先是对 foo 减 ( , 将得到的值再与 a 比较. 如果关系我达式中的两个操作数都是有符号的整数 〈唱起型数据、 有符号寄存器数据旦旦者 卡 ill制格式整数 ), 那么表达式就阳当被看做是两个有符号数的比较. 如果关系表注式中的任意 -个操作数为实型敬据, 那么另外一个操作数就应当首先被转换成实型激据, 然后表达式就被 看做是两个实型数据之间的LL':校. 除以上两种悄况外, 农达式部被作为无符号数之间的比较. 8. 相等操伟符 相等操作符的优先级比关系操作符里低. 表 2-20 列 出 了 相等操作符。 • a-b 剖-b a-b al-b 亵 2-20 徊等操作符 a咎于b. 也以但 足 和1 2 8 -'1可气7> 1三 b. 也指{i'l x 相 z a 事t 于b. 仿 !4!nj能为 禾知 {川 . -'1、雪? J' b. t古 !4!可能为本组1 ( x ) / 66 / 第 2 章 Ver胁' 这四个相等操作符有相同的优先级. 相等操作符在比较两个操作数时是按位比较的, 如果两个操作数的位宽不等, 那 么较小位宽的操作数在高位补 o. 与关系操作符一样, 如 果 比较关系为 " 假 ", 则表达式结果为值0: 反之, 比较关系为 " 真 飞 则结果为值 1 . 对于逻辑相等和不等操作符 (=和!=〉, 如果在操作数中有未知 (x) 或高阻 (z) 位, 则比较关系不明确 , 比较的结果为 l 位的未知 ( x ) 值. 对于金等或非金等操作符 (= 和!=), 操作数中的未知 (x) 或高阻 (z) 他也应当纳入比较, 从而比较的结果是一个明 确的值, 要么为 0 要么为 1• 9. 逻辑操作符 逻辑表达式的结果值可以是 o (定义为假〉、 1 (定 义 为 真 〉 或者 x ( 逻辑关系不明确 未知). 对于二元的逻辑操作符&& (逻辑与〉 和11 (逻辑或), 前者比后者有更高的优先级, 但两者都比关系操作符和相等操作符的优先级低。 对于单目 的逻辑操作符! (逻辑斗的, 它 有最高的优先级. 下面是逻辑操作符的应用举例。 E例 2-40] 逻辑操作符的应用 . ( 1 ) 假定寄梓器变盘 alpba 保持整数值 237, 而 beta 保持值 o. regA = alpha 晶晶 beta; regB = alpha I I beta; // regA 被设贺为 o // regB 被设贺为 1 (2) 下面的表达式对三个子表达式进行逻辑与操作, 而不拇要任何的困括 号. - a < s ize l & & b ! = c 晶晶 index ! - lastone 但是出于可读性考虑, 加上因括号可以使求值的优先级非常清晰, 虫1I下可这样噎写上 面的这个表达式. (a < size-l) 品品 (b ! - c) 晶晶 (index ! = lastone) ( 3 ) 逻辑非操作符 ( ! ) 迦常用在下面的结构中: if ( ! inword) 在某些情况下, 使用逻辑非符号 比使用相等操作符望能加部人的理解, 比如下面的结 构使用的是相等操作符, 但是它实际上与上式是等效的。 if ( i nword == 0 ) 10. 按位操作符 技位操作符是将一个操作数中的一位与另一操作数巾的对f盯在进仔计算, 从而得到结 果的一位. 这样逐位处理, 直到完成操作数所有位的计算. 如 果两个操作数的位宽不等, 那么较短的操作数应当在高位补 o. 衷 2-21 至表 2-25 是技位运rr.结果的真值表。 队 67 \ A嘱画M兑岛髓,即岛唰讲 & 。 x z 。 表 2-21 绞位与银作结果真值表 。 '‘ 。 。 。 。 3‘ 。 '‘ J‘ 。 x x 褒 2-22 拨位ltt集作结果真值襄 。 3‘ 。 J‘ z 。 JI 3民 3‘ z 3‘ 革 3‘ z 3‘ J‘ ‘1 3‘ ‘J 褒 2-23 按位舜戴银作结果真值褒 ,、 。 3‘ z 。 。 1自 ‘' 。 3‘ '‘ 3‘ '‘ 3‘ 3‘ 3‘ 1. 3‘ ‘3 3‘ x 表 2-24 按位异军民非操作结果真值亵 --"0户‘ 。 3‘ 1. 。 I I )i 0 " 。 E ‘' 3‘ 3‘ 3‘ 飞 a , 1民 '‘ '‘ ‘』 3‘ z ,也 x 3‘ 3‘ 亵 2-25 1跑 回 取反馈作结果真值袋 - 。 。 j吃 x z 3‘ 1 1 . 规约运算符 单 H 规约运算符是在一个单挫的操作数上按位进行运弈, 战终得到一个一位的结果 值. 对于规约与 、 规约或、 规约异或操作, 芮先是将操作数的第一位与第二位进行相应的 位运fl:. 第二步及后绥的步骤 足 , 将 J:一步的一位结果值与操作数的下一位进行相应的位 / 68 ;. 第2. 运n. 以此类推, 直到计算完操作数所有的位得到最终的结果也. 对于规约 与非、 规约或 非 、 规约异或非, 只需要将规约与、 规约或、 规约异或操作的结果值分别求反即可. 表 2-26 至表 2-28 是规约运算中位运算的真值表. 表 2-26 规约与键作位运'事.值'曼 & 。 ,、 z 。 。 。 。 。 。 '‘ x x 。 '‘ 3民 x z 。 '‘ 3‘ 百 衰 2-27 规约或镶作位运算真值褒 。 。 。 3‘ z '‘ 1民 3‘ 丁民 z x 3‘ x x 3‘ 褒 2-28 娩约异或娘作位运算真值. ,、 。 。 。 3‘ z '‘ x 。 3‘ 1民 '‘ '‘ x 3‘ 3‘ z 直 3‘ • K 3‘ .<< 2-29 显示了规约运算符应用在不同操作数 k的结果 '且 '事 . 4'bOO∞ 4'bl l l l 4'ω110 4'blOOO 表 2-29 规约运算操作结果 & ... 什 ,、 .J、 说明 。 。 。 操作政府.(j(直 占1I 且 1 0 。 。 。 t撞f1"ft所(j{�仰为 1 。 。 。 生'件JH,.偶做个位.:tJ 1 。 。 。 t量11,敏.(i(,f�个位且� 1 12, 移位操作符 有两种类型的移位操作符: 逻辑移位操作符《和>>. 算术移位操作符<<<和>>>. 左移操 作符《和<<<应当将它们左边的操作数按照右边操作数指定的位数在移相应的位数, 空闲位补 o. 向理, 在移操作符》和>>>应当将它们左边的操作数按照右边操作数指定的位数右移相应 的位数. 逻辑右移后的空闲位补 o. 而算术右移后的空闲位分两种悄况进行处理: 如果结果的 队 69 \ 应南疆摩设计实例躏讲 类型为无符号型, 则空闲位补 0: 如果结果的类型为有符号型, 则空闲位按照左边操作数的最 高位 ( 即符号位〉 值进行补充。 如果操作符右边的操作数有一个未知 (x) 或高阻 (z) 值 , 则移位结果为未知 (x)。 结果的符号由左边操作数的符号和表达式的其余部分决定。 下面举例说明移位操作符的使用。 E例 2-41] 移位操作符的使用。 mOdule shifti reg [ 3 : 0 ] start, result; initi.al begin start = 1 ; result = (start << 2) ; //result 的黛终结果为二进制值0100 end endmodul e modu1e ashift; reg signed [ 3 : 0 ) start, resu1ti initial OOgin start = 4 ' b1000i result = (start >>> 2) ; / / result 的最终结 果为丁.避制ffi. 1 1 1 0 end endmodule 13. 条件操作符 条件操作符也叫三目操作符, 具有右结合性, 带有三个操作数。 其语法格式如下: conditional_expression : : = expressionl ? ( attribute_instance } expression2 : expression3 expresslon 1 : : '"' expression expression2 : : .. expressl.on expression3 : : � expression 在条件表达式中 , 首先对表达式 I 进行求值. ( 1 ) 如果表达式 1 的值为 " 假 " (0), 那么接下来就求表达式 3 的值, 并将表达式 3 的值作为最终条件表达式的值. (2) 如果表达式 1 的值为 "真" ( 1 ), 那么表达式 2 的值将被求出, 并作为最终条件 表达式的值。 / 70 IA (3) 如果表达式 l 的值不明确 ( 为 x 或 z), 那么表达式 2 和表达式 3 部应当被求值, 然后将它们的结果根据表 2-30 按位计算, 从而得到最终的条件表达式值: 当然有一种情况 例外, 那么就是表达式 2 和表达式 3 中任意一个结果为实数型, 则最终的条件农达式值为 00 如果表达式 2 和 农达式 3 的结果值位宽不|叶 , 则需要将位宽较短的操作数扩展到较快 位宽操作数的位宽, 即在其高位补00 '曼 2-30 条件不明确情况下条件褒达式的结果 ?t 。 x z 。 。 '‘ x '‘ 1民 :‘ x x 且 3‘ 3‘ 3‘ z 3‘ 3‘ 3‘ '‘ E例 2-42) 条件操作符的使用 . 本例用一个三态输 出 总 统 说 明 条 件操作符的曾通用法. wire ( 1 5 : 0 1 busa 事 dzive-busa ? data : 16·bZ J 当 drive busa值为 l 时 , 由 data 驱动 bωa; 如果 drive busa 值为未知 ( x), 贝IJ 出一个 未知值驱动 busa; 否则, busa 不被驱动. 14. 连接与复制操作符 连接操作符是将两个或更 多表达式连接起来合并成一个表达式的操作符, 用花括号{} 将破连接的表达式括起来, 括号中 各表达式用远号 'ef' 分隔开. 除 了 非定氏的常哇, 任何 表达式都可以进行连接运算. 这是因为连接操作中每一个操作数都需要计算完整的连接位 宽. 下面举例说明连接操作符的使用. E例 2-43) 连接操作符的使用 . module concatTest; reg a ; reg ( 1 : 0 1 b ; reg ( 5 : 0 J c; iniLial begin a=l 'b1 ; b=2 ' bOO ; c=6'blOlOOli Sdisplayb ( 恼 , b } ) i $displayb ( { c ( 5 : 刀 , a ) ) ; end endmodule / 1 ('川位一个 -f位做 3 ' blO O 11产 唯一个问位数 4 'blOll \ 71 \ 连接符号的另外一种应用形式是复制操作. 将一个表达式放入双重花括号11 {{ } } " 中 , 而复制因于放在第一层括号中 . 用 来指定复制的次数. 该复制符为 复制一个常重或变量提 供一种简便记法, 如下例所示- E例 2-44】 复制操作符的使用. module replicTest; reg a; reg [ l : O ) b; reg [ S : O l c; initial begin a-1'b1; b-2 'bOO; Sdisplayb ( { 4 ! a ) } ) ; c-! 4 ( a ) ) ; Sdisplayb (c) ; end endmodu�e /1结果为 1111 /1结果为 001111 2.10.2 攘伟数 在表达式中可以指定几类操作数. 最简单的操作数类型是引用 一个线网或变量型数据 的完鞍形式, 也就是给定的线阙或变量名 . 在这种情况下, 组成线间或变量值的所有位都 被用做操作做. 如果线网矢母、 寄存器矢盘、 整型变母或时间型变班的某一位被引用, 那 么这样的操作数就称为位选择型操作数。 如 果线网矢母、 寄梓器矢i盐、 整型变盘或时间型 变放的某儿个连续位被引用, 那么这样的操作数就称为部分位选弹型操作数。 一个存储器 字也可被引用做操作数。 操作数的合并 〈 用连接操作符将几个操作数连接起来〉 也被看做 是一个操作激。 此外, 一个函数的调用也被认为 是操作数。 1 . 矢量的位选择和部分位选择的寻址 枕边弹是指从钱间矢血、 寄存器矢盘、 整型变敏琪时间型变1íllj'选取一个特定位。 这 个特应优可以用表达式来寻址。 如果位选择超出 了 寻址范用或者被选择的位的值是 x 或 Z, 那 么在i 忱的引用返回值为 x。 一个实型或实时时间型变娃的位选择成部分位选择声明都是 非法操作. 部分位边择中的几个连续位也可以被d址. 有两种形式的部分位选择: 一是常革形式, 一是索引形式. 常 Et形式的部分优选择语法棉式如下: vect (msb_expr : lsb_expr} / 72 / 第 2 :1脏 方括号中两个表达式都是常量表达式。表达式 msb_expr表示地址高位, 表达式 lsb_expr 表示地址低位. 如 果部分位选择超出了 寻址范围或者被选择的部分位的值为 x 或 z. 那么 引 用 的返回值为 h 索引 形式的部分位选择语法格式如下: reg [ 1 5 : 0 ) big_vect; reg [ 0 : 15) 1itt1e_vect ; biq-vectIlsb-base-expz + : width-expzl liutle-vect I msb-base-expE + : widEh-ekprl biqEvect [rrlsb-base-expz - : width-幽expr) li ttle-vec t [ lsb-ba se-expr - : wldth-expz ] 表 达 式 width_expr 是 一 个 常 量 表 达 式 , 它 不 受 运 行 时 参 敬 赋 值 的 影响 。 表达式 isbJa臼_expr 和 msb_base_expr 在运行时可 以改变. 前两个 部分位选择中位地址起始于地 址基址, 并且逐渐增加, 被选择的位的数 目 等于表达式 width_expr 的值. 后两个部分位选 择中位地址起始于地址基址, 并且逐渐减少, 被选择位的数目 等于表达式 width_expr 的值。 部分位选择中超出寻址范围的位或者是被选择的优本身值为 x 或 Z. 那 么 从这些位读 出的值为 x; 而如果对部分位进行写操作 时 , 只对寻址范围 内 的位起作 用 , 超出寻址范围 的位不受影响. 下面主持例说明位选择。 E例 2-45 ) 索 引 形式的位选择。 本例巾, 索引 index 将对矢量 acc 中的某一位进行寻址. reg [ 1 5 : 0 ) acc; reg [ 2 : 17] acc: acc[ 1ndex1 E例 2-46) 索引形式的部分位选择. reg [ 3 1 : 0 J b1g_vect; reg [ 0 : 31 ] 1itt 1e_vect: reg ( 63 : 0 ) dword: inceger se1; inìcia1 begin i f { biq-vect [ O + : B l z= big-vect[7 : 0 1 ) beqin end iE {little vec t l O + : 8 ] zz little-vect I O : 7 ] } be9in end i f { bi9-vect I15 - : 8] =z big-vect { 1 5 : 8 1 } beqin end i f (lict1e_vecc [15 - : 8 ] == 1ictle_vect[8 : 1 5 ) ) begin end i f (3e1 >0 晶晶 se1 < 8) dword [8.se1 + : 8 ) - big_vect [ 7 : 0 ] : / / 曾换被这仔仔j字节 F面i举例说明位导址中需要遵循的一些原则. \ 73 \ E例 2-47】 位寻址原则 . reg [ 7 : 0 l vect; vect .. 4 ; 11 周二进制形式 00000100 对矢盘 vect 赋值, 戴高位是第 7 位, 最低位是那 0 位 · 如 果 addr 值为 2. 那么 vect[addr] 返回值为 1 . · 如果 addr 值超出寻址范围 , 那 么 vect[addr) 返回值为 x. · 如 果 addr 值为 0、 l 成者 3-7. 则 vect[addr) 返回值为 o. • vecl[3:0) 引用返回位的值为 01000 • vect[5: 1)引用返回位的值为 00010. • vect[返回值为 x 的表达式]返回值为 x. • vect[返回值为 z 的表达式]返回值为 b · 如果 addr 的任何一位为 x 或 Z. 那 么 addr 的值为 x 。 注撞s 部分位选择时, 如巍舍引恤� x Äi. z. 则偏峰时可a根错; 如果位选择... 部分位选择趟 出 7 声 明的导址范圃, 则‘译时也可能根错. 2. 数姐和存储器寻址 数组和再储黯 〈一维奇非器数组〉 声明已经在前面的章节讨论过, 现在将讨论数组的 寻址. 存储器寻址的语法格式如下: mem_name [addr_expr] 地址表达式 addr_expr 可以 是任意表达式, 因此存储器可以被间接寻址, 如下所示: mem name[mem name [ 3 ] ] 在上式 中 J mem_oame(3)足一个地址表达式, 它表示再储辑 mem-name 中地址为 3 的 字。 而该字的值义成为存储掘 mem-nme 的地址盒' 引 。 与位地捧一样, 再储器声明中给定 的寻址范围, 决定 了存储器地址表达式的作用范围. 如果地址索引 表达式超 出 了 寻址范围 或者地址索引 中 有任何的位值为 x 或 z. 则被引用的值将为 b 多tfn数组 ( 比如二维或」维 〉 的寻址语法格式如下: EHOd-azzay iaddz-expz ] [ addz-exprl threed-aEEay Iaddr-expz1 [addz-expz l i addz·-expz1 / 1 二维敛组 寻址 / 1 三维数组 寻址 地址.&.达式 addr_expr 可以是任意表达式. 为 了 表示数组元素的位选择或部分位选择 , 需要首先选中数组元素 . 即需要为数组的 每一维度指定一个地址. 然后接下来的位选择或部分位选择与前面讲过的方式相同. 下1仰在例说明 多维数组的位选择豆豆部分位�蝉. / 74 IA 第2章 E侧 2-48】 多维数组位寻址. twod_array ( 1 4 J ( l J [ 3 : 0 ) twod_arr ay[ 1J [ 3 J ( 6 ) twod_array[lJ [3] [se1) threed_arra y [ 1 4 J ( 1 ) [ 3 : 0 J / / 寻址一个二钳;敏组字的低四位 //导址一个二tl�敏组字的 第 6 位 //使用索引交默�址二维数组字中的某一位 / 1 对二维数组非法的位寻址 3. 字符串 字符串操作数被看 做 由 8 位的 Ascn 代码构成的常量数字序列 , 每一 个 8 位的 ASCU 字符对应一个数字. 任何 Verilog HDL 操作符都可以处理字符串操作数. 如果一个数值变 量卢明的位宽大干赋值值的位宽 , 那么赋值操作完成后 , 该变茧的左踹 〈 高位 〉 应当补 00 对于字符事变盘的赋值操作与此雷同. 下面举例说明- E例 2-49] 字符$ 变量的赋值. module strlng_test; reg [ 8 * 14 : 1 ] stringvar; / / U} 明一个?符$交堡, T口 以容纳 14 个 ASCII 字符 initla1 begln str lngvar = "Hello world"; Sdisplay ( " 屯 s is stored as 宅h", stringvar, stringvar ) ; stringvar = ( stringvar, " ! ! ! " ) ; $dlsplay ("在5 is stored as %h", stringvar, stringva r ) ; end endmodule 仿真结果为: Hello world i5 5tored as 00000048656c6c6f20776f726c64 Hello world l ! ! is stored as 48656c6c6f20776f726c64212121 可见由于字符帘'HeUo world"只有 1 1 个字符, 而声明的字符串变盘 stringvar 可以容纳 14 个字符, 所以, 将在变成 stringvar 的而位补 o ( 由 于一个 Ascn 字符对应两位卡λ进制 数字, 所以在此补上 6 个 1-六进制数字 O. 对应 3 个 ASCII 字符). 而对于字符串的合并 {stringvar川l !"} 网1)好为 14 个半符, 所以赋值完成后不对 stringvar 的商位补0。 ( 1 ) 字符串操作 对字符串通常有复制、 合 并 、 比较这些操作. 复制是通过简单的赋值操作实现的. 而 合并是由连接操作符来实现的. 比校哇j 山相等操作符来实现的。 当 阳 市将. 措矢盘来处理字 符串时, 寄存器矢髦的位数笔少为 S.n (n 为 ASCll 字符的个数〉 位. (2) 字符串值的补充和潜在问题 己与将字符部赋值给变班时 , 如果字符净 的位宽 小 F变 i益的位宽 , 则应当在变 j茸的左端 ( 高位〉 补 0。 这种 补 0 可能会影响比校和合并操作的结果. fl:1:J.J比较和合并操作符并不区 队 75 \ • 分补充 的 0 值和原始的字符串 字符喻, (ASCU 码为 0)。 下面将举例说明这种潜在的问题. E 例 2-50] 字符@ 补 0 的潜在问题. reg [8* 1 0 : 1 ) s 1 , s2; l:litia� begin 51 "He11o"; = s2 " world ! " ; = 主f ( { s 1 , s2 ) -- " Hello world ! " ) $displa y ( " strings are equal " ) ; end 本例中的 比较操作返回结果值为 " 假 "。 因 为 在将字符串赋值给变量时, 对变茧的左 端进行 了 补 O. 赋值完成后, 变 量 s l 和 s2 的结果如下: 51 - 000000000048656c6c6f 52 - 00000020776f726c6421 而合并操作的结果为: { s l , s 2 } =000000000048656c6c6f00000020776f726c6421 因为字符帘'HeJlo world!"不包含 O 值补充, 比较的结果将为 o ( 即 为 " 假 吟 , 这可用 图 2-4 加 以说明. f 〈?一--., � 飞 航阳)()(l(阳)(4865仇c:f饥lO6O207 仔2位6421 4865位6c:6C20n6m6c:642I "HeIJo'" '"、‘lorld'" 回 2-4 字 符 耶 鲁 ← 0 的精{E问题 (3) 空字符帘处理 �字符串 " " 被看做等效于ASCU 空字符 "飞。" C具:值为 0), 而 与字符串 "0" 不 同 。 2.10.3 延迟表达式 Veri10g HDL 中 , 延迟表达式的格式为用囚括号括起来的三个表达式, 这三个表达式 之 间 用 冒 号 ( : ) 分隔开. -t个表达式依次代表最小、 典电、 最大延迟时间值. 具体的延迟 表达式语法格式如下: constant_expression : : = con5tant_primary I unary_ope rator I attribute_instance ) constant_prlmary I con5tant_expression bioary_operator ( attribute_instance ) constant_ expres5ion l c。nstant-expression ? { attzibute-instance l constant-expression z / 76 IA . 第 2 . VeriIc咆 constant_expression I strinq constant_mintypmax_expression : : ­ constant_expression | c。nstant-expres si。n : c。nstant-exPEes Sion : constant-express ion expression : : ­ primary I unary_operator ( attribute_instance ) prμnary l expressi。n binazy-。PeraEOZ { attribute-instance } expressi。n I conditional_express�on I string mintypmax_expression : : = expression I expression : expression : expression constant_primary : : constant concatenation I constant function call I ( constant_mintypmax_expression ) I constant_multiple_concatenation I genvar_identifier I number 1 parameter-identifier I specparam_identifier pr1lI\ary : : ­ number I hierarchlcal identifier I hierarchical identifier [ expression ) { ( expression ) ) I hierarchical identifier [ expression ) ( [ expression [ range_expression ) I hierarchical_identifier [ range_expression ] I concatenation I multiple_concatenation I function call | s ystem-functi。11.,call I constant function call I ( mintypmax_expression ) 下面举例说明延坦表达式的用洁。 E例 2-51 ) 延迟表达式的使用 。 ( a : b : c ) + ( d : e : f) / /;极小延迟值为 a+d (J!J;阳 . 典型延迟值为 b 吨 的 和 . 战大延jß值为 / / c + f 的 和l val - (32 ' d 50: 32 ' d 7 5 : 3 2 ' d 100) 2.1 0.4 表达式的位宽 为 了 对表达式求值时得到可靠的结果, 控制农达式的位宽是非常重要的。 征某些情况 下采取最简单的解决办?去, 比如两个 16 位的寄存器矢 缸的位排序方式和操作被指定, 那 么 结果就是一个 1 6 位的值. 然而在某些情况下, 究竟有多少位参与表达式求值或者结果 队n\ 帽乱 跑黯疆摩设计实倒精瑞 奋多少位, 并不是显而易见的. 例如两个 1 6 位操作数之间的算术加法, 是应该使用 1 6 位 求值还是该使用 17 位 〈 允许进位位溢出 〉 求值? 答案依靠被建模设备的类型以及那个设 备是否处理进位位溢出来决定. vt町ilog HDL 利用操作数的位宽来决定布多少位参与哀达 式的求值。 1 . 亵达式位宽规则 控制表达式位宽的规则 已经公式化, 因此在大多数实际情况下, 拥l旬一个简单的解决 方法. 表达式位览是由包含在表达式内的操作数和表达式所处的环境诀定的。 自主表达式 的位宽 由 它 自 身 单独决定, 比如延迟表达式. 环境决足型农达式的位宽由读表达式 自 己 的 位览和它所处的环境 ( 实际上该表达式本身又是另外一个表达式的一部分 〉 来决定, 比如 一个赋值操作中右侧表达式的位 宽 由 它 自 己的位宽和赋值符左侧的位宽来决定. 表 2-31 说明了 表达式的形式如何决定表达式结果的位宽. 在表 2-31 巾 , i 、 j、 k 都表示单操作数 的丘地式, I币 L(i)代哀衣达式 i 的位宽, op代表操作符. 表 2-31 表达式位宽规则 . .i3 式 小)Î! t(:'IU� 自由..f鱼. 与整致相同 冒t 明 定K1曾做 与给定的位宠相间 ì op j . t量作衍。p)句3 + _ . '''.' & I ^ ''- or...l' 。 肘 ,操作衍 。p J.J. +-- mu(时í).L(j)) L(i) i opj. 除作衍 。p J.J: 1 位1 . d o C Tl JV' -1--1叫I , > > - < <- R.k.i占式f此时 . 1Il个妹作做的 位�部统:全为 max(L(i).L(j)) 。pU曾刊 衍 。p .J)(. &-& I 叶 ^ "- or ...JI 1位 IVHi�陪你虫�ðØIé I�I ;;二l次占i 式 i opj. Ii作f.} op λI , >> << •• >>> <<< i ?j : k (i... ,), (iU.....kll L(i) max(L(j).L(k)) uη+...+ L(j) i气L(ì)+...+ L(j)) j )ên b�l占式 i 处 1'.1 主4划在式 所{i操作敛�U在自主<<达式 所有除价l'L郁结白 -F.�占总式 2. 表达式位宽问题举例 在表达式求值过程 中 , 中间结果应:与采用 具有届太位宽操作 数 〈 如果是在赋值语句巾, 也包括赋值符的左侧 〉 的优宽。 在表达式求值过程中要注意避免丢失数据的重要位. 下面 举例说明. 1 78 /' '商 2 章 E例 2-52) 表达式位宽问题举例 1 • reg [ 1 5 : 0 ) a , b , answer; answer = ( a + b ) >> 1 ; 1 1 声明三个 16 位寄存粮矢盘 11 不能E确达到 目 的 上式的 目 的是 a 与 b 相加 〈可能导致淄 出 ) , 然后再右移 l 位 , 以保存ill:位位到一个 1 6 位的寄存器 answer 中 . 这样问题就来了: 因为表达式中所有操作数都是 1 6 位位宽, 因 此表达式 ( a + b) 产生的中间结果也仅仅是 1 6 位位宽, 这样在执行右移 1 位操作之前. 就已经丢失了进位位. 解决办法是使表达式 (a + b) 按照至少 17 位位宽来求值. 例如在 表达式 (a + b ) 中加上黯数值 0, 则表达式求值时将按照整数的位宽来执行, 如下所示: answer = (a + b + 0 ) >> 1 ; 11能够正确达 到 目 的 E例 2-53 ) 表达式位宽问题举例 2. module bit1ength ( ) ; reg ( 3 : 0 ] a , b , c ; reg ( 4 : 0] d ; initia1 begin a - 9; b - 8; c - 1; Sdisplay ( " answer - 屯b " , c ? (a&b) : d) ; end endmodule 仿真结果为: answer = 01000 对于表达式 (a&b). 应. Z均属于环境决定型表达式, 它本身的位宽 为 4, 但它又足条件 表达式的一部分, 所以应当采用是大位宽操作数 d 的位宽 5 作为 自 己的实际位宽. 3. 自 主表达式举例 E例 2-54) 臼主表达式. module se1f determine; reg [ 3 : 0 ] a ; reg [ 5 : 0 ] b; reg [ 1 5 : 0 ] c; initial begin a " 4 ' hf; b 酶 6 ' ha ; 队 79 \ $displa y ("a*b=毛 x " , a*b) ; c = (a**b); $display ( "a**b=屯x", c ) i c = a*舍b; $display( "c=奄x", C) i end endmodule //表达式 a*b 为 自主表达式 / / 由于操作符号' 仆的存在 //表达式 a**b 成 为 自 主表达式 //表达式 a**b 位宽出 c �定 本例的仿真输出结果如下: ♂b=16 a**b=0021 c=ac61 / / 由子表达式 a白 的位宽为 6 . 所以相乘结果 96 被截短为 16 //表达式 ( a * 吨 } 位宽 为 16 ( c 9<1位觉〉。 由 于 俨 咆 是 ; 自主表达式, 它的位宽 / / 为 6, 所以其值为 21. 生穿过赋僚操作后, 在表达王�补 0 , 从而制l蹋终结果0021 //表达式 a忖b位宽为 16 2.10.5 育符号表达式 为 了得到可靠的结果, 控制表达式的符号是非常重要的。 除了文章后面概括的规则, 两个系统函数$signed( )和$unsigned( )也应当用于处理表达式的符号类型. 这两个函数对输 入表达式求值, 然后返回一个同输入表达式位宽相 同 、 大小相同的值, 但是返回值的符号 类 型 由 系统函数决定。 • $signed: 返回值为有符号型. • $山lSigned: 返回值为无符号型。 下面举例说明。 . E例 2-55) 系统函数$sign创( )和$unsigned( )的应用. reg [ 3 : 0 ) regA; co reg signed [ 3 : 0 ) regS; regA = $unsigned (-4) ; / / regA = 4 'bll00 regS = $signed ( 4 'bll0 0 ) ; 1/ regS = -4 1 . 表达式符号类型规则 · 表达式的符号类型仅仅依靠操作敬, 与 LHS ( 左侧 〉 值无关。 · 简单十进制格式数值是有符号数. · 基数格式数值是无符号数, 除非符号 ( s) 用 于基数说明符 〈 例如 4'sd12 ). · 无论操作数是何类型, 其位选择结果为无符号型. · 无论操作数是何类 型 , 其部分位选择结果为无符号 型, 即使部分位选择指定了 一 个完整的矢量。 / 80 14 , 第 2 1撞 Veri问 E例 2-56] 部分优选择结果的符号类型. reg ( 1 5 : 0 ) a ; reg signed [ 7 : 0] b; initia1 a - b(7:0); // 发达式 b [ ì : O ) 为无符号型, 因此在 a 的高位用 。 补光 · 无论操作数是何类型 , 连接 (戚复制〉 操作的结果为无符号型. · 无论操作数是何类型, 比较操作的结果 ( 1 或 0) 为 无 符 号 型 . · 通过类型强制转换为辑型的实数为有符号型。 · 任何 自主操作数的符号和位宽由操作数 自 己 决定 , 而独立于表达式的其余部分. · 对于非 自 主操作数遵循下面的规则: 》 如 果有任何操作数为实型, 贝IJ结巢为实型: 》 如果街任何操作 数为无符号型 , 贝IJ 结 果 为 无符 号 型 , 而不论是什么操作符: 》 如果所有操作数为有符号型, 则结果为有符号型, 而不论是什么操作符. 2. 襄达式求值步骤 · 根据前述表达式位宽决定规则, 确定表达式位宽 . · 根据表达式符号规则 , 确定表达式符号. · 将表达式中每一操作数 〈 自 主操作数除外 〉 的 符号类型强制转换为表达式的符号 类型. · 将衷达式中每一操作敏 〈 自 主操作数除外 〉 的位宽扩展到表达式位宽. 当且仅当 操作数为有符号 型 〈 在符 号 类 型强制转换之 后 〉 时, 对其进行符号扩展. 3. 对赋僵表达式求值的步骤 · 根据赋值表达式位宽决定规则. 确定 LHS ( 左侧 〉 位宽. · 如 果有必要, 对 LHS (左侧 〉 位宽进行扩展. 当且仅当 LHS 为有符号型时, 对其 进行符号扩展- 4. 在有符号表达式中如何处理 x 和 z 如果一个有符号操作数的位宽被扩展到更大的位宽, 而其符号位值为 X, 那么结果值 的宅闲位同当用 x 进行补充: 如果其符号位值为 Z, 那么结果值的空闲位应当用 z 进行补 充. 如 果一个有符号值的任意一位为 x 或 Z, 那么包含该值的任何非逻辑性操作都将产生 一个完整的结果值 X, 而该结 果 的符号类型与表达式的符号类型一致. 队 81 \ • 第 行为级建模 前面已经提到过樱 块的儿种建模方式 ( 也叫做描述方式 ) , 包括行为级跑榄 ( RTL 级 建棋也属 于行为级建模〉、 结构级建棋 (包括f J级建棋和开关级建棋〉 以及行为级和结构 级的混合边 模. 当模块内 部只包含过程块和连续赋值语句 (asgsi n), 而不包含模块实例 ( 模 块调用〉 语句和基本元件实例 〈 基本元件调 用 〉 语句时, 就称该校 块采 用的是行为级姐 棋: 相反 , 当模块内 部只包含模块实例和基本 元件实例i吾句, 而不包含过程块语句和连续赋值 语句时, 就称该模块采 用 的是结构级建棋: 当然在模块内部也可以果 用这两种n 棋方 式的 结合, 即混合建棋方式. 本12主 要介绍行为级也棋方式, 关于结构级建模将在第 4 .4t 介绍. 行为级建模的 目 标不是对电路的具体硬件结构进行说明. íι:J在 为了 综合及仿贞 的日 的 而进行的. 行为级建模常常用于复杂数字逻辑系统的顶层设计 , 也就是通过行为组建模把 一个复杂的系统分解成可报作的 若 下 个模块, 每个模块之 间的理辑关系通过行为模块的仿 JL加 以验证 。 这样就能把一个大的系统合理分解为若干 个较小的子 系统, 然后阵将每个子 系统用可综合风格的 Veriglo HDL 模块 l(' J级结构!:oc RTL 级、 3草怯级、 系统级的棋块〉 加 以描述. 同时行为级建模压 可以用来生成仿页. 激励信号, 对己设计 模块进行仿真验证 . 例 如 , 行为级边 模对于解决微处理器描述或者组杂时序控制这类的 问题 是非常合适的. 3.1 行为级建模的结构 Veriglo HDL 中模块的行为组建模方式的基本语法格式如F : module<缺块名> () 模块端口说明 {盖全数定义] 扳倒炎型说明 '自3. 过程块 ( initial过扭块或always过程块, 可以有一个或多个〉 连续赋值滔句 [任务定义 (task) ) I函�定义(function) ) endmodule 针对t;峰 语法格式进行如下说明. · 方 括号 " []" 内 为 可选项。 • : <块名〉 〈 块肉局部交虽说明〉 时间控制 l行为语句 1: lI.t问控制 n行为爵句 n; 〈块定义语句 2> 针对上述格式, 做如 下说明。 · 过料, 语句关键词 inir ial 衰明该过程块是一个 inilial 过秤, 块. • <块定义语句 1>和〈块定义语句 2>构成了一组块定义语句, 它们可以是 begin-end 语 句组i或fork-j oin语句组。这两条块定义语句将它们之间的多条行为谣句组合在一起, 使之构成一个语句块, 并使其在格式上更像一条语句. 去与谓合J 块l-þ只包含一条行为 语句并且不需要定义块名和块内局部变盘时, 这两条块定义语句可以省略。 - 4莫 名〉为可选项, 块名可以为语句块创建一 个局 部作用域 . 定义了块名的过程块称为有 名块, 在有名块内可以定义局 部变量, 有名块内部语句的执行可以被 disable 语句中断. · 块 内局部变量说明也是可选项 , 只有在有名块内才可 以 定 义用 部变量, 并且块内 局部变量只能是寄存器数据类型. · 时间控制用 来对过程块语句的执行时间进行控制 . 它可 以是任何一种时间控制方 队 85 \ 应用雹霹酷镇偶精谓 式。 有关时间控制方式将在后面的章节介绍. · 行为语句可以是下 列语句中 的一种 : 》 过程赋值i吾句 〈 阻塞型或非阻塞型过程赋值语句); 》 过程连续默 值语句 (剖 signl d回 ssign �立在í' force/ rele部e 语句组); );> if条件分支语句: );> case 条件分支谓句: 》 循环控制语句 ( forever. repeal. whli e. for 循环控制语句); );> wait等待语,1:IJ; );> disabl e 中断语句: 》 事件触及 语句 〈event-时 gger); 》 任务调用 谓仨'.) (用户 自 定义任务必系统任务). 注意:J:.迫行为语句中的赋值语句(除岛rulrel幅民过程连续赋值语句外}只能 对寄存罄型吏量进行赋值. initiLa 过秤, 块的使用1: 要 是面向功能仿真, 不具有可综合性. 它通 常用于实现仿真激 励棋块的初始化、 监视、 被形生成等功能: 而在对硬件功能棋块的行为拙述中 . initial 过 程块常常 用 来对认铺 执行一次的进程进行描述 , 例如它可 以用来为寄存揣 变量 赋初值。 下面是有关 initial 过和块的例子. E例 3-3) inti ial 过程块用于对变量和有,俯 器进行初始化. module register_ initialize; parameter SIZE-I024; parameter BYTESIZE=8; reg[BYTESIZE-l : O ] memory(SIZE-l;Oj ; //严明一个存储量量 reg areg; initial //声明一个寄蒋器变盘 / / initial过程1ft句 begi n : S EQ_BLK_A // 块定义语句. SEQ_BLK_A 为块名 integer index; / /计数变应. 只J块肉j心制l交血 for( index-O ; index: <块名〉 〈块内用部变i过说明〉 时间控制1行为语句1: 时间税制n 行为语句n; 〈块定义i否合� 2> 针对上述棉式, 做如下说明. · 过程语句关键词 alw ays表明出 过程块是一个 aiw ays 过程块。 • @ ( 敏感事 件列 表 〉 是可选项 , 带有敏感事 件列表的语句块被 称为 " 出事件控制 \ 87 \ 噩酶雹摩酷镇饵黯鹊 的语句块", 宫 的执行要受敏感事件的控制. 敏感事件列衷的格式为: (event-expression (or event-expression)) 敏感事件列表是由一个或多个事件表达式 ( event-expression ) 构成的, 当非在多个表 达式时用。 r 将它们组合起来o or 用 来 说 明 : 只要发生了敏感事件列表所 列 出 的 多 个 事件巾的一个, 就将启动后面语句块的执行。 敏感事件列表实际上 代表了一个事件控 制类型的时间控制. 有 关时间控制 、 事件控制和敏感事件列表将在后 面 的 章 节介绍 . • alw ays 过程块中 关于块定义语旬的规定和 initial 过程块巾 的忻况 一样, 它们可以 是 begin-end 语句组� fork才 oin 语句剑 , 这两组 语句组 构成的�ft句块分别称为顺序 语句块和并行语句块。 当过程块内只包含一条语句且不简 要定义块名与块内局部 变盘时, 块定义语旬可以省略。 • <块名〉为可�项, 对它的规定与 inilial 过程块中的情况一样. 定 义 了 块名 的过程 块称为奇 名 块 . · 块内局 部变母 是可选项, 对它的 规 定 与 initial 过程块 巾 的情况一样 。 只在 在奋 名 块 内 才能定义局 部变量, 块 内局 部变量只能是寄存器类数据 类 型 . · 时间控制用来对过程块内 各 条语句的执行时间进行控制. 其作用与 initiaJ 过程块 中的时间控制部分作用是相同的. · 对行为语句的 规定与 initiaJ 过程块 中 的情况相同 . 从k述ì1t法格式定义可以看出 .alw ays 过程块和 initial 过程块在格式上的区 别主要在f: alw ays 过程捐句后面可以街 一个敏感事件列哀, 该敏感τJH-t 列 衣 的 作 用 是 用 来激活 alw ays过耻语句的执行: I币 initial 过程语句的后面不允i午有敏感事件列点. 在:ilHi仿且 时, 和 initial 过程块一样. alw ays过程块是从仿点 时真IJ 0 开始 执行的. 但 是 alw ays 谓句任仿真过程中是不断需复执行的 , 而不 像 initial 过和 块小 的语句那 样在执行 -议后 就被挂 起 , 不会再次执行。 并且. aJw ays过程块内各条 语句J的:rüE 执行必须由敏感 事件gij农 巾 列 出 的 事件进行触发才 能启动。 如果 alw ays过剧, 块 ' 1 1 的 i盘磁!H 件州 农默认, 则 认为触发条件始 终被满足. alw ays 过程块将无条件地循环执行下去, 且主IJi且到$fin isb 或 $ stop 系统任务为J1:0 敏!啤iJ. 件�'J衣山一个或多个事 件表达式 ( event-expression) 构成, �J. 件.&. 达式说明了 启动块内语句执行时的触发条件. 当存在多个事件衣站式IH盟阳关键词。 r 将多个触发条件 组 合起来o Verilog制 定 : 只要这些事 件表达式所代表的多个触发条件中有 一个成Tl.. 就启 动块内 谓句的执行. 例 如 , 在下面谓台j叶' : always @ ( a or b or c) begin ..._. end 1 88 ;. .3. always 过程块的多个事件表达式分别是信号 a、 b 和 C. 它们代表的触发条件分别是信 号 a, b, c 发生变化, 这三个事件表达武之间以 关键词。 r 分隔 . 只要信号 a、 b、 c 中任意 一个值发生变化. begin-end 语句块的执行就被触发: 而如 果 a、 b、 c 的值都没发生变化, 则 begin-end 语句块中的语句不被执行. 此时由 于 aJ ways 过程语旬的重复 执行的特点,仿 真过程将不断对触发条件进行监测 , 等待 a、 b、 c 信号发生变化。 aJways 过程块的使用主 要是对硬件功能模块的行为进行描述, 它也可以在仿真模块中用 来对时钟进行描述。利 用 always 过程块可以实现锁得 器和触发器, 也可以用来实现组合逻辑. 用 aJ ways 过程块实现组合逻辑时要注 恩 将所有的输入信号都列入敏感事件列衰 , 而在 用 always 过程块实现时序逻辑时却 不一定要将所有的输入信号都列入敏感事件列表. 敏感 时 间 列 表 中未 包 含 所 有 输 入 信 号 的 情 况 称 为 不 完肇 事 件 说 明 ( IncompJ ete E vent Sp臼 if ication)0 不完整事件说明情况在仿真. 时可能会引起仿真器的误解,如 下面的例子 所示- E例 3-5) 敏感事件列表中未包含所有输入信号的情况. m。dule thzee-input-and{E, a,b, c ) ; 。utput f ; input a , b , c; reg f ; always @ (a or b) begin f-a晶b&c; end endmodule 例 3-5 描述了一个三输入与门 , 由于 输入信 号 c 没有出现在敏感事件列表巾 , 所 以仿 真时当输入信号 c 发生变化时不会重新计算 f的值。 因此,仿真得到的约 果并不是一个三 输入与门 的功能行为. 摆正确实现i 输入 与 f J应该采 用例 3-6 的描述方式. E例 3-6) 敏感 事件州 表中包含 了所有输入信号的情况。 module three_input_and ( f , a , b, c ) ; output f; input a , b , c ; reg f ; always @(a or b or c ) begin f帽a&b晶c; end endmodule 在使用 aJ ways 过程tJ.t 时足 要注 ZEAif免 引屈仿真死锁状态 的发生 . 怵jI .J aJ ways 语句街 重复 执行的特点, 所 以当 敏感事伺工 列表默认时, 语句块将一直循环执行下丘 , 这就有可能 队 89 \ 噩噩雹事审慎倒躏讲 在仿真 时产生仿真死锁情况. 如 例 3-7 所示。 E例子7)不恰当 使用 always 语句而产生仿真死锁。 always begin clk=-clk; end 上例中 的 alwasy 语句不带有敏感事 件列表, 所以 be gin-eod 语句块的执行 是无条件重 复进行 的。 这样当 仿真 进程进行 到该 always 过程块后 〈 假 定 为10 时刻), 将开始重复执行 块语句。 clk-句clk; 由于该语句没有时间控制部分 , 其每次执行 都不需要时延, 这样仿真 进程就将停留在 10 时刻不断地重复执行 这条语句. 这样, 仿真 不能往下一时刻继续运行 , 进入了一种仿真 死锁状态. 要避免死锁状态的出现, 需要为语句块中 的语句加上延时控制, 则 该 alwasy 语句块将成为一条非常有用的描述语句, 如i 例 3-8 所示. E例 3-8 ) 为避免 仿真死锁采取的措施. always begin nO c l k-‘clk; end 该例将生成一个周期为 20 个时间单位无限延续的信号波形. 3.2 语旬块 所谓语句块是指 initial 过程块或 always 过程块中位于过程语句 ( initial 语句马克 alwasy 语句〉 后面, 由" 块定义语句1 " 和" 块定义语句 2 " 所界定的一组行 为语句. "iJk: 定 义 悟 句 1 " 和" 块定义语句 2 " 构成了一对" 块定义语句"。 块定义语句分为两种. · 一种是 begin-end 语句组 , 用 来组合需要顺序执行的语句. 由 begin-end 吾i 句组标 志的语句块称为" 顺序块n . · 另一种 是 fork-joi n 语句组 , 用来组合需要并行执行 的语句。 由 fork才oin 语句 组标 志的语句块称为" 并行块飞 " 块定义语句 1 " ( begi n戚 fork 语句〉 标 志 了 谓句块的开始", 块定义i否合!J 2 " (end 或 join 语句〉 贝IJ 标志着 语句块的结束.当 语句块内只有一条语句时, 块定义悟。J可以省略。 如果在定义语句块的同时还寻|入了一个块名 , 则该语句块可由这个块名唯一标识, 该 / 90 h 语句块被称为一个" 有名 块飞 在有名 块内 可 以 定 义 内部寄存器变眶 , 并且可 以用 " di sabln e 中断语句来中断有名 块 内语旬 的执行. 同时语句块的块名 还提供了 唯一标识寄存端的一种 方法. 语句块只能出现在行 为描述摸块中 , 但它不一 定非要 出现在与过程语句 initial 或 alwasy 的 结合中 . 例如它还可以出现在条件分支语句 、 循环 控制语句及任务和函数中. 下面分别介绍顺序语句块和并行 语句块. 3.2.1 颠廖语句块 ( begin唱nd) 顺序语句块定义语句为 " begin- end". 顺序块巾 的 各 条语句按顺序一 条一条执行 , 其 语法格式如下: hu e nv .l 川 块 〈 内 块 肉 各〉 部变 盘 说 明 时向控 制 1 咱丰 行 为 ·治 句 时间接$1) n end 行为活1-1] n 其中, 块内局 部变蛊 可 以 是 reg 型变应卢明语句 、 i nteger 型变E卢明语句 及 r臼 l 型 变量声 明语句。 顺序块执行 时的特点如下: · 顺序块内 各 条语句是按它们在块内出现的议序连 条顺序 执行 的 , 当前面一条语句 执行 完毕后下一条语句才能开始执行。 · 块内每条谓句的延时控制都是相对于前一条语句仿真 结束时刻的延时控制. · 仿真 时 , 如 果遇 到顺序块, 块 内第 一条语句随即开始执行 : 当 顺序块中 最后一条 语句执行 完毕 时, 程序流程控制就跳出顺序块, 顺序块结束执行 。 整个顺序块的 执行 时间等于其内 部各条语句执行 时间的总和。 下面是一个顺序语句块的例子. E 例3-91 一个时钟上升沿控制的 3 忧移位寄非辘 . rn。dule three-bit-shift-zeqIstez tclk, d-in , d-out ) J -- npu t c- k J -lnpu t d- - - n-' . out ‘ preg O m,• }UE al wa ut d- 。ut., ze9 ys8 - { ap , renud seAM d q - bd。 eck begin d-。ut=re9-b J • req-b=Eeg-aJ \ 91 \ re9_a=d_in; end endrnodule 在 例 3-9 中 的代码中 包含 了一个 begin-end)顺 序语句块 , 它属于 aLw ays 过程块的一部 • 分 . 时钟的上升沿跳变将触发顺序块的执行 : 第一条语 句 首 先执行, 将 reg_b 的值赋给 d-out: 然后流程控制转到第二条语句, 并执行, 将 reg_a 的伯赋给 reg b: 然后执行第 3 条语句, 将 d-in 的值 献给 rge _8 : 最后程序流程跳出顺序语句块, 顺序语句块结束 执行. 下面是一个带有延时控制的顺序语句块的例子。 E例 3-101 带有延时控制的顺序语句块, 用 于产生时j于被J辱。 m。du le sequential-s i9na l Egentd-。uE ) J parameter d - 50; / /声明一个参数d 。utput [7:0) d_out; reg (7:0) d_outi // 声明一个有于仔器d out initial begin / / I11PI!l!1 i�短时拍制的旅形 d out - 'hOO; td d out - ' h35; td d out - 'hE2; fd d out - ' hOO; td d out - ' hF7; end endrnodule 如 国 3-2旷源 为该例的仿tI 输出波形. l喝3-2 份有延时控制的顺j沪语句挨产生的时If波形 3.2.2 并行语句 块 ( fork才。in) 并行语句块的定义市 句为 " fork才io n". JHiì吾旬块 中 的 多条语句是)f 行执行的. 某 语 法格式为: fork:<块名〉 以t内用白宫变应说IYJ 时间搜制l 行为ìlt�IJ 1 / 92 / '目3蠢 行 ..... . 11{削控制 n joio 甘为泊1'J n 其巾, 块内局部变盐说明可以是rcg割变虽声IVJm-句、integer 1旦变是声明语句、real 型变量声明J识也J、time型变�l:卢明语句必过1件(event)卢刚语句. 并行语句块执行时的特点如下: • 并行语句块内各条谓句是同时并行, 即当科J乎流程控制进入)f行块后, 块内各条 语仑iJ!.ß各自独立|斗时开始执行. 各条语句的起始执行时(IIJ lftl等于理序流科控制进 入城井行语合!,)�的IH闷。, · 块内各条 语句的延时控制部;在相对1工程序流N控制进入并行语句块的时刻的延 时, 即相对于并行iR句块开始执行时刻的延时. • 当并行语句块内所有m句部已给执行完毕后. UP马执UU.tI'nJ最快的那一条块内语 句结*执行后, 程序流程控制跳111t1二行块, 纠�Uf行语句:快的执行。 较个对-行语 句块的执行时间等f执行时间挝氏的那条语{�J所丽的执行h-tl可. 下面是并行语句块的例子. E 例 3-U) )1-1并行语{JJ�产生时jJf波彤。 module parallel_signal _gen (d_out ) ; output [7:01 d_out; reg [7:0] d_out; initial fork d out - 'hOO; 51.\10 d-out .飞. ' h 35 ;1 .100 d out - ' hE2 ; '150 d out - 'hOO ; 1200 d out. 圃 , hF7; join endmodule 本例剧并行语句块产'1.: 时序液)路, 13例3-10巾的模块sequential_signal_gen Ú同样的 功能. 如剧33- 所示为本伊J ñ: 其 中 : 符号 ( 的 是延时控制的标识符; <延迟时间〉是 直接指定的延迟时间盘, 它表 示 仿真时间单位的个数 , 可 以是一个立即数、 变;最或表 达式. 如 果代表 〈延迟时间〉的变盘 或表 达式的值 为 未知 ( x) 或高阻 ( )z , 贝IJi亥 延时控制等效子 。 延迟 : 如果代表 〈延迟时间 〉的变盘或表 达式的值为负值 . 则 以该负值 二进制补码所代表 的无符号整数值 作为实际的 时间延迟量。 1 . 第一种形式的延时控制语旬 这种形式的延时控制语句在〈延迟时间〉后面跟着 一条行为语句. 在这种悄况下 , 仿真 进程在遇到这条带有 延时控制的行为语句后并不立即执行行为语句指定的操作, 而 是 要 延 迟到〈延迟时间〉指定的时间最过去 后才开始 执行行为语句指定的操作。 E 例 3-151 第一种形式的延时控制语句。 �10 rega = regbi //<延迟时间〉为立即数 iò rega = regbi 1/<延迟时间〉为参数 们(d+e) 12) rega = regbi 1/ <延迟时间〉为表达式(d+e)/2的值 iregr regr = regr + 1i //<延迟时间〉为交盘regr的值 2. 第二种形式的延时控制语旬 在 这种 格 式 中 , <延迟时间〉后 面没有出现任何 行为语句 , 而 只有一个语句结束符号' ( ; )。 在这种情况下, 仿真进 程在遇到该延防地制语句后不执行任何操作, 而是进入 一种 等待状态, 直到过了〈延迟时间〉指定的时间盘 , 才 结束这条延时控制语旬的执行 。 这种 形 式 的延时控制语句出现在顺序块和并行块中时, 产生 的作用是不同 的 。 E 例 3-161 第二种形式的班 时控制语句用于顺序块。 begin HOi a=bi end 等价 于语句: #10 a-bi /98 h 由上例可见, 第二种形式的延 时控制语句是使该控制语句的下一条语句执行时刻延 迟 了指定的时间量。 E例 3-17) 第二 种形式的延 时控制语句用于并行块 。 fork clk=O; tlO clk=l; 量10; '20 c1k-1; )Ol.n 在 上 例 中 , 语句句lOi" 不会对并行块 的 仿真时序产生任何影响. 如果将该语句改 为 "#30飞 那么 该语句将是并行块 中执行结束时刻最长的一条语句. 只有在该语句执行完毕 后 , 并行块 的执行才能结束. 3.3.2 边沿触发事件控制 事件控制方式是时间控制的另一种方式. 在这种时间控制方式下, 行为语旬的执行需 要 由 指定事件的发生来触发, 该事件称为 "触及事件". 在la ways 过程块 'IJ所使用的敏感 事件列 表就是一种事件控制。 事件控制方式不仪能用于 a1ways 过程块 , 而且.if可以用于其 他的行为语句. 事件控制方式又可以进一步分成两 类 : 边沿触及事件控制和电平敏感1JJ仲 控制 . 在此只对边沿触丘 事件进行讨论, 电平敏感事件控制留待后面叙述. 1 . 边沿 触发事件控制 这一类时间控制方式在指定的信号变化时刻, 即在指定的信号跳变边沿才触发语句的 执行: 而当信号处F稳定状态时则不会触发语句的执行. 边沿触发事件控制的 语法格式有以下儿种: • @ (<事件表达式》 行为语句: • @ ( <事件表达式>): • @ (<事件表达式l >or<事件表达式 2>or...or<事件表达式0 >) 行为语句: • @ (<事件表达式l>or<事件表达式 2>or...or<事件表达式n>). 在上述四 种格式q1 . 符号 li@" 是lh沿触及事件控制的标识符 , ae 事件及达式"代 表 触发语句执行的触发事件: 而 " 行 为 语句 " 则指出 了触发事件所要触发执行的具体操作。 《 事件表达式l >or<习叫牛 表达式 2>or...or什I件表培 式 n>) 称为 "敏感币件列表飞 (1 )事件表达式 事件表达式可 以是下面三种形式之一: • <信号名〉: \ 99 \ • pose dge <信号名 〉: • negedge <信号名 λ 其 中 . <信号名 〉可 以 是任何数据类型的标量或矢皿· ① 第一种事件表达式形式: 代表的触发事件是〈信号名 〉所指定的信号发生了某种逻 辑变化〈不论是正跳 变还是负跳 变0) 它是信号除了保持稳定态以外 的任意一种变化过程. 比如语句: 芭(req-a)ze9-b=req-a J 就表示触发赋值语句 11 reg_b可eιa; " 执行的触发事件是信 号 Itreιa " 的逻辑值发生 了 变 化, 只要 reg_a 的值从 0、 1 . x. z 四个值中的一个变化到另一个 〈 比如从 l 变化到 z). 赋 值语句就被触发, 执 行对应的赋值操作 〈 将 r eg_a 的值赋给r eg_b)o ② 第二 种事件表达式形式: 在〈信号名 〉前加上关键词 posedge. 代表的触发事件是〈 信号名 〉所指定的信号发生 了 正跳 变。 所ìltl 正跳 变就足指发生如下逻辑转换关系的一 种: • O-x • 0→z • 0→ l • x→ l • z→ 1 比如语句: @(posedge reg_a) reg_1加re g_a; 表示触及赋值语句 " reg_b=r eg_a; " 执行的触发事件是信号 11 re g_a" 的逻辑值泣 生 了 正跳 变, 只要 reg_a 的值发生了七述丑 种逻辑转换中的一种 ( 比如从 x 变化jlJ 1 ) . 服 值语 句就被触发. 执 行对应的赋值操作〈将 reg_8 的值赋给 reg_b). ③ 第三 种 事件表达式形式: 在〈信号名 〉前加上关键i可n egedge, 代表的触发事件是〈 信号名 〉所指定的信号发生了负跳 变。 所谓负跳 变就是指发生如下逻辑转换关系的一 种 : • l- x • 1 →Z • }-O • x→ 0 • z- O 比如语句: etneged9e zeq-a} re9-b=req-a J 表示触发赋值语句 It reg_b=reg_a斗 " 执行的触 发项件是信 号 " reg_8 " 的逻辑也发生了 负 跳 变, 只要 reg_a 的值发生了上述五 种逻辑转换中的一种〈比如从 l 变化 到 x ) , 赋值语 /1001A 句就被 触发 , 执行对应的赋值操作 〈 将 reg_a 的值赋给 reg_b )。 (2) 语法格式 下面我们再来讨论前面给出 的边沿触发事件控制的四种语法格式。 ① 边沿触发事件控制的第一种语法格式: @ (<哪件表达式》行为语句; 这种语法格式的敏感事件列表内只包含 了一个触发事件, 只有当这个指定的触发事件 发生之 后 , 后面的行为语句才能启动执行: 在仿真进程中遇到这种带 有事件控制的行为语 句时, 如 果指定的触发事件还没发生 , 则仿真进程就会停留在此处等待, 直到指定的触发 事件发生之 后 再启动执行后面的行为语句 , 仿真进程继续向 下进行 。 ② 边沿触发事件控制的第二种语法格式: @ CdJJ件发达式> ); 这种语法格式与前面的第一种语法格式一样只指定了一个触及事件, 但 这种格式中没 有行为语句来指定触发事件发生 时要执行的操作。 在仿真进程中遇到这条事件控制语句后 会进入 等待状态 , 直到指定的触发事件发生 之后才 结束等待状态 , 仿真进程继续向 下进行。 ③ 边沿触发事件控制的第三种语法格式: @ (<事件发达式l>or<事件表达式2>or…。r<事件表达式n>) 行为i1i-句: 这种语法格式的"敏感事件列表" 内 指定 了 由 不同〈事件表达式〉代表 的 多 个触发事件, 这些〈事件表达式〉要用关键词 or组合起 来。 只要这些 触发事件中的任何一个得到发生 , 就启动行为语旬的执行。 在仿真进程遇到这种格式的边沿触发事件控制语句时, 如果所有 的触发事件都没有发生 , 贝lJ仿真进程就会进入等待状态 , 直至IJ 其 中 的 某一个触发事件发生 后才启动执行后面给出 的 行为语句, 仿真进程继续向 下进行。 E例 3-18) 边沿触发事件控制语旬 的例子。 initial begin a=l; @(posedge clkl or negedge clk2 or b) a=b; end 在例3-18 所示的程序中, 边沿触发事件控制语句的敏感事件列表内包含 了三个事件表 达式: posedge c lkl 、 negedge clk2 和 b. 其中前两个事件· 表达式分别属于前面讲过的第τ 种和第三种事件表达式形式, 它们指定了信 号挑 变lh 沿种类。 这三 个事件表达式所代表的 触发事件分别是: 信号 clkl 发生正 跳变, 信 号 clk2 发生 负跳变, 信号 b 发生 任何变化。 只 要发 生 了 这三个触发事件中的任一个, 赋值语句 " a=b;" 就被 启动. ④ 边沿触发事件控制的第四种语法格式: 队 101 \ 噩罔疆摩设计实倒躏讲 @ (<1]1件次达式 l>or<事件表达式 2>or"'or<事件发达式 n》: 同 第三种语法棉式 一样, 这种语法格式的 " 敏感事件列哀 " 内指定了 多个触发事件. 但 是这种格式 中没有 行为语句。 在仿真 进程遇到这种格式的il1沿触发事件控制 语句时, 如 果所帘 的触发事件都没有 发生, 则仿真进程就会进入等待状态, 玩到j其中的某一个触发事 件发生后才结束等待状态, 仿真进程继续向下进行. E例3-19) 连续监测信 号a 或 b 发生变化的时间. rn。dule dIsplay-irlf。zrnation-of-change J reg a , b ; / / 声明寄fi.稽变饿a , b initial 11信号a , b如说测试波形 begin a-O; b-O; no a-l; b-O; lt20 a-l; b-l; .30 a-l; b-l; end always / /重复监测�fP} a , b begin @ (a or b) ; //等倍, 直到 a.!b!l. 发'仨1f化后i1!U�得符状态, 并执行下一 /1条语句 $display( "one of a and b changed in time :‘t", $time) ; end • endmodule 对i去快快进行仿真, 其结果为: 曲 。ne of a and b changed in time: lt one of a and b changed in time: j one of a and b changed in time: . n u 咱《 · · U 句,‘ n u 可以看出, 在例 3-19 巾 ,a law ys 过程 块巾 的 begin-e nd 语句块q. 的两条语句可以用下 面的一条语句替换: @ (a or b) $display("one of a and b changed in time : 屯t " , $time) ; 2. 敏感事件列表在a lways过程块中的使用 在3.1.3小节中已经讲过Ja law ys 过程块可以带有事件控制 . 带有事件控制 的a law ys 过程 块既可以实现组合逻辑又可以实现时序逻辑 : 在 用 于实现这两种不同逻辑功能种类 / 10214 '自31撞 时 , always 过程块内 的敏感 事件列表会具有不同特点。 (1 ) 用 always 过程块实现组合逻辑功能 • 事件表达式内不fI�包含po sedge和J negedge 关键词, 即敏感 事件列进 中 的 事件衣达 武只能是前面所述的第一种事件表达式形式。 · 组合逻辑的所有输入信号 都要作为〈信号名〉出 现在敏感 事件列表中 . t面给出的第一个特点是闵 为组合逻辑电路的输出 是由输入电平所决定的, 输入不同 的跳变方式对输出 不会产生任何影响 , 因此敏感 事件列表巾的耶件表达式不能是其余两种 对跳变沿加以指定的形式. 上面给 出 的 第二 个特 点 是 因 为组合迪机的输入输出关系在悔 个 时刻都应该是严棉成 立 的, 即无 论什么时刻输入发生了变化, 在输出揣郁应该立 即千1.反应. 如果某个输入信号 没有出现在敏感 事件列衣巾, 则过程块就不能幢测到该信号的变化, 该输入信号 对输出 信 号的影响 就不能实现, 这样就不能在任意时刻保证组合逻辑的输入输出关系. E例3-2 01 利用敏感 事件列 表来对组合逻辑建模。 module sel_adder_ðnd _multiplier(y , a , b , sel); inpuc a , b , sel; output y ; wire[3:0] a,b; reg [7 : 0] y ; always @ ( a or b or sel) begin if(sel��O) y�a+b; else if (sel= = l ) y=a�b; end endmodule 例 3-20 所示模块有三个输入, 分别是数据输入 a、 b 和 sel. 当 控制信号 sel 为 高电 平 时棋块实现乘法功能. r币当 sel :为低电半 时椒 块实现加'Ì'Ê 功能. always 过程块中的敏感 事 件列表内包含 了所有的输入信号, 当任何一个输入发生 变化部能及时对输出进行 更新. ( 2 ) 用 alwasy 过程块实现时序逻辑功能 • 事件表达式可 以是4H牛 表达式i 种形式任;在 一种。 · 不要求所衔的输入信号郁出现在敏感事件列表的 〈信号名〉中。 因为时序逻辑电路 逻辑状态的改变认求生在某个咸菜几个时钟输入俏。的变化地沿, 而扩1:其他输入 倍号发生变化时也路j逻辑状态保悔不变. 所以事件控制H需对这儿个时钟输入信 号进行监测就可以f. 没有必要把此他输入信号也放入敏感事件列衣11' • E例 3-2 1 1 时钟下降沿触发的 D 触发器• 。 0- U Aaa、m e np d ut- &ES C在&,、E飞Akq, ,cd'·' 4Ab , d ) ,. \ 103\ output q; reg q; always @(negedge clk) begin q=d; end endmodule 在例 3-21中 . always 过程 块的敏感事件列表包含了 事件表达式 " negedge clk". 官 指出 该 D 触发器的改变发 生在 cl k 信 号 的 负 跳变边浩 , 而 在其余时刻 D 触发器状态保 持不变. E例 3-22 ) 同时由两个时钟沿 clkl 上升沿和 clk2 下降沿进行控制的8 位移位寄存器. rn。duleabits-shi Et-register {d-。ut , d-in , C lk l , C lk2}J input clk1 , c l k 2 , d_in; output d-outJ zeg d-OUEJ reg [ 1 : 7] data; reg [ 1 : 7 ] i ; always @(posedge clkl or neqedge clk2) beqin d out=data[l]; for(i - l ; i<7 ; i-i+ l) data [ i]-data [i+ l ] ; data ( 7 ] -d in; end endmodule 在例 3-22 棋块内. always 过程块的敏感 .p:件列表包含f 两个事件表达式"po sedge cl k1 " 和 "negedge clk2飞 这个敏感事件列表农示该移位寄布,辅 的移位操作是LtJ cl k1 信号 的正 跳 变jjJ_站 或 c1k2 倍号的负 跳变Jhj沿 触发的, 移位寄存榻 的 内 部状态和输出 只在这两个跳变jtl 沿发生 变化, 而在其他任何情况下都保持不变。 ( 3 ) alwasy 过程块实现组合 和时序混合 的逻辑功能 要 实现组合和时序混合 的�辑功能. �克们可以通过布一个板 块'1'm立 多个)1:行结构来 实现。 用一个喝 多个带有!jJ件控制的 aJways 过程块来实现时j乎 逻辑部分的功能: 丙川j连续 赋值语句或另外 一个 〈 或 多 个 ) alwasy 过程块来实现组合逻辑部分功能。 在这种ftt况下, 何 一个 always 过和. 块只实现了一类逻辑 , 而我们现在32讨论的是用闯 一个 al ways 过程块 米实现组合和 时序混合的迦刷 功能的怕出 . 在组合逻辑和时恃 逻4l�混合 的情祝下 , 模块逻辑状态 和输出 发'1.: 变化时刻变问M受时 钟跳变沿和 某吨 输入控制信号 的控制, 典哩 的例子 是带片步进位 〈泊字 〉 控制输入n-t 钟跳 ! 1 04 � '自3. 变边陆触发器. 比 如一个带 有异步清零控制输入位 cl r 的时钟上升沿T 触发端, 其 输入输 出 真值表如表 3-4 所示. dIt ? 褒 3-4 带舞步清零的上升�a T触发籍的输入输出真值褒 • 飞 ? c:ur,a…E ? 。 。 。 。 。 。 。 。 四11.'ωk!l) 。 。 。 真值表的第 l 行说明:当南军信 号 c lr 为 '1 时, 无论其他输入信号和触发拇 当前状态 如 何 ( " ? " 表示任何状态 ). 触发器状态 〈 即输出 q ) 将始终为 0; 真值表的第 2 行到第 5 行说明清零信号 clr 为 0 时 , T 触发器处于1正常工 作状态 : 若在 时钟上升沿输入t=0则触发 器状态 保持不变, 而 如 果在 时钟上升沿输入t= 1贝IJ触发器的状态 将发生翻转. 因此在 输入信号 c lr 为 0 时, 触发器的逻辑功能是普通的时序逻辑. Jt 状态 和输出在 时钟上 升沿发生 变化 : 而在 输入 c lr变为1 时. T 触发器的输出 立即变为 O. 这时的逻辑功 能就是关于控制信号饨 的组合逻辑.在 此可以用一个 al ways 过程块来实现这种混合 的逻 辑功能, 如�IJ 3-23 所示。 E例 3-2 3】带 异步泊苓 c Lr ( 高电平有效 〉 的时钟上升沿T 触及器. module asyn-clE-TEE { q , elk , clz, E } J input clk , clr , t ; output q; re9 q ; always @ (posedge clk or posedge clr) be9in if (olr--l) q-O; else if (tcal) q-句q; end endmodule 由例 子23 可 以有i"!:H : 在 实现组合和时序混合 逻辑时, always 南句的敏感τlJ件列表 内 耍包含时J芋逻辑部分的111钟信号以及组什逻辑部分的输入控制信号. 1'1:上例'1'就足时钟信 号 cl k和 控制信号 c Lr邮费出 现在敏感事件州点'1I 0 这两个信号中 的任何一个灰尘 变化都会 启 动忧 gin-end 11刷子语句块的执行:根据控制信号clr的逻辑电平取值, 分别实现组合逻辑 (cl r 为1 时 〉 和时j卡 逻辑 (cl r 为 0 时 ). 虽然可以利刷 一个 always 过程块来实现组合逻机功能或者混合逻辑功能. (且必须注12 \ 105\ 到 aJways 过程块主 要 是 为 了 对时序逻辅建模而寻 |入的一种描述方式。 所以在实际硬件设计 中应该尽量使用结构描述方式 ( 连续赋值语句 、 模块调用语句 、 基本元件实例语句 〉 来描 述组合逻辘, 这样可以便综合后的结果更加接近实际硬件的结构。 3.3.3 电平敏感事件控制 ( wa 民 语句 ) 电平敏感事件控制是与边沿触发事件控制对应的另外 一种事件控制类别。 与边沿触发 事件控制不同 , 在电平敏感事件控制方式下启动语句执行的触发条件是某一个指定的条件 表达式为丑。 电平敏感事件控制用关键词 wait 来表示, 它可以有如下三种形式: • wait ( 条件表达式〉 语句块: • wait ( 条件表达式〉 行为语句: • wait ( 条件表达式)0 电平敏感事件控制的第一种形式中包含 了一个语句块 , 它可以是顺序块 (begin-end) 或并行块 ( fork-join)。 在这种事件控制语句形式下, 语句块启动执行的触发条件是: 条件 表达式的值为其 〈逻辑 1 ) . 当仿真进程执行到这条电平敏感事件控制语句时, 条件表达式 的值为真, 贝IJ语句块立即得到执行: 否则语句块耍一直等到条件表达式变为其时, 再开始 执行. 如下面的语句: wait (enable--l ) begin d=a&b; d=d l c ; end 所实现的功能是2 等待使能信号 enable 变为高电平后进行 a、 b、 c 的与或逻辑操作­ wait 语'旬的作用是对 begin-end 顺序块的启动执行时间进行控制: 只 有 当 enable 信号为 l 时才开始顺序块的执行 。 如 果在仿真进程中遇到 wait 语句时 enable 为 1 , 则立即开始执行 顺序语句块中的赋值语句: 如果在仿真进程中遇到 wait 语句时 enable 不为 1 , 则要等到 enabl e 变为 1 后才开始顺序块的执行。 电斗Z敏感事件控制的第二种形式中包含 了一条行 为语句, 它可 以是 3. 1.2 节中给出 的 任何一种行为语句。 在这种事件控制语句形式下, 行为语句J8qJ执行 的触发条件与前面第 一种形式下的触发条件相同。 两者 唯一不同之处在于这里启 动的是一条行为语句的执行, 而在第一种形式下启动的是一个语句块的执行. 比如: wait (enable=ll d=(a&b) I c ; 同样实现了 " 等待使能信号 enable 变为高电平后进行 a、 b、 c 的 与或逻辑操作" 的功 能。 在此 wait 语句触发的是单条赋值语仨句tJ "d=司{础b均)1阳c;" 电平敏感事件控制的第三种形式中没有包含 行为语旬鸟或2趴i语吾句块。 在这种电平敏感事件 /106 1.. 第 3 1民 控制语句形式下,当 仿真�ilI程: 执行到 wait 控制语句时条件表达式的值为 具 , 则立即结束该 wait 事件控制语旬的执行 , 仿真进程继续向 下进行: 而如果仿真进程执行到wait控制语句 时条件表达式的值不 为 真 , 则仿真进程 进入等待状态, 直到条件表达式取值变为真时才退 出等待状态并结束诙 wait 语旬的执行 , 仿真进程 继续向 下进行。 这种形式的电平敏感 事件 控制常常用来对颐序块中各条语句的执行时序进行控制. 比如如下语句: begin wait (enab1e--1) ; d-a&b; d-d l c ; end 也能实现 " 等待使能信号 enable 变为 高电平后进行 a、 b、 c 的与或理辑操作" 的功能. 仿真进程 遇到 begin-end 顺序块后执行其巾第一条语句就是不带 有行为语句的 wait 语句. 这条 wait语句的执行将使仿真进程 在 enable 信 号 变 为 i 后才能继续往下执行, 从而对 wait 语句后面两条赋值语句的执行时序进行控制. 请读者注意, 这种形式的 wait 语句只有在顺 序块中才能实现时序控制功能. E倒 3-2 4) 也可F敏感事件控制和J)ll沿触发耶件控制的比较 。 rn。duie level-and-edge-COInpaze(flaql, fla92 ) ; output f1ag1 , f1ag2; reg enab1e, f1agl, f1ag2; init:ia1 //第一个 1nit ia1 过程块 , 用于产生 enable 仿 号 begin flagl"l; flag2-1; enabl e - 1 ; jf20 enab1e-0; #10 enab1e- 1 ; 810 Sfin1sh; end init1a1 / /页It 个 1n 1t1a 1 过程块 , 用 F实现也平敏:I B'JH'I'控制 beg1n HO; wa1t (enable--1) f1ag1-‘flag1; //.rt触发条件liXv., flagl 翻转 end initial / / 那-二个 initial 过llî1块 , 用 J:'实现UJ.仰危h友 'JHtþ控制 begin UO; @ (posedge enable) f1ag2--f1ag2; / / )i触发条件成_��, flag2 翩机 end endmodule � 107\ 应用噩摩设i十实倒篇讲 国 3-7 是对上述模块进行仿真的输出结果圈。 因 3-7 电平敏感事件控制和边沿触发明1't抑制的L�校 伊J 3-24 巾的棋块包含 了 三个井行执行的 inilial 过程块. 第一个 inijial 过程块剧 来产生 使能信号. enable 的旅形, 并给信号 flagl 和 tlag2 赋初值 1 : 第工个 initial 过相块用来在 t=10 时刻引入 也平敏础事件控制, 只要触发条件 (enabl e二1 ) 成吐, 就将 tlagl 取值翻转; 第 三个 initial 过程块用 来在 t=10 时刻引 入地沿触发事件控制 , 当 其触及条件 ( enable 发生 正 跳变〉 成v.. . 就使 flag2 取值翻转 . 通过对输出 f1agl 和 tlag2 的变化进行观察, 我们可以 对 两 种 !JJ11t-控制方式 下 的 不 同触发方式进行比较. 由国 3-7 可见: flag1 信号的变化发生 在 严1 0 时刻, 这是国为当 伍 t=10 时刻开始引入 电平敏感 事件控制时, enable 信号的值已经是 l 了 , 即 在 t=10 时刻触发条件满足, 所以对 flagl 进行取反操作. flag2 信 号 的变化发牛J正 t=30 时刻, 这是i划为地沿触发非件控制只对 enabl e 信号指定的正跳变ül.沿敏感. rm只有在严30 时真1I enable í.:I号A灰 ' 尘正跳变, 指定的 边沿触发条件得到满足, 对 f1ag2 取反操作被 触发执行. 3.4 赋值语旬 行为描述悦快中过机块 内 的 语句块是山过础性赋illilHd 和尚级机Jl':雨句这两种基本 成分构成的。 {E本节我们将讨论过程性赋假话句和连续赋{fI ifcf�IJ。 过程性赋1Jl i再句是使JTJ f两种结构化过机块 ( initial i立即块平11 always 过程块〉 巾的赋 fli在{aJ. 在过挝块rl 1只 能使JfJ过程性赋值吾i 句, 问IH过科i'I:赋伯ì1t1JJ山Hf1�使用在过程块 小 . 过和!块内 不能山现连结赋值语句。 根据对被 赋缸变母产生作用的优先级差别, 可以粉过剧性赋侦讯句分为如下两种类咆. • �且l 过础性赋侦讯句 ( 以下简称过和赋值P,HaJ )o · 过科!.连续赋值语句. 其.fi' ?于迦过科性赋倪吾i 句 又可 以 根据赋值操作时的不同IHJ卡特点分成阻在型过程赋 值milJ和I�阻提气吃过程赋值语句. / 108/ .3. 3.4.1 过程赋值语句 过程赋值谓句的语法格式为: 〈被赋值变量> <赋值!操作符> <赋值表达式>: 其 中 , <赋值操作符〉可 以 是 lt=n 或 11 <=" 之一, 它们分别代表了阻事型和非阻塞型 赋值类型。 还可以在上述语法格式中增加时间控制部分. 过程赋值语句只能用于对变量型 数据进行赋值操作. 在经过赋值操作后 , 被 赋值变量的取值将保持不变, 直到另一条贼值 语句对该变量重新贼值为止. 过程赋值操作的具体目标可以是: • reg、 integer、 real 、 time 型变量 〈 标盘或矢盘). · 上述变盘矢盘的某一位或某儿位。 · 存储器数据类型 , 只能对某个地址单元的联个字进行操作 , 不能对该字的某一位 或某几位进行赋值操作. · 上述几个变盘用连接操作符 " {,} " 拼接起 来构成的整体­ E例 3-2 51 过程赋值语句赋值 目 标的 各种形式. module evaluation test; reg a; reg ( 0 : 7 ] b; integer i ; reg ( 0 : 7 ] mem ( 0 : 256] ; initial begin a..O; i=365; • b ( 2 1 -1 ' b l ; b(O: 3j-4'bl010; mem [ 2 0 0 ] - 8 ' hfd; (a, b }-9' blOllllOl1 ; end endmodule 1 1 对一个标饿硝.寄((.锵曼kÄti赋{({ 1/对一个莓'问交1il:赋fI'i 1/:对寄:(f-楼矢载的某一位赋1'1l. /1对寄存苦苦矢蓝的liíIPq{也赋响'i 1 1对存储锦的某一个字I�{f[ 11对 用法攘运rr.符l.1i撞构成的导班w眼倪 过程贼值i再句中 的赋值表达式可以是任何合 法的表达式. 各种过程赋缸语句都可以带 有时间控制, 过程赋值语句l' I可以出 现延 时控制形式的时 间控制和事件控制形式的时间控制。 根据时间控制部分在过程赋值语句中出现的位置, 可 以将过程赋值语句中.的时间控制方式分为如下 两类: · 外 部时间控制方式: • 内 部时间控制方式. 队 1 09\ • 1 . 外部时间控制方式 如 果 时间控制部分出现在整个赋值语旬的最左端, 即出 现在赋值H标变量的左边, 贝。 这种时间控制方式就是外 部时间控制方式. 在外 部时间控制方式下, 过程赋值语旬在仿真时是这样执行 的 : 仿真进程遇到这条带 有时间控制的过科赋值语句后 , 首先延 迟等待由 时间控制部分指定的延 时时间量, 或者是 要等待到指定的触发事件发生之 后 , 才开始计算右端的赋值表达式, 并将其取值赋给左端 被赋值变量. 例如语句t 8 1 0 a=b; 在仿真时就相当 于执行如下几条语句: initial begin no; a-b; end 1/ 先延时 1/ 再求 b 值并将其似赋给 a 由此可见, 在外 部时间控制方式下, 时间控制所控制的是过程赋值语旬开始执行时刻 到赋值表达式被计算以及赋缸操作执行时刻之 间 的时间22. 赋值表达式的计算以及对左端 变 量的赋值操作是发生 在时间控制部分所指定的时刻之后的。 E例 3-2 6) 外 部时间挫制方式. m。dule tirnir19-c。rEtzol-。utJnode (b,c,d, elk, enable} input clk , enab1e; 。utput b , c , d; reg b , c , di ioitial //此过程块用于对输出进行4日j始化 fork b=O; c=O; 扣 ·- d=O; n -m i 4t a 'A I IJIt过程块刷子对输出进行赋侦 . 其中包含了外部时间 1 / 校制方式 fork '5 b=-b; @(posedge clk) c=-c; wait(e nable) d凰-d; //语句 s1 /1语句 s2 1/而句 s3 join endmodule / 110丘 对上述模块的采用 如 阁 38- 所示的仿真激励输入披形. 第 3 事 行为"郎、 阁 3-8 例 3-26惧'1袅的w页.激励输入波形 用如图 38- 所示的仿真-激励输入 被j在对例 3-26 中 的 模块进 行仿真, .,u;仿真输山披形如 阁 3-9 所示. 图 3-9 例 3-26 �负1比CJCJi!JJl:输出波形 在 例 3 -26 樵块巾的 第二个 initial 过和块rl' H\现了三条过程赋缸语句 , 这-三条过秤,赋值 语句都带 有外部时间控制形式的时间控�Mo .LC'i1f再1.) s1 的时间控制来JU 了延 H才植制方式, 语句s2 的时间控制来阳了.ilLi沿触发事件控制方式, 语句 s3 采用 f 电乎敏[�l�件控制方式。 在 仿真进 程进 入到第二个 initial 过程块后 , 仿真进 程将同时进 入飞条赋值i在句 sl 、 d、 s3. 这三条赋值语i.)同时开始得到执行 〈户。 时 刻 ) . 而 赋值操作真正得到执行的时刻是由 各条逼句巾的时间控制部分决定的. 对于语句 s1 . 仿真进 程在 时 时刻讨如 "-b" 的取值, 并将其结果赋给 b. 对于语句 s2. 仿真进 程要在 cl k 求生if.跳变时 (t=10 时刻〉 才计算 "_c " 的值丹将其赋给 c。 对于 语句 s3, 仿真进 和耍了E enabl e 为高电子时 (r=25 时刻〉 才 计 算 "-d" 的优月二将其贼给 d. 在 外部时间控制方式下述有一种特妹tt'1说. un飞外部时间控制指店的延 jg时间为 o ß.t 的情况,我们称其为 " 显式零延 时控制", 例如l下rki的语句: '0 a田b: 该语句的执行过程 与不具有时间控制的献值语句 " a b:" 的执行过料很相似: 在语句 开始执行后, 它们部是 拧先计算表达式 b 的值, 再对变 ET a 进 行赋也: 同时间条白句的开 始执行时刻、 衣i占式计算时�lj矛n变虽;赋值时刻部是栩|司的. 但是上面这条语句J在执行时序上址是勾悟句 1( a=b; " 的执行u'tJ于有471敬妙的足别: 在 显式零延 时控制下, 赋值语句队j赋值表达式的计算以及变景的赋值操作是在 叮 lFJ 仿真时刻 的末尾进 行的. Up蛋等到这一时刻其他正常操作元成后才 进 行 的 . 巾赋伯ifHIj j{a=b; " 内 的表达式计算和变盘赋值操作则是在 赋值语句j开始执行后立即进 行 的 , )1.不可要等伴同一 \ 111 \ 时刻其他操作完成后才进 行 。 比如下面的语句: initial begin a-O; / /语句51 b=O; / /语句 52 end initial begin �O a=l; / / 语 句 s 3 .0 b=l ; //语句 " end 其 中 的四个赋值语句对应的赋值操作都要在仿真时刻 0 得到执行。 但是由于语句 53、 " 的左端加上了显式零延时控制 "制", 因 此 83 、 " 这两条赋值语句对应的赋值操作是在 普通赋值语句 8 1 、 82 对应的赋值操作执行完毕后才开始执行. 所 以 上 面这段语句的执行过 程,是: 先给 a、 b 赋值 0, 然后在仿真时刻 0 的末尾执行对 a、 b 赋值 1 的操作, 则 a、 b 的 最终取值都为1 . . 由此可见, 显式零延时控制提供了一种对语句执行!即芋进行控制的有效方怯。 2. 内部时间控制方式 除了外 部时间控制方式外, 过程赋值语句中的时间控制部分还可以出现在赋值操作符 和赋值表达式之间. 这种时间控制方式就称为 内 部时间控制方式。 在内 部时间控制方式下, 过程 赋值语句中的时间控制是这样执行的 : 仿 真进程遇到带 有 内 部时间控制方式的过程赋值语句后, 立即计算服值语句中赋值表达式的值, 然后进入 时间控制部分指定的等待状态 , 直到指定的延时时问量过去之后或者是指定的触发事件发 生 后, 再将赋值表达式的取值赋给左端的被 赋值变量。 比如, 语句: a=UO b; 中的时间控制部分 " 制 。 " 就出 现在赋值操作符 11_ " 和赋值表达式 "b" 之间, 因此 该语句带 有 内部时间控制方式的时间控制。 它在执行时 相 当 于如下几条语句的执行: initial begin temp-b; #10; a=temp; end 由此可见, 在内 部时间控制方式下, 时间控制所控制的是赋值表达式被 计算时刻到赋 值操作被 执行时刻之间的时间差, 赋值表达式被 计算时刻和赋值变:屋被 赋值的时刻是不同 1 1121A 第3. 的 , 它们之间的时间若是由时间控制部分决定的. 【例 3-2 7) 内 部时间控制方式. •• module Eimir19 control-innez-rrt。de (b,c,elk} J inpuc clk; 。ucput b , c ; reg b , c; initial 1/此过程块用于对输出进行初始化 fork b-l; c-l; tr.5 0 ; / / i蒋句 51 11 语句 s:1 11语句 53 C嚣.5 0; Il脊 i 句 " join initial 1 1I比过程I使用于对输出进行赋值, 其中包含r内部时间控制 fork b-1l5 b; Il[tt+>) s5 c-@ (posedge clk) c; 11ì1t1与1) s6 join e.ndmodule 例 3-27 模块第气个 initial 过程块内出 现的两条过程赋值语句 s5、 56 翻1倍有内部方式 的时间控制. 对上述模块采用 如图 3-]0所示 的仿真激励输入 被形. 回 3-10 �j 3-27 帧块的i!jtt激励输入法形 用如 剧 3-1 0 所示 的仿真激励输入波j�x-t仿IJ 3-27 r�1的棋:快进 行仿真. J:t仿真输出被形 如回 3-11 所示。 阁 3- 1 1 例 3-27 拟块的仿真输出法形 当仿真il料l \ll!l刽语句 s l 、 s2. 在 t=OR-t主IJ构变 址 b、 c 赋初值 1 .. 当 仙iJt垃j 程遇到语句 s3、 s4. iE 1=5 时在IJ将变世 b、 c 的值赋为 o. 叫仿真进 程遇到语句 s5, .(.E指定的延 迟母过 去后 (1=1 5 时刻 ) , 将 计算得到的赋值表达1飞 飞" 的值赋给 b: 尽管此时变准 b 的取值已 经 为 o ( 由语仨Ij 53 赋值), 但是赋值哀地式 U b " 的计算是在 t=O 时 刻进 行的, 所以经过赋 \ 113\ 必由胸惜比 血腥廖设计实伊j糟剖 值操作后, 变量 b 的值等于它在 1=0 时刻的取值 " 1 ", 而 不是它在赋值操作前的值 "叮0" 同样, 当仿真进 程遇到语句 弱, 当其指定的触发事件发生时 〈 时钟信号 clk 发生 正跳变, 即 1=10 时刻〉 才将己 计算得到的赋值表达式 II C" 的值赋给 C : 尽管此时变量 c 的取值已 经为 o ( 出 语句 " 赋值 ) , 但是赋值表达式 lJC" 的计算是在 1=0 时刻进 行 的 , 所以经过赋 值操作后 . 变盘 c 的值等于它在 1=0 时刻的取值 " 1 ", 而 不是它在赋第操作前的值 "0"0 3.4.2 阻塞型赋值语句 语句 1 . 阻塞型过程赋值语旬 以赋值操作符 11_" 来标识的赋值操作称为 阻塞型过程赋值 C Bl ocklng Asignment)。 在 前面章节中给出 的例子内用到的赋值语句都属于阻塞型过程赋值语句. 阻塞型过精赋值语 句具有如下特点. · 顺序块 Cbegin-end 语句块〉 内的 各条阻塞型赋值语句将以它们在!顺序块中 的排列 先后次序依次得到执行: I(rj井行块 ( fork-join 语句块〉 中 的各条阻塞型赋值语句 则是同时得到执行. · 阻塞型过程赋值语旬的执行过程是 : 肯先计算右踹赋值表达式的取值, 然后立即 将计算结果赋值给 " = " 丘端的被 赋值变量。 阻塞型过程赋值语旬的这两个特点表明: 仿真进 程在遇到阻塞型过程赋值语句时将计 算表站式的值并立即将其结果赋给 '1_ " 左边 的被 赋值变景: 在顺序块中, 下一条语句的 执行将会被 本条阻塞型过程赋值语句所阻塞, 只有在当前这条阻拯型过程赋值语句所对应 的赋值操作执行完毕后下一条语句才开始执行。 • 比 如, 下面的程序: initial begin a"'O; a=1; • / /'活何 51 / / ì恶i'1J s2 .co end 中包含 了 两条阻癖型过程赋值语句 sl 和 s2. 它们都在仿真时刻 0 得到执行, 其对应的赋 值操作也是在 0 时刻进 行 的 。 但由于它们都是阻塞型过程赋值语旬, 所以在执行 51 时 s2 被 " 阻 塞 " 而不能得到l执行: 只有在 s l 执行完毕, a被 赋值 。 之后 , s2 才开始执行 。 而 s2 的执行将使 a被 重新赋值 i 。 所 以 t面的顺序块执行之后变量 a 的最终取值为 1 0 E例3-28] 阻器型过程赋值语句带 有延 时控制时的情况。 rn。dule blockir19.massiqnmenE-test ; reg a ; 1 initial / 114h begin a=O; a=tS 1 ; a:UO 0; a=US 1; end endmodule / / 语 句 51 //语句 52 //语句。 //语句 " 如圈 子12 所示为该模块的仿真输出波形。 第 3 事 行琦副队\ 圈 子 12 -ø-� 3-28 模块的仿真输出波形 例 子28 中 的 各 条语句将依次得到执行, 并且在前一条语句所指定的赋值操作没有完成 之前下一条语句不会开始执行。 因此. s1 在 t=0 时刻开始执行, 对应的赋值操作在 件。 时 真IJ完成, a 被赋值0; s2 在 t=O 时刻开始执行, 对应的赋值操作在(=5 时刻完成, a 被赋值 1 ; s3 在 (=5 时刻开始执行, 对应的赋值操作在 t=1 5 时刻完成, a 被赋值 0; s4 在 户 口 时刻开 始执行, 对应的赋值操作在 t=30 时刻完成, a 被赋值 1 ; 整个 initial 过程块执行结束。 阻塞型过程赋值语旬的完整语法格式如下所示: block�ng_as5ignment : ; 菌 variable_lvalue = [ delay_or_event_control 1 expression delay-or-event-tc。ntr。l : : 阜 delay_control • I event control I repeat ( expre5sion ) event control delay_control : : = jf delay_value I fIC ( πl�ntypmax_expression ) event: cont:r.ol : : = @ event identifier 自 ( event_expression ) e舍 自 (") event_exp;r-essìon … - expreSSl.on hlerarchical ìdentifìer I posedge expres5ion � 115\ I negedge expression I event_expression or event_expression I event_expression I event_expression variable lvalue : : = hierarchical variable identifier | hierazehical--variable-identifiez [ exPEessi。n l { { exPEessi。n ] } | hierarchical-vaziable-identifiez [ expressi。n l l i expressi。n ] } ( range_expression 1 l hiezarchical-variable-identIEiez [ range-expressi。n l I variable concatenation 其 中 , " variableJvalue " 是 合 怯 的被 赋 值 变 量 数 据 类 型 : " 嚣 " 是 赋 值 操 作 符 : iI del ay_or_event_control " 是 可 选 的 内 部 时 间 控 制 , 可 以 是 延 时 控 制 或 事 件 控 制 : "expression " 是赋值表达式: 赋值操作应当 在指定的时间控制破触忍之后进行. "=" 赋值操 作符也可以用 在过程连续赋值语句或连续赋值语句中。 2. 非阻塞型过程赋值语旬 以 赋 值 操 作 符 (1 <= " 来 标 识 的 赋 值 操 作 称 为 非 阻 嚣 型 过 程 赋 值 ( Nonblocking sA signment). 非阻塞型过程献值语句的特点是: · 在 begin-end 顺序语句块中 , 一条非阻塞型过程赋值语旬的执行不会阻塞下一条语 句的执行, 即在本条非阻塞型过程赋值语句对应的赋值操作执行完毕之 前 , 下一 条讲台J也可以开始执行. · 仿其进样.在遇到非阻寒型过程赋值语句后首先计算其 右端赋值表达式的值 , 然后 要 等 到 当 前仿真时间结束时再将该计算结果赋值给被 赋值变址• e.n非阻塞型过程 赋值操作是在间一仿真时刻上的其他曾-迦操作结束之后才 得到执行的. 因此非阻 那型过程赋值语句的这个特点是不同于阻塞型过程赋值西句的执行时序特点的。 例如, 下面的语句: initial begin A<-B; B<-A; end / 1 凶句 s1 /1 滔1-.J s2 上述语句包含 了两条非阻塞型过程赋值语句 5I :和 52, �I 仿·真进程遇到 initial 过程块 后 ( t=O 时真1)). 语句 s l 首先开始执行, 赋值表达式 " S " 的值得到计算 (但是对被 赋值变 盘 A 的赋值操作要等到当前时间步结束时才执行). løJ 时 由 r. s1 是一条非阻塞型过程赋值 语旬, 所 以 sl 的执行不会阻塞其下一条语句 52 的执行: r是 s2 也随即开始执行, 所以此 时为变t,t S 进行的赋值操作也要等到当前时间步结束时才得到执行: 所以在当前时间步结 束时,s l 、 s2 两条语句对应的赋值操作同时执行, 分别将已经计算得到的 A 和 B 的初始 1 11 6 /4 第 3 事 行颁国除\ 值赋给变量 B 和 A, 这样就交换 了 A 与 B 的取值。 E例 3-29] 非阻塞型过程赋值语句带有延时控制时的情讯。 module nonblocking_a55ignment_test; reg a ; initial begin a<=O; 11语句 51 a<=#5 1; 11语句 s2 a<=il0 0 ; //语何 s3 a<-ot15 1 ; 1/语句 " end endmodule 如圈 子13 所示为该模块的仿真输出波形。 阁 3- 1 3 伊� 3-29 模钱的仿真输出波形 在例 子29 中 , 各条语旬的执行时序如下: · 语句 51 在 t=0 时刻最先开始执行, 由于 sl 是非阻塞型过程赋值语旬, 它的执行不 会阻塞下一条语句 s2 的执行, 所以语句 s2 也随即开始执行 〈 在 户。 时刻 ) : 同时 由 于 到 中没有延时控制部分, 所以语句 s l 对应的赋值操作在 严0 时间步结束时得 到执行, 变量: a 被赋值 00 · 语句 s2 在开始执行后 ( t=0 时刻 ), 由 于官也是一条非阻塞型赋值语句, 它的执行 不会阻攘下一条语句 s3 的执行. 所以语句 s3 也随即开始执行 。=0 时刻〉。 又 由 于 s2 中带有内部延时控制, 所以话句 52 对应的赋值操作将在延时结束 时刻 (t=5 时 刻 〉 所在的时间步末尾得到执行, 变士最 a 被赋值 1 0 · 语句 s3 在开始执行后 ( t=0 时刻 ), 由 于它也是一条非阻塞型赋值语旬, 它的执行 不会阻塞下一条语句 " 的执行, 所以语句 s4 也随即 开始执行 (户0 时刻〉。 又 由 于 s3 中 带 有 内部延时控制, 所以语句 s3 对应的赋值操作将在延时结束时刻 (t=10 时刻〉 所在的时间步末尾得到执行, 变量 a 被赋值0。 • 语句 " 在开始执行后 (t=0 时刻), 由于辛苦有内部延时控制, 所以语句 " 对应的 赋值操作将在延时结束时刻 ( 户 口 时 刻 〉 所祀的时间步末尾街到执行. 变量 a 被 赋值 l 。 下面再举儿例说明非阻塞型过程赋值语旬的用法。 队117\ E例 3-30) 在同一过程块 内 使用 多 条非阻塞型过程赋值语句对同一变量赋值的情况. module multiple1; reg a; initial a - 0; initial begin a <- 110 0; // 在 t- l 0 时 刻 , 给�fJi: a 赋í!i o a <- UO 1; // ,(E t-10 时刻,给变革t a 赋值 1 end // 在 庐山 时刻 , 变-fil: a (JJ< Jïi终驭值J. n endmodule 如国 3-14 所示为上述模块的仿真输出被形. 因3-14 例 3-30 领块的仿真输出法形 由上例可见, 如果在同一过程块 内 使 用 多 条非阻塞型过程赋值语句对l司一变世赋值 (时间延迟相同 ), 则 被赋值变盐的最终取伯足确定的 , 且 由过舰块内的t战后一条非阻�唱 过程赋值语句决定。 E例 3-31 ) 在多 个过辑块内使用非阻塞唱过程赋值语句对|司一变量服值的的况. module mu1tiple2 ; reg a; initial a = 1; initial IB a <- .B 1 ; //语旬到. �E t-B Il.t多IJ执行亥i il.t1il. lE t=16 时刻给变!i'ta 赋 值 1 initia1 112 a <- #4 O; //i如OJ s2. 征 性12 时�iJfÀ行i复m句, (E t=16 日J友1)给变!ila 赋值。 endmodule 如图 3-15 所示为上述榄块的仿真输出被形. 阁 3-15 例 3-31 秘块的仿真输巾被形 在 t路模块内 , 语句 sl 和 s2 在 户16 时刻部对变量 a 进UM值操作 , 但是山 f'm1�J s2 1 118� .3. 的执行时间晚于语句 sI , 所以变量 a 的最终取值由语句 52 决定。 非阻塞型过程赋值语旬的完整语法格式如下所示: nonblockin9_assignment .• •. ­ variable_lvalue <- [ delay_or_event_control 1 expression delay_or_event_control .. .. ­ delay_control I event control I repeat ( expressioo ) event_control delay_control : : - nv i delay_value ta伽le」 wa,.t- ,· aE& SES e v e n I - •eeec wv。(ne{ Enmetziv- o neL-、t&ndyEe..p一 n --ma-xxl_eeexpr-L e。 sn si} on ) e (舍} event_expression . .­ •• express�on hierarchical identifier posedge expression negedge expression event_expression or event_expression I event_expression , event_expression va.riable lvalue : : .. hierarchica� variable identifier I hierarchical_variable_identifier [ expression 1 ( r expression 1 1 I hierarchical_variable_identifier [ expression 1 ( [ expression 1 ) [ range_expression 1 l hleEaEchical-variable-identifier [ zange expresslon ] variable concatenation 其 中 . " variableJvalue " 是 合 法 的 被 赋 值 变 盘 数 据 类 型 ; 11 <= " 是 赋 值 操 作 符 : Itdelay_or_event_control"是可选 的 内 部时间控制,可以是延时控制城事件控制:tIexpression" 是赋值表达式: 赋值操作应当在指定的时间控制被触发后进行: 如果没有指定时间控制, 则赋值操作的时序不确定. "〈=" 赋值操作符与关系操作符中的 " 小 f等于" 相间, 编译 器将会根据该操作符出现的环境, 决定它是赋值操作符还是关系操作符. 如果该符号出现 在表达式中 则为关系操作符, 如 果 出 现在非阻塞型过程赋值语句中 则为赋值操作符. 3.4.3 连续赋值语甸和过程连续赋值语句 1. 连续赋值语旬 ( Continuous Assignments ) Verilog HDL 语言中的连续赋值语句与过程块一样也是一种行为描述语句 〈 在某些文 队 119\ 精到L 应用雹靡设i情锢糯讲 献中将连续赋值酒句归类于一种新的 " 数据流描述方式", 在本 归中将其视为一种行为描 述语句). 连续赋值语句主要用来对组合逻辑电路的行为进行描述, 而不需要指定组合逻 辑电路元件之间具体的硬件连接关系. 在i 接赋值语合J只能用来对线网型数据类型 ( 标庭或矢盘〉 近行耀动 (赋值), 而不能 对变量型数据类型进行赋值, 它有以下两种格式. • 显武连续赋值语句 t是 闷型撇撇炎型 〈 赋缸i驱动强度) [线间型数据{业'Äl:J 线网型敛倔名t assign 骨 〈 延1I.11il: ) 线 间型数据名 =l!iItftt .:<<在 1 式: • �Id式在i 纷赋值诏·句 • 线|州型数据典型 ( 赋值驱动强度 ) [线闷型数据优宽]# ( 延lI.t J,t ) 线网型数据名 = 赋 值表达式: 在显式连续赋值百句巾 包含了两条语句: 第一条语句是对线阀割数据进行类型声明的 语句 : 第二条阳台J足对这个已经得到声明的线闷型数掘进行连续赋值的赋值语句. 在隐式 连续赋值语句rjl将线闷型数据的声明 语乞iJ .& 对牵i 线 闷型数据进行连续赋值的赋值语句组 合�JI司一条谓句 中 . 利用 隐式连续赋值语句可以对线间咽.数据进行类咆卢明的同时实现连 结赋值. 对 1:述活法格式做如下说明. · 关键词 "assWI" 是连续赋值语句的标志 . • "( 赋值驱动强度 )" 为可选顶, 它片能任隐武连续赋值语句棉式巾 得�J扣定. 它 用来对线网型数据受到的驱动强度进行指�. 该�项由 " 对 1 驱动强度" 和 " 对 0 驱 动 强 皮 " l.liIi 项 组 成 。 比 如 语 句 " wire(weakI ,strongO) 伊b&c; " 内 的 " ( weak I ,strongO)" 就表示该语句指定的连续赋值对线闷响数据 a 的驱动强度是: 赋 l 值时的驱动强 IJ[为 "weak ( 弱 )", 而赋 。 但时的班动强度为 "strong ( 烛 〉 飞 如果在隐式连续赋 ili语仇1) Ij1默认 了驱#J强l主这一项, 则驱动 强度默认为 ( slrong1,strongO)0 • "# ( 延时 由 ) " 也为可选项。 它指定了IÍl赋值表达式内信 可发生变化时刻到线网型 数据取值被.l1!1fr时真IJ之间的延迟时间最. 它类似于根本元件卢11月时指定的延时最. "延时监" 的基本棉式如下: I (delay l , delay2, delay 3 ) .lt巾, delay I 、 delay2 和 delay3 都是一个数值o d巳lay l 指 定 f 纷闷型数据转移到 " I ,. 状态时的延时值 〈 称 为 k升延时 ); delay2 指 定 了 线网梢数据转移到IJ "0" 状态时的延时值 〈 称 为 下降延时); delay3 指定了线网型数据转移到 "z ( 向阻 ) " 状态时的延时值 〈 称为 关 断 延 时 ). (E实际使用111 " 延时 监 " 可以省略为山一个琪两个延时值构成, 这种忻况下三 种 延 n.t值 (" 上丹延时值"、 "下降延时值"、 " 关断延时值") 的确定准则为: / 120/'J 第 3 掌 行为丽丽来入 》 若只给出一个延时值, 贝IJ这个延时值将同时代表 " I工升延时值"、 " 下降延时 值"、 "关断延时值". 〉 若只给 出 了 两个延时值, 贝IJ这两个延时值将分圳代表 " 上升延时缸"、 " 下 降 延时值", 而 " 关断延时值" 将 由 给 出 的 两个延时值中较小的那一个指定. 》 若 " 延时值" 这一项默认 , 则默认所有的延时值部为 o. • " 赋值表达式 " 内可以包含线网型、 变盘型马克函数调刚等任何数据类型的操作数, 同时也可以包含任何操作符. 下面举例说明连续赋值语旬的使用。 E例 3-32 ] 显式连续赋值语句. module continuous_assignrnent_testl ( z . x . y ) ; l.nput X. y; output z; wire z . x . y ; assign ' ( 3 . 2 . 4 ) z=x&y; endmodule 如回 3-16 所示为对该模块进行仿真的输入输出波形. 国 3-16 例 3-32 蚁块的仿真输入输出该形 在伊IJ 3-32 巾 , 连续赋值iE句指定用及.ib式 "x&y" 的取值对统网型数据 z 进行连续驱 动 , 其中指定的延时最为 "(3,2,4)". 它指明了从信号 x 必 y 发生变化到 z 槛更新时刻之间 的延迟时间最: 上升延时为 3 个时间单位 , 下降延时为 2 个时间单位, 关断延时为 4 个时 间 单位. 从国 3-16 巾可见, 输入信 号 Y J权-0'1{I:仿真过程中似持不变〈 为 1 ). 贝IJ农地式"x&y" 的l{X伯克仓 出输入信 号 x 决应. 在仿真n-j生IJ t=L O 时 刻1 X 取值 山 O 变为 l 。 则 点地J'\(1 x&y" 的取值也出 0 变为 1 . 但是该表达式的值并不会\If!P赋给输 出信 号 Z. 而是要经过 " .1:升 延时" 后, 再将此表达式的值赋给 2. 即{F. t=13 时刻, 将占i在式的值 (t=10 rH刻的取值〉 赋给输 山 信 号 2. 同 样 , 在1}(f{.时刻 t= 15 时刻. X 取值 山 l 变为 O. 则表达式 ., x&y " 的取 值也山 l 变为 0。 但足受 " 下降延时 " 控制 , 在 t= 17 时刻 , 才a斗将夺4友变达式 "气x&y" 的I取仅值{ 自 O 〈产户=1归5 时刻的取值) �版民给 2 0 该连续赋值i语岳合句J中并未出4视l山见M且I "�驱怪2动丑讪�1.强虽皮" 这一1刷9贝扎iL, 所以线 协怀闷�Jl F乔刑r罚l数据 z 收到的驱动强度为默认 的 "气 ( stron咆g l.stro∞ng剖0) " I 例 3-33 汀】 隐式连续赋值语句. module c。ntinu。us-assiqnrnenE-Eest2 { z , x , y } J input x , y; 。utput z ; \ 121 \ . W.lre x , y; wire ' (3 , 2 , 4 ) endmodule z-x&y; 伊� 3-33 模块使用了一条隐式连续赋值语句, 它描述 了 与例 3-32 相同的硬件行为. 在实际使用时, 连续赋值语旬的赋值目标可以是如下几种. · 标量线网型数据类型. 如: wire a,b; assign a-b; · 矢量线网型数据类型. 如: wire [ 7 : 0 ) a , b ; assigo a�b; · 矢量线网型数据的某一位. 如 : wire [ 7 : 0 ) a , b ; assign a ( 4 ) =b [ 4 ] ; · 矢量线网型数据的某几位。 如 = wire [ 7 : 0 ] a, b ; assign a ( 4 : 1]-b[4 : 1 ] ; · 上面几种类型的任意拼接结 果。 如 : wire a , c ; wire [ 2 : 1 ] b; assign { a , c )-b; 在需要对多个线网型数据进行连续赋值时 , 还可以采用如下形式的连续赋值语句, 它 可以实现对多个钱网 型撤掘进行连续赋值。 3·' a s s -l 内' n o u t - 配 - AU c 旧t ­。 r ­ 吨 " ., 圳b out xor-a^b; 。ut not a--a; 。ut not. b回-b; 上述语句是下面 5 条独立的连续赋值语旬的简化形式。 ass· 1 hu ass· 1 ·' ass· 1 hu ass· ll -­ ass- qn gn gn d 9n 9n 。。。。。uuuuu铲伽伽←P·凰aLL."h- - - ­a。xnnnz。。。d-ztt-a'- ­alaab晶bA· ·J J ab,.,. / 1 22/A 正如 " 连续赋值" 这一名称所表述的含义, 连续赋值语句对统阀割数据进行的是连续 的驱动. 与寄存器变量不同 , 线网型数据 〈 除 了 的reg 类 型 以 外 〉 没有放据保持能力, 只有在 被连续驱动后才能取得确定值 〈 寄存器型变量只要在某一时刻得到一吹过程赋值后就能一 点保持其取值), 若一个钱间 型 数据没有得到任何连续驱动, 则它的取值将为不定态 t. x"。 连续赋值就是实现对线网型数据进行连续驱动的一种方法 〈还有一种进行连续驱动的方法 是由 某个模块输出端来对线网型数据进行驱动, 这归类 子结构描述方式). 一个统网型数据一旦被连续赋值语句赋值后, 赋值语句右端赋值表达式的值将始终对 被赋值线网型数据产生驱动 〈 连续驱动 ). 在仿真执行时, 只要布9;lt赋值表达式的任一操 作数发生变化, 就会立即触发对线网型激据的更新操作: 重新计算赋值表达式的取值, 然 后将计算结果赋值给被赋值钱网型数据. 即赋值表达式 内 各个信号的变化将随时被反映到 赋值表达式和被赋值钱网型数据的取值上. 如果在一个棋块 内 包含 了 多 条连接赋伯语旬, 或者在一个模块小 问时包含 了在i 接赋值 语句、 过程块、 模块实例或基本元件实例 , 则各条连续赋值语句和其他的过程块 、 技块实 例和l基本元件实�J之间是以并行方式执行 的 : 它们都同时从零仿真时刻开始执行. 下面给出用连续赋值语句实现 4 位全加器的一个例h E例 3-34】 用连续赋伯语句实现 4 位全加器。 m o Z气 JC-l m d U le -nP auEdA e[ U - O 4 ]{a 'b' a'b ,s , co} J -LnPuE C -l OuEp u← I A J - s u m qd J · output co」 ; assiqn (co, sum)-a+b+ci; endmodule 上例连结赋值语句内的被赋值日标是一个 5 位宽的组合线网型放据 " {co,sum} ", 它是 由两个线间组数据 CO 和 sum 拂接而成的. 这个组合线网型数据的敲l吨位就 是 c o 的 i也缸, 低 4 位是 sum 的取值: 连续赋值语句中的赋值表达式是 Ua+b+ci", 它是对输入信 号 a, b 和进位输入Ci 进行求和的一个求和表达式. 因此这个求和l表达式将对组合线网数据进行连 续驱动: 组合线网数据的低 4 位 〈线同数据 sum) 将等 1'-加法运算的本位和输出 , 而组合 线网数据的战高位 (co) 将等于加怯运算的进位输出. 如 图 3-17 所示为对该模块进行仿真的输入输出被形. 闯 3-17 例 3-34 模块的仿真输入输出汲形 • \ 123\ 最后总结一下连续赋值语句和过程赋值语 旬 之 间 的 区 别 . · 从语法上来看, 连续贼值语句由 " 但sign" 关键词来标识 , 而过程赋值语句中则不 包含这个关键词. · 连续赋值语句中左侧的被赋值数据类型必须是线网型数据, 而过程赋值语句中的 被赋值数据类电则必须是寄存器:类型的变最. · 连续赋值语句不能出现在过程块 ( initial 过程块或 always 过现块〉 中 , 而过程赋 值语句则只能出现在过程块内 . · 连续赋值语句主要用来对组合逻辑电路进行建棋以及对钱网 型撒据间的连接进行 描述, 而过程赋值语句主要用来对时序逻辑电路进行行为捎迹。 · 连续贼值谓句对被赋值线网型数据的赋但是 " 连续" 的 〈 即连续赋值语句产生作 用后. 赋值夜达式中 信 号的任何变化都将立即反映剑被赋值钱网型数据的取值上, 这也是我们街时会使用 "连续驱动"这个术语的原因), 而在过程赋值语句情况下, 只有在过程赋值语句被执行时才执行赋值操作, 语句执行完后被赋值变量的取值 不再受到赋值衣达式的影响。 下面是连续赋值语句的完整洁法格式. net declaration : : 8 net-Eype [ siqned 1 { delay l list-。f-netEider1tiEieZS J I net_type [ drive_strength ] ( signed ) [ delay] list_of_net_decl_ assignment.s I net_type ( vect.ored I scalared J [ signed ] range ( delay] list_of_net_ ident.ifiers ; I net_type [ drive_s trength 1 [ vectored I scalared ] ( signed ] range { delay] list-。f-net-deel-assignments J I trireg ( charge_strength ] ( signed ) [ delay) list_of_net_identifiers ; I trireg [ drive strE王nqth l [ slqned ] [ delay] list-OE-net-deel­ assignments trireg [ charge_strength J [ vectored I scalared ) [ signed ) range [ delay] list of net ident.ifiers ; trireg [ drive_s trength J [ vectored I scalared ) ( signed J range ( delay] list_of_net_decl_assignments ; list-。f-net-deel-assiqrlrRents : : = net_decl_assigr回\ent { I net_decl_assiqnment 1 net_decl_assignment : : = net ident.ifier = expression: contlnuous_assiqn : : = assign [ drive_st.rength ] ( delay] lis t-,。E-net-assi9fIIRents J list of-net-assignments : : = net_assignment ( I net._assignment I net_assignment : : - net lvalue = expressìon: / 1 24/. '自 3 . 2. 过程连续赋值语旬 ( Procedural Contìnuous Assignments) t亏过程赋值语句一样, 过程连续赋值沼句也是一种过程性赋但语旬, 它用来实现过程 连续赋值。 正如它的名称所点示的那样, 过程连续赋值是在过税块 内对变盘成线阀割数据 进行连续赋值的, 而过程连续赋值语句就是用来实现过程连续赋值的过程性赋值谓旬. 过程连续赋值语句 句连续赋值语句的不同之处在于: · 过程连续赋值南句只能用在过程块 ( ioitial 过程块!& always 过程块〉 内 , 而连续 赋值语句不能出现在过程块 内 . • 过程连续赋值语句可以对寄有·器类明变 盘进f币在纸:赋û'[ ( force-release ì在句组连可 以对线网 型激据ilt行连续赋缸), 立的赋值H标不能是变吐或线网型数据的某一位 或某几位, 而连续赋值语句只能对线闷型数据进行赋值, 它的赋值 目 标 IfJ 以是线 闷型数据的某一位或某儿位. 过程连续赋值语句执行的是一种 "连接赋值": - R对某个变量或线网tt�敬据进行了 过再连续赋缸 , 则它将一 月受到过程连线赋值语句内 " 赋值衣达式 " 的连续驱动, " 赋值 表达式" 内任何操作数的变化部会引起被赋值变最戒线网型激占国'取值的更新, 直到对其执 行 了 " 撤销过程连续赋值 " 操作为止. 在 Verilog HDL 叶 ' 有 两 组 过 程 连 接 赋 值 语 句 可 以 实 现 过 程 连 续 赋 值 , 它 们 是 ..assign-deassign" 语'ÍJJtfl和 .. force-release " 吾i 句组。 ( 1 ) assign 和 deassign "assign 语句" 和 11 deassign 语句 " 构成 f 一组过程连续赋值讯句 。 它们只能用 于对寄 存揣炎咆变茧的连续赋的操作, 而不能用 米对线网 型数据进行连续赋值操作. 县:巾 "assign 语句 " 用 米实现对奇在器央电变量的连续赋值. 而 "deassign 语句 " 则是一条撤销连续赋 值的语句, 它用来解除由 、sign 语句" 对市布苦苦类型变结进行的连续赋值状态. ① "assign 语句" 的使用语法为: assign <寄存格炎型交IJ:> = <赋J'f(U ' J.!式>1 .u; 巾 , <寄存器类型变Et〉指明 了辜j 纸:赋值操作的 目 标变吭, 而〈赋值表沾式〉贝1)指明 了 连续赋值的驱动源. 一且 但Sign 语句j得到执行 , 寄存器类型变[E将由赋值夜在i 式进行连续驱动, 它将进入 被连续赋值的状态. 如果此时有普通的过和赋值语句对该寄仔精变琶进行过程赋倪操作, 由 于址:相连续赋值语1d assign 的优先级 ,:G 于件通过程赋缸识-fd, 所 以 处 于连接赋伯状态下 的寄得端变盐将忽略'fJ迦过程赋值语句对立的过程赋值操作, 立的边辑状态仍然由过程连 续赋值tff句内 的股值表达式所决定。 如 果先 后 有 两 条 assign 语句对|可一帘蒋器变量进行 f 过程连续赋值, 那 么 第 二 条 assign i丹句的执行将现 凶第一 条 部sign j1f1l]的执行放果, Up守i 抨拇变:!il最终将进入 山 第 二 条 assign l汗1.1)实现的在i 给赋@状态。 比 如 , 下面的语句: \ 125\ reg out ( 3 : 0 J ; initial begin out=O; #10; a5sign out=a&b; '10; assign out=a l b ; end / / 5 1 , 过程赋俗语句 Ils2, 第一条过程连续赋值语句 I ls3 . 第二条过程连续赋俄语句 上述语句的仿真执行过程如下: • 计先, 过程赋缸语句 s l 得到执行, 在 户。 时 刻 out 被赋值 。 并保持这个取值. · 在 t=1 0 时刻. s2 开始执行, 它实现了对变盘 out 的连续赋值. 因此从t=10时刻起, out 将处于被连续赋值状态, 它将受到赋值表达式 "a&b" 的连续驱动, 信号 a 或 b 的任何变化都将触发 out 取值的更新操作。 · 在 t=20 时刻 . s3 得到执行, 它将覆盖 82 产生的作用, 所以从 严20 时刻起. out 将由赋值表达式 "alb" 连续驱动. ② " d四ssign 语句" 的使用语法为: deassign <帘得器炎"t!变蓝>: Itde部SigI 语句 " 是一 条撤销连续赋值语句J o 当它得到执行 后 , 原先 由 苗Sip 语句对该 变盘进行的连续赋值操作将失效, 寄存器变iìt被连续赋值的状态将得到解除, 该变量义可 以 由 普通过程赋值语句进行赋值操 作 了 . 洼.1 当 用 伽邸, 语句槛铺 了对某个寄存葛吏量的连续赋位后, 该寄存喜爱量 仍将保持 阳ai伊 语句执J于前的尿布取恤, 比如, 下面的语句: reg [ 3 : 0 ) out; initial begin 。ut-O; assign out"1; &88i9O out-2; dea8si9O out; end //81, 过程赋值话句 //s2, 第一象过程连续戴值语句 / /83, 第二a悔过程连镇赋值语句 //剖, _触情连续赋也语句 在仿真执行过程 中 , 在语句 " 得到执行之前, 吏量 out 处于由 第二*" asis p语句 ( s3 ) 实现的连续赋值状毒, 其值就连续皿动为 "2"; 当 伽sis F 语句(54 ) 得到 执行后 , 变 量 out的连续赋值状态植解除, 其取值仍保持原位 "2"0 FUü举例说明 assign 和 deassign 语旬的使用. 1 1 261 E 例 3-351 具有异步*1 苓输入的下降沿 D 触发器. module dff_asyn_clear (q,d,clr,clk) ; 。utput q; input d,clr,clk; reg q; always @ (clr) //用1二实现异w消零的 always 过程块 begin B if ( ! ca ls rs )-L 9 nq o ., e 、A s e a d e a S s 1- qd nq ., end always @ (negedge clk) begin q=d; end endmodule //用于实现正常D 触发器功能的 always过程块 上例棋块内的第一个 always 过程块描.ì&了异步'泊�功能的实现, 这个 always 过程块 是由清军控制信号 clr 的跳变触发执行的. • 当输入 ctr 由 非零逻辑值变为军时. 过程连续赋值语句得到执行 , 变量 q 受到 "0" 的连续驱动, 因 此 q 的值被强行置成 1'0". 从这时起一且到撤销连续赋值操作被 执行之前, 由时钟 c1k 的下降沿对 q 的过程赋值操作将被忽略 〈 因 为 assign 过程连 续赋值语句比普通过程赋值语句 " q=df 具有更高的优先级) , 输出信号 q 将- 1[ 保持取值 "0", 这样就实现 了 当 clr 为 "0" 时的请客功能. • 当输入 clr 由军变为非军逻辑值时, deassign 语句得到执行, 它解除了对寄存器变 虱: q 的连续赋值, 因此寄存器变i丘 q 将结束由 UO" 连续驱动的状态 ( 结 束对 q 端 的强行清军控制 ), 此后当再有时钟下降沿出现时, 模块将实现 D 触发端的正常工 作功能. 从例 3-35 可见, 由 于过程连续赋值语句比普通过程赋值语句具有更高的优先组 , 当用 一条 臼sign 语句对寄存黯变盘进行连续赋值后, 其他的普通过程赋{t[ 语句对该变1tl进行的 过程贼值操作将不再起作用 〈 直到通过执行一条 deassign 语句来撤销该寄存器变币的连续 赋值状态为11:). 因此过程连续赋值语句特别适合用于实现优先级高 r正常时1�迦辑功能 的 异步置位或异步消�逻辑功能. ( 2 ) force 和 release " 岛rce 语句 " 和 " release 语 句 " 也构成了一组过科连续赋值再i 句. 这组过视连续赋值 语句不仅能对寄存器类型变最产生作用 , 还能对线网咆数据进行连续赋值操作 . 勺 bree 语 句 "的优先级高 于"也Sign 语句", 我们称它为"强制语句"0 11release 语句 人 1 27\ 应用毒摩设计实伊跚讲 语句", 它用来解除指定寄存器变盘或线网型数据上由 It force 语句" 实现的连续赋值状态, 我们称它为 "释放语句飞 ① It force 语句" 的使用语法如下: force <寄存者曾变是或线网电数据> = <赋值表达式>: 如果 岛rce 语句内指定的被赋值目 标是寄存器类型变;壁, 则在 force 语句得到l执行后, 该寄存器变量将强制 由〈赋值表达式〉进行连续驱动, 进入被连续赋值的状态, 此时将忽略 其他较低优先级的赋值语句 〈 普通过程赋值语句就 assign 语句〉 对该寄存器变量的赋值操 作, 直到执行了一条 release 语句来释放对该寄存器变盘的连续赋值为止. 如 果 force 语句 指定的被赋值目标是线网型数据, 则在 force 语句得到执行后, 对应的线网型数据将得到〈 赋值表达式〉的连续驱动, 此时将忽略该线网型数据 上较低优先级的驱动 〈 如 臼sign 连续 赋值语句就实例输出端对该线网型数据的连续驱动 ) , 直到有一条 release 语句来释放对该 线 网 型数据的连续驱动为止. 下面举例说明 force 语旬的使用。 E例 3-361 被赋值目 标为 寄存器变量的 force 语句。 module force_examplel ; reg [ 2 : 0 1 var_regl, var_reg2; init:ial .lb e q n va r req l罩O as #1 s-i qn oJ vaz- E e 9 两z ,『 ι4 E。 Eo ree zee v v aazz- ­r r e e q qψ 1 2 d = = aa匈 . , . , u3 Ils1, 过程赋值语句 1152 , 过程远纸:眼伯语句 , assign 语("J 1153, 过程连续赋伯语何, force 语句 11时, 过程连续赋但岳 i 句 , force 语句 end • • endmodule 上例的模块实现了对两个寄存器变母 var_regl 和 var_reg2 的过程连续赋值: • 仿真执行进程开始后, s l 首先执行, 它 用 来实现对变盐 var_regl 的过程赋值操作, 变 量 va盯rEr陀穹吨g l 被赋值 "哈0" • 随即 52 也得到执行 , 它是一条 as岱蚓s剑ig伊n 过程连续赋值语句 , 用来 实现对变蠢 var 附reg2 的连续赋值, 从而 var_reg2 将被连续赋值为 " 1 飞 · 在仿真时刻 户1 0, 53 开始执行 , 它是一条 force 过程连续赋值语旬, 用来实现对 变:m: var_regl 的连续赋值, 这样变.i:1 var_regl 将被连续赋值为 "4飞 • 随后 s4 也得到执行 , 官也是一条 岛rce 过程连续赋值语旬, 用来对变最 var_reg2 进行连续赋值. 由 于在 s4执行之前变iil: var_reg2 已经处于由 assign 语句 (52) 所 实现的连续赋值状态, 但因为 force 语句的优先锁商于 assign L吾句的优先级, 所以 执行 s4 时将忽略 52 对变'虽 var_reg2 的作用 , var_reg2 将被连续赋值为 "4". / 128h 如困 3-18 所示为对例 子36 模块进行仿真的输出波形. 第3J民 回 3-18 例 3-36模块的仿真.输出该形 E 例 3-37 ) 被赋值目标为线网型数据的 force 语句. module force_examp1e2 (var_net1, var_nec2 , i nl , in2) ; input inl,in2; oucput var_neCl, var_net2; wire var netl,var net 2, inl, in2; assign var necl-O; //剖, 连线赋íll泊句 , 将 var necl 连续赋值为 O 。r '10 (var nec2, i n 1 , i n2) ; 1 / 5 2 , 基本元件实例语旬 , 指定 "必门" 输出对 //var nec2.l1l:行生 i 纷驱动 initial begin t20; force var netl=inl&in2; //s3, force l:l:科连续赋值语句 force var net2叫-in l ) 晶�n2; / l s 4 , force 过程连续赋值语句 end endmodu1e 上例模块中用 force ï再合J对两个钱同型数据 var netl 和 VMLneG 进行了过程连续赋值操 作. 在 initai l 过程块执行之后, 由于语句 。 和 抖 的优先级分别比语句 s l 和 s2 优先级旦高, 因此最终 Var-netl 将由 11 in1&in2 " 连续驱动. Var-net2 将 由 "(-in l )&in2 " 连续驱动. 如图 3-19所示为对例 3-37 仿真的输入输出被形. 回 3-19 例 3-37模块的仿真输入输出法形 ② 11 release 语句" 的使用自斗法如下: release <寄存然交战且应线间目 1 数据>: 与 deassign 语旬的作用相似, 在执行了 陀lease 语句后, 原先由 force 语句实施的对赋 值 口 标 的过程连续赋值操作将失效, 变 址将解除被连续赋值的状态. 从此刻起, 该赋值目 标又可以被更低优先级的赋佳话句进行赋值操作 了. 布 release 语句内的赋值口 标是寄存·措炎刑变缸的'的况下, 如果在 force 语句执行之前 \ 129\ 应用程原设i惯例糟瑞 该寄存器变量已经由于受 "挝Sign 语句" 的作用而处于被连续赋值的状态 〈 就是例 3-36 中 变 量 var_reg2 的情况), 那么在执行了 release 语旬之后, 该寄存器变量将恢复到由 assigl 语句实现的连续赋值状态: 如 果 在 岛rω 语句执行之前该寄存器变量不是处于被连续赋值 的状态 〈 即 ßiIJ 3-36 中变量 var_regl 的情况), 那么在执行了 release 吾t; 句后, 该寄存器变量 将退出被连续赋值状态, 其取值保持不变。 如果 rel国se 语 句 内 的 赋值 目 标是线网型数据. 并且在 force 语句执行之前已经通过 assip 语句或基本元件实例语句指定了驱动源 〈 即 分 别为例 3-37 中 var net1 和 var net2 的情况), 则在执行了 relωse 语句之后, 该线网型数据 将恢复到原有的驱动方式。 下面举例说明 release 语旬的使用。 E 例 3-381 为伊IJ 3-36 模块中的过程块加上 release 语句• m o d u le h M 咱4 zeq d uu 缸 、4 E in4,, -ce e --o-s v al - mpr、e目'qe ,. , V E e 9 何4 ,. 扫be何『, Var-zeql=OJ ass i J「g 习-4 uZ-Ln-0oz CJ e . ,ι0rCe 峰'1oJ v a r 一 Z e 9 2 = ., va r - r e q 1 = 4 ,. va z - Z e q 2 = 4·, CwA . relea e v a E-E eg 1, ed ., Eelea e v a r-E eqd 2 1 / 此 , 过程赋健语句 1152. 过程连绥赋值语旬. a55ign i蕃句 l/s3. 过程连续赋值语句. force 语句 11时, 过程连续赋值语旬. force 语句 Ils5. re1ease 语句 Ils6. re1ease 语句 end endmodu1e 在例 3-38 中 , 由于在执行 。 之前变量 var二regl 未曾 被 assign 语句进行过连续赋值操 作 , 因此在执行 sS 之后, 变量 var_reg l 将退出被连续赋值的状态, 其取值保持不变 ( 保 持原有值 "4勺。 但是对于 var_reg2 来说, 由于在执行 s4 之前变量 var_reg2 已经由 assign 语句 (s2) 实现了连续赋值, 所以在 56 执行后, 变量 V缸'_reg2 将恢复到由 笛Sign 语句 s2 确定的连续赋值状态, 即 被 " 1 " 连续赋值的状态。 E例 3-391 为例 3-37 模块 中 的过程块加 上 rel回归 语句 。 modu�e force_example2 (var_net1 , var_net2, inl , in2 ) ; input in1,in2; output Var-netl, Var-net2J wire var net l , var net 2 , Lnl,in2; assign var_netl=O; or #10 (var net2, inl,Ln2 ) ; 1151. 连续赋值语句. �等 Var-netl 连续赋值为 0 Ils2. 基本元件实例语旬, 指定 " 或f] n 输出对 Ilvar net2 进行连续驱动 /130� initial begin 120; force force var necl=inl&in2; //53. force 过程连续赋值语句 var nec2=(-inl)&in2; //54. force 过程连续赋侦语句 110: relea5e var necl; //55. release语句 relea5e var nec2; //56. relea5e语句 end endrnodule 在�IJ 3-39 中 , 由 F在 53 得到执行前 也Sign 再i 句 (51 ) 已经将线网型数据 var netl 指 定 为 由 "0" 连续驱动, 所以在执行了 release 爵句 (55) 之后, 变量 Var-net l 将退出 53 指 定 的连续赋值状态而恢复到语句 5L 指 定 的 dJ "0" 进行连续驱动的状态. 同样, 由 于 在 " 得到j执行前 52 已经将 var--rmt2 指定为由或门实例的输出端驱动 , 所以在执行 了 56 之后 , var net2 将迫出 54 指定的连续驱动状态而恢复到由 52 指定的连续驱动状态. 如 阁 3-20 所 示为例 3-39 的仿真输入输出被形. 阁 3-20 例 3-39模城的仿真输入输出放形 3.5 分支语旬 前而已经讲过, 过相块主要是由过秤z性赋伯语句 ( 包括普通过程赋值语句和过程连续 赋值语句 〉 及 高级�lU子研句 〈 包括分支语句和循环控制语句 ) 这两种行为谓钊所构成。 前 面已经对过程性赋值语句做了校为详细的介绍. r而所谓高级程序语旬, 就是为 f对硬件电 路进行行为描述而从阿级语言中直接借用的耻序设计语句. 高级和阵-吾i 句被刷于对硬件电 路的行为进行描埠, 它们只能出现在过程块 肉 . Veri10g HDL q:1的高级程序语句是从 C 语 占中引入的, 它们可以分成分支语句和循环控制语句两类。 本节将对高级程序语句中的分 支语句进行讨论 , 由关f循环挫和j语句留待下一节讨论。 Verilog HDL 巾存在着如下两种分支语句: • if-else 条件分支语句: • case 分支控制消句. 3.5.1 if-else 条件分支语句 i仁el罚 条件分支语句的作用是根据指定的判断条件是否满足来确定下一步要执行的操 队 1 31 \ 作. 它在使用时可以采用如下三种形式. 1 . 使用形式 t if (<条件表达式>) 语句成语句块J 这种使用形式中没有出现 el民 项, 其执行过程是: · 如果指定 的〈条件表达式〉成立 〈 即该条件表达式的逻辑值为 " 1 勺 , 贝1)执行条件分 支语句中给出的 " 语句或语句块", 然后退出条件分支语旬的执行. · 如果指定 的〈条件表达式〉不成立 ( 即 该条件表达式的涅辑值为 " 0"、 " x"、 "z 勺, 则不执行条件分支语句中给出的 " 语句或语句块", 而是直接退出条件分支语旬的 执行. 例如, 下面这条条件分支语句: if (enab1e==1) out-data in; 在 执 行 时 , 就会根据条件表达式 " enable-l " 是 否 成 立 来 决 定 是否执行赋值语句 "oupdata-ini": 如 果 enable 取值为 " } ", 则赋值语句 "oupdata-inf ' 得到执行 : 如 果 enable 的取值为 "0"、 Ilx" 或 "z飞 则不执行指定的赋值语句. 2. 使用形式 2 if (<条件表达式>) e1se 语句或语句块 1 ; 语句或语句块 2 ; 这种使用形式的条件分支语句将以如下方式得到执行. · 如果指定的〈条件表达式〉成立 , 贝1)执行 " 语句或语句块 1 ", 然后结束条件分支语 句的执行. · 如果指定的〈条件表达式〉不成立, 则执行 else 项指定 的 " 语句或语句块 2 ", 然后 结束条件分支语句的执行. 这种形式的 if-else 条件分支语句实现了一种二路分支选择控制. 例如下面的语句: i f ( select=l) out-input1; else out-input2; 在执行时, 将会根据条件表达式 " select= I " 是否成立来快定执行两条过程赋值语句中 的哪一条. 如 果 select 取值为 " 1 飞 则执行 Itout=input1 ;": 有则 〈 臼l民t 取值为 "0"、 41x " 或 "z勺 执行 "out=讪pu队". 3. 使用形式 3 i f (<条件:表达式 1>) 语句或语句块 1; /132h . '目 3 . else i f (<条件表达式 2>) 语句就滔句块 2 ; else if (<条件表达式 n-1>) 语句就语句 块 n - 1 ; else 语句或语句 块 n ; 这种使用形式中一共出现了 n 个条件分支项, 其中每个分支项都指定了 当该分支项的条件 满足时所要执行的操作. 在执行这种形式的 if-el脆 条件分支语句时, 将按照各个分支项的排列 顺序对各个条件表达式是否成立进行判断, 当遇到某一项的条件表达式成立时, 就执行这一项 所指定的语句或语句块, 然后地出整个条件分支语句的执行 。 如 果所有的条件表达式郁不成立, 则执行战后的 else 项所指定的 "语句或语句块 n", 然后退出整个条件分支语句的执行. 这种形式的 iιelse 条件分支语句实现了一种 多路分文选择控制。 E 例 3-40) 第三种形武的条件分支语句. rn。dule sel-fr。rn-three tq, sela, selb , a , b , c } J input sela, selb, a , b, c ; output q; reg q; always @ (sela or selb or a or b or c) begin if (sela) q=a; else i f ( selb) qQb; else q-c; end endmodule 在例 3-40 模 块 内 的 if-else 条件分支语句中出现了三个分支项 , 该 条件分支语句在执行 时将依次对控制信号 sela 和 selb的取值是否为 " 1 " 进行判断. · 如 果 sela 取值为 It 1 飞 即条件表达式 ttsela " 成立, 则赋值操作 (lq=a;" 得到j执行. · 如果 seLa 取值不为 " 1 飞 而 selb 1民值为 " 1 ", 叩条件表达式 11selb" 成夜, 如l赋 值操作 "qzb;" 得到执行。 · 如果 sela 和 selb 取值都不为 " 1 ", 即条件表达式 Itsela" 和 "白Ib" 郁不成立, 则 eLse 指定的赋值操作 "qzcin 得到执行. · 如果 seLa 和 selb 取值都为 " I 飞 即 条件表达式 " sela " 和 ttselb" 都成寸., 这种情 况下由于首先判断条件表达式 "sela ", 因其成立, 所 以就执行赋值操作 "q=a;飞 然后结束整个条件分支语句, 对后面的分支项条件农在i 式 "selb" 并不做判断, 所 以不会执行赋值操作 "q俨=b忱;" 可见, 这种形式的 if二else 条件分支语句内 各个条件表达式的排列顺序决定了对各个条 件表达式进行判断的先后次序, 这种排列顺序隐含着一种优先级关系, 即持:在前面的分支 项所指定的操作比后面的分立项所指定的操作有更高的优先级。 比如, 在例 3-40 中 , 条件 队 1 33\ /怎蝙吨 帽比四鹏话抗十跚跚 表达式 " sela" 就 比条件表达式 " selbtJ 更靠前, 所以赋伯语句 " q=a;" 比 " q=b;" 具有更 高的优先级 , 因此如 果两个条件表达式都成立时将执行赋值语句 " q=a; ", 然后结束整个条 件分支语旬, 而不会执行 "q=b;飞 如圈 子2L 所示为例 3-40 模块描述对应的硬件电路图。 selb I .‘ .、/ cI br al sclb 国/ 〉ï selb c 严、。\ b 共/ 目Ib ?〕 14:OUTI a 1 • IS:OUT•I 〉q 阳 3-21 例 3-40 悦块的硬件电路阁 对于上述三种形式的 if-else 条件分支语句, 巫j ilri作以下几点说明 . • <条件表达式〉一般是一个逻辑表达式或关系表达式. 如 果这个逻辑表达式或关系 表达式的取值为 " 1 ", 则认为 该条件.&达式成吐, 而如果该逻辑表达式戚关系表 达式取值不为 11 1 " ( 即取值为 "0"、 "xH 火L 气"), 贝IJ该条件表达式不成立. · 第气种和第三种形式的 if-else 条件分立语句在形式上是由 多行或多条语句构成, 但 Verilog HDL 将它们视为一条 if二else 条件分支语句来进行处理. · 处于分立项内 的朋 F指定该分支项对应操作的阳台J可以是一条行 为谓句成多条行 只J 语句. .(:f:: 多条行为语句悄况下要用 begio 和1 eod 这两个关键词将这多条语句组合 成一个语句块. 在 Verilog HDL 话:节-11还允许 if-else 条件分支语句嵌套使用. 例如: if (<条件付使这式 1>) if (<条件提达式 2>) else else if ( < 条件.êé在 i 武 3>) else �句 1; 语句2; 话句 3 ; 语句 ) 〈分支项表达式 1>: 话何必i吾句块 1; 〈分支项表达式 2>: i.肘.J或 ! 活i 句块2; 〈 ,优 M 、, 瓦AU扪'hil-J -dJ呀 d 土uh a 11 u K1MR · H K U n MU V 叫 e c a s e 或 治 n' 块 n·' 或 酒 '扪 块 n+ 1 在上述格式q1 , <控制衣达式〉代表着对程序流向进行控制的控制信号: 各〈分支项表 达式〉贝IJ代表〈控制表达式〉的某些具体状态缸, 在实际使用时, 这些分支项农达式迦常是 一些常重表达式 : 各个 " i蒋句或语句块" 贝IJ指定 了在各个分支下所要执行的操作: 处于战 后的以关键词 "default" 开头那个分支项称为默认分立项, 它可以默认. C部e 语句的执行过程如下: • 当〈控制衣达式〉驭值2夺$于〈分支项哀达式 l恬〉的值时, 执行 " 谓句或话f句才块 lγ尸" • 当〈控靠制tJ衣i达占式〉取值等于〈分支项哀达式2>的{值直时, 执行 " 语仨钊�或 戎4!且阳日讷怡 丰合句j块 2 "飞: .. .. .. · 如 果〈控�ljlJ衣达式〉取值 与 所有〈分支项表达式〉都不相等 , 贝IJ执行 defaull 分支项的 tt TìI-句或谓句块r1+ l ": · 在执行完任一分立项的 " 语句�! ìIf句块 " 后, 跳出 case 语句结构 , 终 Ll: case 语句 的执行. / 1 36/ • '自 3 j脏 case 语句中各〈分支项表达式〉的取值不能相 等 , 否 则出现语法错误. 如果〈控制表达式〉 的 多 个 不同取值对应向一操作, 则可以这样简写: 用 逗 号 ( , ) 将 这 多 个〈分支项表达式〉隔开, 再将在这些情况下需要执行的 " 语句或语句块" 放在这几个 分支项表达式的后面. 比如下面的语句: case(Op_code) 2 ' b O O : out=a&b;/ /控制表达式 " op_code " 取值为 " 2 ' b O O " 时执行操作 "out.-a岳阳 " 2'b01, 2'b10, 2'b1 1 : out�a lb; //控制表达式 "op_code" 取值为 "2'b01"、 "2'blO" 或 .. 2 ' b 11" 11'1" //执行操作 "out-a lb; " defau1t : out-0; //t空制表达式 " op_code" 取值与土述分支项表达式都不同时, 执行镇 //作 "out=O; " endcase 上述语句是下面多条语旬的简写形式: case (op_code) 2'bOO: out=a&b; 2 ' b0 1 : out=a l b ; 2 ' blO: out=a l b ; 2 ' b 1 1 : out=a lb; defaul t. : out且0; endcase //控制表达式 "op_code " 取值为 "2'bOOn 时执行操作 "out..a&b; " //撞制表达式 "op_code " 取值为 " 2 ' bOl" 8.]-执行操作 "out=a lb; " //撞倒表达式 " op_code" 取值为 " 2 ' bl O " 时执行操作 " out-a |bJ " //撞制表达式 " op_code" 取值为 " 2 ' bl l " 时执行操作 "out=a lb; " / /控制表达式 "op_code " 取值与上述分立项表达式都不同时, 执行操 //作 "。utz0 1 " case 语句中控制表达式和分支项表达式之间进行的 比较是一种按位进行的金等比较, 即只街在分支项表达式和控制哀达式对应的每一位都彼此相等的情况下才认为这两者是 相等的。 在进行对应位的 比较时, "x" 和 "z" 这两种逻辑状态与 "0"、 " 1 " 逻辑状态一 样作为合法的状态参与比较. 下面主举例说明这种金等比较的特点。 E例 3-43) c路e 语句执行时对 "革"、 IIZ" 状态的处理。 rn。dule example-xz{ i n} J input in; a1ways @ ( in) begin case(in) 1'b1: $disp1ay("va1ue o f input si9na1 i s 1 " ) ; 1 ' b O : $display( "va1ue o f input si9na1 is 0 " ) ; l' bx: $display ( "va1ue o f input si9na1 is in unknown state" ) ; 1 ' b z : $disp1ay ( "va1ue of input 5i9na1 is in high impedance state") ; 队137\ endcase end end.module 在上例中, 控制表达式为 "in飞 它有四种状态 110"、 11 1 "、 ,.x"、 气", 主与输入伯号 in 的取值为 "x" 时, 只有第 3 个分支项的表达式值与控制表达式的比较结果为 "相等", 此 时执行语句 .. $display("value of input signal is in unknown state");": 同样当输入信号 in 取值 为 "z" 时 , 执行语句 "$display("value of input signal is in high impedance state");飞 由 于 case 语句具有上述按他进行全等比较的特点 , 所以控制表达式和分支项表达式必 须具有相同的位宽, 只有这样控制表达式和分支项表达式才能ill行正确的比较: 当各个分 支项以常:数形式给出时, 必须显式地标明每个常数的位宽 . 否则 Veri10g 编译端会认为'自 们具有与机器字长相同的位宽. 下面举例说明 c臼e 语句的应用. E例 3-44) 用 臼se 语句实现操作码译码. modu le decode-of-opcode-use-case t a , b , 。pc。de , 。uE } ; input [ 7 : 0 ) a , b ; inpu t [ l : O ) opcode; 。utput [ 7 : 0 ) ouc; reg out; always @ (a or b or opcode) begin case ( opcode) 2 ' b l O : out-a+b; 2 ' b l l : out=a-b; 2 ' bOl: out-a食b; 2 ' b O O : out=a/b; endcase end endmodule 如阁 3-22 所示为对该榄块进行仿真的输入输出波形. / 1 38 � 困 3-22 例 3-44 模块的仿真输入输出议形 第3. 2. casez 和 casex 语旬 Verilog HDL还提供了另外两种形式的 case 分支语旬 , 它们 是 casez 语句和 casex 语句. 可以利用它们来实现这样的分支控制: 由控制表达式和分支项表达式一部分数位的比较结 果来决定程序的流向。 C槌ez 语句执行时的比较过程将不考虑控制表达式及分支项表达式 中处于高阻态 11z" 的那些位的比较, 而 臼sex 语句则将高阻态 "z" 和不定态 气" 都视为 不必关心的情况. 通过这两种形式的分支控制语旬, 就可以通过对控制表达式和分支项表 达式的灵活设定来实现由一部分数位取值决定的分支控制. ( 1 ) c皑白 语句 臼sez 语句的格式如下: casez (<控制表达式>) 〈分支项表达式 1>: 语句或语句块 1 ; 〈分立项表达式 2>: 苔 ìi 句或吾 i 句块 2; .... ... 〈分支项农达式 的: 杏 i' 句或语句块 0; defau1t: 语句或语句块 n+1: endcase 从上面的格式可见, c臼ez 语句和 C路e 语旬的使用格式完全相同 , 两者唯一不 同的是 使用不同的关键词 Ucasez" 和 Itcase "。 在 casez 语句中 , 如果控制表达式或分支项表达式 的某一位取值为 "z飞 则在分支语句执行时将忽略该位的比较, 即控制表达式和分支项表 达式在这一位的取值将不会对程序流程分支的选择产生任何影响 。 下面举例说明 casez 语 句的应用。 E例 3-45] 用 casez 语句实现操作码译码。 module decode_of_opcode_use_casez ( a , b , opcode, out) ; input [ 7 : 0 ] a , b ; input [ 3 : 0 ) opcode; output [ 7 : 0 ] out; reg [ 7 : 0 ) out; always @ (a or b or opcode) begin casez (opcode) 4 ' blzzz: 。ut=a+b: //分支项 1 4 ' b0 1 ? ? : 。ut=a-b; 1/分支项 2 4 ' b001 ? : out=a*b; /1分支项 3 4 ' b0001 : out:=a/b; //分支项 4 endcase end endmodule 队 139\ 应黯雹厚如f实倒藕诩 在例 3-45 模块中, 输入信号 。p∞de 为四位宽的操作码, 它用来指定对输入 a, b 执行 的运算类型, 臼血Z 语 句 内 的控制表达式为操作码 "opcode飞 各分支项表达式以常量形式 给出: · 第 l 分支项表达式为 " 4'blzzz", 其低三位为 (, z", 所 以控制表达式在与该分支项 表达式进行比较时将忽略这低三位, 只对最高位进行比较。 所 以只要操作码的最 高位取值为(1 1 ", 两个表达式的比较结果就" 相 等 飞 该分支项对应的操作"out=a+bi" 就得到执行. • 第 2 分支项衰达式为 "4'bω01凹??俨", 其低二位为 (1叮?"飞, 在此符号号� lt?γ" 的含义就是 "气z 扩" 所以控f帘制如剖j表达式在与该分支项表达式进行比较时将忽略低二位, 只对高二位进行 比较。 所 以 只要操作码的最高二位取值为 "01 飞 两个表达式的比较结果就"相等", 该分支项对应的操作 "oupa-bin 就得到执行. · 第 3 分支项表达武为 " 4'bOOl ?飞 其最低位为 "?", 所以控制表达式在与该分支项 表达式进行比较时将忽略最低位, 只对高三位进行 比较。 所 以只要操作码的最高 三位取值为 " 001 " , 两 个 表 达 式 的 比 较 结 果 就 " 相 等 ", 该分支项对应的 操 作 "oupfbi" 就得到执行。 · 第 4 分支项表达式为 "4'ω001 飞 没有哪一位是 "z", 所 以控制表达式在与该分 支项表达式进行比较时对全部四位都要进行 比较。 只有 当操作码的取值为 "4'b∞01 " 时, 两个表达式的 比较结果才 " 相等", 该分支项对应的操作 "OUFUbin 得到执行. ( 2 ) c臼ex 语句 C部ex 语句的格式如下: ,,.1.••:… .:.• casex(<控制农达式>) 〈分支项表达式 1> : 沼句或i备也j块 1 ; .」J ‘咽 圃' '‘咽 圃...,-. - . - . . ‘咽 圃, '‘咽 圃, , 〈分支项农达式 2>: 语句成语句块 2; 〈分支项表达式 n>: 语句或语句块 n; default: 语句或语句块 n+1; endcase 从上面的格式可见, casex 语句与 casez 语旬以及 C臼e 语旬的使用格式完全相间, 在此 不同的是使用 了关键词 Ifc槌ex飞 与 C路ez i吾旬的不同之处在f: 在 casex 语句中 , 如果控 制表达式或分支项表达式的某一位处于 "z" 或 "x" 状态, 则在分支语合j执行时将忽略该 位的比较: 而在 casez 语句中只忽略处于 " z " 状态的位。 下面举例说明 casex 语旬的应用。 E例 3-46) 用 ωsex 语句实现操作码译码。 module decode-of-opcode-use-case x { a , b , 。pc。de,out) J / 140;'4 .3. input. [ 7 : 0 ] a , b ; input [ 3 : 0 1 opcode; output [ 7 : 0 ) out; reg [ 7 : 0 ] out.; always @ (a or b o r opcode) begin casex(opcode ) 4 ' blzzx: out=a+b; 4 ' bOlxx: out.=a-b; 4'bOOl?: 。ut=a*b; 4'bOOOl: out=a/b; endcase end endmodu l e 11分立项 1 11分支项 2 11分立项 3 11分立项 4 在例 3-46 模块中, 控制表达式 lO) disable .5 clk=‘clk; end end end endrnodule FORεVER-PARTJ • / 142/ 如图 3-24 所示为其仿真输出波形. '目 3 . 圈 子24 例 3-48 棋块的仿其输出放形 与例 3-47 相 比 , 在例 3-48 所描述模块 中 , 通过使用 disable 语句实现了对时钟个数的 限制 〈 柳11111限制个数为 5)0 forever 循环语句被置于有名语句块 11 FOREVER PART" 之 内 , 问时'ι 自 身 的循环体部分由另一个语句块构 成. 该循环体语句块包含i条 语句 , 当 终 止语句 "disable FOREVER_PART;tt 得到执行时 , 有名块 " FOREVER-PART" 的执行将被 终止, 程序流程将跳出 " FOREVER PART" 语句块. 当 forever 谓,句的循环次数执行到 1 1 时 , if条件语句中 的 条件表达式 " counter>10" 成立, 否i 合d "disable FOREVER_PART; " 就 得到执行 , 从而实现了跳出 forever 循环的 目 的 . 3.6.2 repeat 循环语句 repeal 循环语句实现的是一种循环次数顶先指定的循环, 这种循环语句内的循环体部 分将被电复执行指定的次数o repeat 循环语句的语法格式如下: repeat (<循环次数表达式》 语句或tit句块; .fEl:述格式中: • <循环�数表达式〉用于指定循环次数, 它可以是一个鸭咆常报、 寄非器变量·或者 一个数值表达式. 如果 为变盘或者姓值农达式, 其取值只在第一次:ìa入循环时得 到计算 ( 从而旬以事先确定循环次数). • "语句或语句块" 是要被重复执行的循环体部分。 下面举例说明 repeat 循环语旬的应用. E 例 3-49】 用 repeat 循环语句实现循环移位。 modu1e shiít(data out,data in,num,ctrl ) ; input l 1 5 : 0 1 data_in ; input l 3 : 01 num; input ctr1; output [ 1 5 : 0 ] data_out ; reg t:mp; reg [ 1 5 : 0 ] data一。uti a1ways @ (ctr1) begin data out=data �ni i f (ctrl-=l) repeat (num) begin 口np=data_out [15] i data out=data out< ) 语句戎语句块: 在上述格式中, <条件表达式〉代 表 了 循环体得剑重复执行时必须满足的条件, 它通常 是一个逻辑表达式, 在每一次执行循环体之前都要对这个条件表达式是否成立进行判断: " 语句或语句块" 代表了被重复执行的循环体部分. 下面举例说明 while 循环语旬的使用. • E 例 3-51) wbile 循环语句• m 。 d u -e - d ‘n u e e x e ,. 副 n p 咱• -lnteger c ω n E J initial beg -- n count"'O; while (count) 循环体谓句lJ戎语句块: 在上述格式巾: 〈i罚,公Ij L>和〈语句 2>足两条立j 耻赋值语句, 它们分别用来对循环计数 变茧执行赋初值操作和增值操作。 〈条件表达式〉代表循环重复进行时必须满址的 条件, 它 通常是一个逻辑表达式. 在每一次执行循环体之前都要对这个条件表达式是否成立进行判 断 . " 循环体语句或语句块 " 是要被重复执行的循环体部分. for 循环语旬的执行过程如下。 ①执行〈语句 1>0 ②判断〈条件表达式〉是否成立: 若〈条件表达式〉成立, 则执行指定的 "循环体语合v!ll 语旬块", 然后继续执行下面的第③步: 若〈条件表达式〉不成立, 则不再执行 " 循环体谓 合j或语句块 飞 结束循环过程, 跳出 for循环语句. ③执行〈语句 2>. 然后转至IJ②继续执行. 由 上面的执行步骤可以 看 出 : 〈语iJJ 1>只有在第一次循环开始之前被执行一次, 它通 常是一条给循环计数变Ji1:赋初值的过程赋值语句: <语句 2>是在每次循环结束后下一次循 环开始前被执行的 , 它通常用 于对循环计数变目的取值进行修改: 而〈条件表达式〉的取值 判断是在每次循环开始前进行的, 它的结果决应括 "是 沓继续执行循环 飞 条件点沾式的 收值往往是随着循环的进行而发生变化的. 如果: 条件表地式的取值在韩个循环过程中一宦 保持不变, 那么循环体�么是一忧郁得不到执行, ZE么).i!i1!入执行无限次听i环的死循环。 国此, for 循环语句实际上等价于由 wlùle 循环IBftJ构皑的如下循环结构: / 146 ...:4 .3 begin 〈语句 1>; while{<条件表达式>) begin 循环体语句就语句块; 〈语句2>; end end 这样对于使用 while 循环语句时需要 3 条语句才能完成的一个循环控制, for 循环语句 只需要一条语句就可以实现. 下面使用 for 循环语句来描述与例 3-51 相同的功能. E例 3-521 岛r循环语句. module for_example; integer count; initial begin for (count-O; count<10; count-count+ 1 ) begin $display {"count=屯d", count ) ; '5; end end endmodule //循环体语句块 下面再举一例说明 for循环语句的应用。 E例 3-53 1 用 for 循环语句实现一个 8 位乘法器 。 module multipl ier_8bit s ( result,opl,op2) ; parameter WIDTH-8; parameter LONGWIDTH-16; input [WIDTH- 1 : 0j opl , op2; output [LONGWIOTH-1 : 0 j result; • reg [LONGWIDTH- l : O ] result; always @ (op1 or op2) begin: mult integer index; //循环变量定义 reg [LONGWIOTR-1 : 0 j shift_opl, shift_op2 ; // 局部变量定义 shíft_opl-opl; shift_op2-op2 ; result=O; for( index-O; index<=WIDTH-l; index=index+l) //for 循环语句 íf (shí ft_op2 {index]--1) //循环体语句为一条 if语句 result=result+(shift_opl<; 端 n 炎刚与说明 J 间部变ß说|引 1; begin 〈行为m句 1>; 〈行为语句2>; ...- 〈行为语句 n〉; end eodtask 针对上述格式作 以下几点说明. · 关键百i� task 平U endtask 将它们之问 的 内 容标志成是一个任务定义o <任务名〉是为 所定义任务取的名字. 在11:1版本的 Verilog HDL 中不允许在任务定 义时在〈任务名 〉后面出现输入输出端口列表. 而在 IEEE StdI364-2001 标准中. 可以在任务定义 时将输入输出端口列表放在〈任务名〉后面. 例 如 , 这样的任务定义是合法的: task <任务名> (input a, output b) ; begin 〈行为语句 1>; d于为谓句 2>; 〈行为语句n>; end endtask / 148h 第 3 1民 • u端 口类型与说明 " 用于对任务各个端口 的宽度和类型进行说 明 , 其中端口类型 由关键词 inPUl,output.inout ( 分别哀示输入、 输出和双向端 口 〉 指定, 该说明语旬 的语法与棋块定义时相应说明语旬的语法是一致的。 • "局部变章说明 " 用来对任务内用到的局部变量进行宽度和类型说明, 该说明语 旬的语法与模块定义时相应说明语句语法一致. • 由 begin-end 关键词界定的一组行为 语句指明 了 任务被调用时需要进行的操作 . 在 任务被调用时, 这些行为语句将按顺序方式得到执行. · 任 务 定义与过程块、 连续赋值语句及雨 数定义这四种成分以并列方式梓布于行为 描述模块巾, 它们在层次级别上是相同的. 任务定义结构不能出现在任何一个过 程块的内部. E例 3-541 任务的 定义. task read mem; //指定任务 名为 " read mem " input [ 1 5 : 0 ) address://输入编 门 说明 。utput [31 : 0 1 data; //输出制 n 说明 reg [ 3 : 0 ) counteri //局部交1i说明 reg [ 7 : 0J temp (1 : 4 ) i //局部变fit说明 begin //请句块, 指明任务被调用时衍要滋行的操作 for(counter- l ; counter<=4; counter�counter+l) temp [ counter] =mem [address+counter-l ] i data=! temp [ 1 ) , temp [2 ) , t emp [ 3 ) , temp [ 4 ) } ; end endtask //任务定义结构的结尾 当 上 例 所 定 义 的 任 务 被 调 用 时 . begin-end 语句块将得到执行, 用 来完成对非储器 "memn 的四次读操作, 将其结果合并后输出到端口 "飞data" 在任务定义时必须注意以下儿点: · 在任 务定义结构 中 的 " 行 为 南旬 " 部分可以有延时隔句 、 敏感事件控制谓旬等时 问控制语句出现. · 一个任务 可以没街输入、 输出 或双向端口 , 也可以有一个或多 个输入、 输出或双 向端口. · 一个任务可以没有返回值, 也可以JiIt过输出端口或双向瑞口运回一个或多个返回值. · 在一个任务中可 以 调用其他的任务局立面数 , 也可 以训用该任务本身 。 · 在任务 定 义结构内 不允许出现过程块 ( initial 或 always 过程块). · 在任务定义结 构 内 可 以 出现 " disable 终止语句飞 中 断正在执行的任务 , 程序流程 返回到调用任务的地方继续向下执行. 2. 任务的调用 任务的调用是通过任务调用语句来实现的。 任务调用语句的语法格式如下: t、、 149\ 〈任务名> ( 端 口 1 , 端 口 2 , … , 端 口 n) ; 其 中 , ( 端 口 L端口 2,…,端 口 n ) 组成了一个端 口 名 列 表 。 在任务调用时需要注意以下儿点: · 任务调用语句只能出现在过程块内 : · 任务调用语句就像一条普通的行为语句那样得到处理: · 当被调用的任务具有输入或输出端 口 时 , 任务调用语句必须包含端 口 名 列 衰, 该 列表内各个端口名 出现的顺序和类型必须与任务定义结构中端口 说明部分的端 口 顺序和类型相一致。 注意: 只有寄存器类型的变量才能与任务的输出端口相对应。 下例中 的模块对例 子54 中定义的任务 11 r,回d mem" 进行了调用。 E例 3-551 任务的调用。 module task call; reg [ 7 : 0 ] mem[128 : 0 ] ; reg [ 1 5 : 0 1 addressi reg 1 3 1 : 0 1 data; init.ial begin mem [ O ] =S ' hOOi mem[ l J " S ' hOl; mem [ 2 ] = 8 ' h02; mem [3]=S 'h03i mem[64 ]=S 'h64; mem [ 6 5 ) = 8 ' h65; mem [66]=8 ' h6 '6i mem [67 J = 8 ' h67; end initial //initial过程块, 给有·储锦赋初值 /I initial 过程块, 调用任务 " read-rlem", 卖i 取巳赋初 //值的存储器值并显示 begin no address=O; read mem(address, data) ; $disp1ay ( "The value of data in address 屯d i s %h", address, data) ; 1110; address=64; read mem(address, datal ; $display(" The value of data in address 屯d 1s 毡h", address, datal ; end 〈任务 " read mem" 定义部分〉 endmodule / 1 50;" 下面是该模块的仿真结果: The value of da�a in address The value o f da�a in address 0 is 00010203 64 is 64656667 任务的调用具有以下特点: · 在任务内 定 义的局部变量都具有局部和静态的特点. fJ.p如果同时对同一任务进行 两次调用, 则 两个调用进程使用的将是相同物理地址处的同一个用部变:Ji1:. 在此 情况下要防止内存使用冲突。 · 在一个任务 中可 以直接访问上一级调用模块的 任何寄存黯. 例如 , 例 3-55 中我们 可以在任务 "read mem" 中对持储糟变盘 mem 进行访问, 该 mem 变iil足在t一 级棋块 ..task call" 中定义的。 • 由 于 任 务 内 部 可 以包含时间控制语句, 所 以调用一个任务所需的时间可以是非零 时间单位, 即任务的启动时刻可以是不同于任务结束时刻的. · 可以通过一个 disable 语句来中断任务的执行. 任 务被中断后, 程序流程将返回到 调 用 任 务 的 地方继续往下执行. 下面再举一例 说 明 任 务 的 调 用 。 E例 3-56 ) 利用任务调用实现交通灯控制. modu le traffic_lights; reg clock, red, amber, green; parameter on 事 1 , off = 0 , zed-ties = 350, amber_tics = 3 0 , green_tics - 200; //交通灯初始化 initial red - off; initial amber = off; initial green - off; / /交通灯时序控制 always begin reà = on; / / 开红灯 light (red, red_ti c s ) ; green - on; light (green, green_tics) ; //调用延时关灯任务 / /开绿灯 //调用短时关灯任务 amber - oni light (amber, amber_t i c s ) ; / / 开黄灯 // 揭ì 用延附关灯任务 end //延时关灯任务定义 task ligh�; 。u�put color; input [ 3 1 : 0 1 tics; �151 \ begin repeat (tics) @ (posedge c1ock) ; / /延时 co10r = off; / /关灯 end endtask / / 时钟脉冲放形产生 a1ways begin 1100 c10ck = 0; 11100 olock = 1 ; end endmodu1e 上例描述了一个简 单的交通灯时序控制。 任务 " ligbt" 用 来使指定颜色的交通灯延迟 指定的时钟脉冲间期个数后关闭. 其输出端口 "color" 对应着被控制交通灯的颜色, 输入 端 口 It ticsn 对应着延时周期数. 因此上述模块实现的功能是: 点亮红灯 350 个时钟周期 后关闭: 紧接着点亮绿灯. 200 个时钟周期后关闭: 然后紧接着点亮黄灯. 30个时钟周期 后关闭. 如此不断循环, 其中每个时钟周期为 200 个时间单位. 3.7.2 函数 ( function ) 函数 ( function) 类似于其他编程语高 中 的 丽 数概念。 与任务一样, Verilog HDL语言 中的函数使用包括了函数的定义和函数调用。 1 函数的定义 函 数 定 义 的 语法 格 式 如 下 : function <返l!:!I值类型wt返回值宽度> <函数 名片 〈输入编 门说明〉 〈局部变r.l:说明 〉 begin 〈行为语句1>; 〈行为语句 2>; …... 〈行为语句n>; end endfunction 针对上述格式, 作如下说明. · 关 键 词 U funclion " 和 " endfunction ., 衣 示 这 部 分 语 句 是一 个 函 数 定 义 结 构 . " function " 标志带这个函数定义结构的开始, "endfunction11 标志着函数定义结构 的结束. / 1 52� • <函数名〉是为被定义函数所取的名字, 对被定义函数的调用是通过该函数名进行 的. 该函数名在函数定义结构内部还代表着一个内部变量, 函数调用后的返回值是 通过该函数名变量传递给调用语句的. 旧版本的 Verilog HDL语言中, 不允许函数 定义时在〈函数名〉后面出现端口列表, 但是在 ffiEE StdI364-2001 标准中, 可以在 函数定义时将输入端口列表放在〈函数名〉后面。 例如 , 这样的函数定义是合法的: function <返回值类型!!.x返回值宽股> <萨l数名> ( input [ 1 5 : 0 ) address> ; 〈局部变盘说明〉 begin 〈行 为 语 句 1 > ; 〈行为滔句 2>; 〈行为 i着句 n〉J end endfunction • <返回值类型或返回值宽度〉是可选工页, 它用来对函数调用返回数据的类型或宽度 进行说明 〈 这个数据是通过函 数 名 远 囚 的 ) , 它可以有如下三种形式: � [msb:lsb]: 这种形式说明函数名所代表的返回数据变量是一个多位的寄存器变 量 , 它的位数由[msb:lsb]指定。 比 如 , 如下函数定义语句: funcüon [ 7 : 0 ) adder; 就定义了一个函数 adder. 其函数名 "adder" 还代表着一个 8 位宽的寄存器变 盘 , 其最高位为第 7 位, 最低位为第 0 位。 )i.> integer: 这种形式说 明 函 数名 所代表的返剧数据变革是一个整型变量。 )i.> real: 这种形式说明函数名 所代表的返回数据变量是一个实数型变量。 如 果 默认〈返回值类型或返回值宽度>, 则默认雨 数名代表的变景是一个一位 的寄存器变盘。 • <输入端口说明>: 用来对函数各个输入端口的宽度和类型进行说明, 在函数定义 中必须至 少有一个输入端 口 ; 该输入端口说明 语旬的语法与模块定义时输入端口 说明 语旬的语法是一致的。 也意: 在函数定义结构中不允许出现任何输出端口 (output) 或j 者双向端口 ( inout)。 • <局部变量说明只 是对函数 内 部局部变盘'的宽度和类型进行说明。 • <行为语句〉: 由关键词 "begin " 和 "end " 界定, 这部分语旬指明 了 函 数被调用 时要执行的操作, 它们决定着函数实现的运算功能。 在 函 数 被 调 用 时 , 这些行为 语句将按顺序方式得到执行。 E例 3-57 ) 函数的定义. function [ 7 : 0 ) getby te; � 153\ input [ 63 : 0 ) word; //输入制口 说明 input [ 3 : 0 ) bytenum; //输入瑞口说明 integer bit; reg [ 7 : 0 ) temp; //局部变量说明 /1用部变量说明 begin 11行为语句块. 指定函数调用时要执行的馀作 for(bit-0;bit<7;bit=bit+1) temp [bit) =word ( ( (bytenum- l ) . S ) +bit) ; getbyte-temp; end endfunction 上例定义了一个名为 ..getbyte" 的函 数, 该函数有两个输入端 口 : 一个 64 位的输入 端口 IIword" 和一个四位的输入端口 tl bytenum飞 同时该函数还定义了 两个局部变革:: b让 ( 整型变量〉 和 temp (8 位寄存器变量). 该函数被调用时, begin-end 语句块将得到执行, 其中第第一条 for循环语句实现 了 将 64 位寄存器 word 的一部分位的值赋给变盘 比mp, 需 要赋值的位由输入 byteoum 来指定: 第二条赋值语句将得到的 temp 的值赋给函数名变量 "getbyte", 这样就可以通过这个函数名变量将结果值返回给调用语句. 在进行函数定义时必须注意: · 与任 务一样, 函数定义结构只能出现在模块中, 而不能出现在过程块 内 . • 函数必须至少有一个输入端口. • 函数不能有任何类型的输出端 口 (output 喘 口 〉 和双向端口 ( inout 端 口 ). · 在函数定义结构中的行为语句部分不能出现任何类型的时间控制语旬 , 也不允许 使用 disable 终止语句. · 与任务定义一样, 函 数定 义结 构 内部不能出现过程块. · 在一个函数 内 可以对其他函数进行调用, 但是函数不能调用其他任务 . 2. 函数的调用 函 数 调 用 的格式如下: 〈函数名> (<输入波达式 1>, <输入表达式 2>, … , <输入表达式 m》 ; 其 中 . m 个〈输入表达式〉与 函 数 定 义结构巾说明的各个输入端口一一对店, 它们代表 着各个输入端口的输入数据. 这些输入表达式的排列顺序及类型必须与各个输入端 口在函 数定义结构中的排列顺序及类型严格保持一致. 在调用 函 数时必须注意如下两点: • 函 数的调用不能单独作为一条语句出现, 它只能作为一个操作数出现在调用语句 内 。 例如, 下面这条语句对前面所定义 的 函 数 11gegbyte" 进行 了 训 用 : 。uc=getbyte ( inputl . number) ; 在这条语句中 , 函数调用部分 Itgetbyte( input1 , number) " 被看做是一个操作数, 该操 / 1 541.. 作数的取值就是函数调用的返回值。 函数调用部分不能作为一条语旬出现, 即这样的语 句是非法的: getbyte (inputl, number ) ; • 函数调用既能出现在过程块 内 , 也能出现在 assign 连续赋值语句 中 。 比如语句: wi_re [ 7 : 0 ] netl; reg[63 : 0 ] inputl; assign netl=getbyte (input l , 3 ) ; 中的 函数调用就出现在一条连续赋值语句中 , 该语句指定由函数调用返回值对 8 位线 阿型数据 net1 进行连续驱动。 E例 3-58) 函数的调用。 module function call; reg ( 7 : 0 ) call_output ; reg [ 63 : 0 ] call_inputl; reg [ 3 : 0 ] ca�1_input2; initi� begin call inputl=6 4 ' h1234S67B9abcdefO; call_input2=3; cal1_output=getbyte (cal �_inputl , call_1nput2 ) ; I/ 第一伙调用 $dìsplay ("afte.r the first call. the returned l7alue is: %h", call_output ) ; nOO; $dìsplay ("secondca.L1. returnvalue 1s :毡h" , getbyte ( cal�_inputl , 6 ) ) ; 1/第二次调用 end • 〈函数 gett>yte 定义部分〉 encimodule 对该模块进行仿 真 的 输 出 结 果 为 z after the first call, the returned value is:bc second ca�l, return value is : 5 6 在上例模块中的 initial 过程块内对例 3-57 中 定 义 的 函数 "getbyte " 进行 了两次调用: 第一次调用是作为过程赋值语句 "caU_output=getbyte(call_input l ,call_input2); " 右端的赋值 表达式出现的: 第二次调用是作为 系统任务$display 语句内的 " 输 出 变量表项 " 出现的. 从以上给出的函数定义和酶数调用的例子可以看出 , 在函数定 义中必须有一条赋值语 句来对函数名变量进行贼值, 这样才能通过这个函数名变量来将 函 数 调 闸 的结 果 〈运回值〉 传边给调用语句 。 在例 3-57 中给出 的 函 数 定 义 中 , t.getbyte-temp;" 就是这样的一条赋值 语旬, 它将函数调用的运算结果 ( 变量 temp 的取值〉 赋值给函数名变量 getbyte. 队 1 55 \ 应用雹摩设计实倒篇讲 函数的每一改调用只能通过函数名变量返回一个值. 如果椅望一放函数调用能返回多 个值, 可以通过在函数定义和函数调用中使用连接操作符 " { } " 来实现. E例 3-59) 由一次函 数调用返回多个值的方法. module multi out function; reg [ 7 : 0 ) a,b, c , d ; initia1 begin a-8'h54; b-8'h32; I c , dl -multi out func 恼 , b ) ; Ilì蕃句 s1. 边行陆数调用的过程赋也语句 $display ("the va1ue of c i s : %h d i s : 屯 h" , c , d ) ; end function [ l S : 0 ) mu1ti out func; input [ 7 : 0 ) i n 1 , in2; reg [ 7 : 0 ) outl; reg [ 7 : 0 ) out2; begin outl�inl&in2; 。ut2=in l l i n 2 ; multi out func叶。ut1, out2 } ; 11m句 s2. 对函敖名交量进行赋值 end endfunction endmodule 对上述棋块进行仿真的输 出结果为: the value of c is : 10 d i s : 7 6 在例 3-59 模块的雨数定 义 内 , 语句 52 通过连接操作符把两个输出值 。ut l 和 out2 合并 成一个值并将'自赋给函 撤名变量 'SERUM-out-func飞 这样在形式 上边是只有 multi-OULhnc 变母这一个返剧值, 但是该远回 值内实际上包含 了 两个输山数据. 在 对 函 数 " multi out fun c " 进 行调 用 的 过 程赋 值 语 'Í:lJ 5 1 巾 , 雨 敬 调 用 返 回 值 " multi out func " 被赋值给两个变盘 c 和 d 组合成的1:-并变 !ìì: . 这样在执行了赋值语句 sI 之后, 函 数调 用 返 回 值 " muIUJOut-fmc" 中 包 含 的 两 个 输 山 值就被分 别赋值给变量 c 和 d. 注嚣z 由于在函数定义结构内不能 出现任何类型的时间控制语 句 , 因此函数调 用 执行所需的时间只能是靠仿真 时 间 . 即 函数调用的启动时刻和返回时 割是相 同的. 下面给出一个较复杂的应用函数的例子. / 156!A • 第3 • E 例 3-601 乘加器。 module mult_acc(out , ina,inb,clk, clr) ; input [ 7 : 0 ) j_na,inbi input clk,clri output [ 1 5 : 0 ) out; wire [15 : 0 ] mult out, adder outi reg ( 15 : 0 ) outi assign adder_out�mult_out+out; 11实现}JIJ 法运算 assign mult一。ut=mu1t (ina, inb) ; 11调用乘法运n函数, 实现乘法运算 always @ (posedge clk or posedge clr) / /描述时序逻辑, 实现异w消零和输出量k据 egin /1锁存功能 i f (clr) 。ut=1 6'hOOOO; else 。ut=adder out; end Lunction { 1 5 : 0 ] mult; /1函数定义部分 Lnput [ 7 : 0] a,b; reg ( 1 5 : 0 ] r; begin r=O ; for (主=0; i<=7; i=i+1 ) begin i f (a (i}=l) r=r+ (b< (<模块端口列表>J ; 声明语句 模块组项 函数和任务定义 specify 块 endmodule 针对上述格式, 作如下说明。 • <模块名〉: 是给棋块取的一个名字, 它是模块的标识符. • <模块端 口 列 表〉z 是由输入端 口 、 输出 端 口 、 双 向 端 口 的端 口表达式按一定次序 组成的一个列袭, 它用来指明模块所具有的端口。 模块可以利用这些端口与其他 外部模块进行通信。 • 声明语句: 用来对模块端口类型 (输入、 输出或双向端口〉、 模块内部数据的类型 ( 寄存器变量、 存储器和线网类型〉 以及模块内参数进行说明。 模块中将用到的声 明语句如下: Þ> parameter: 参数声明语句: Þ> ioput: 输入端口声明语句: Þ> output: 输 出 端 口 声 明 语 句 : > inout: 双 向 端 口 声 明语句: Þ> net-type: 线网型数据声明语句: Þ> register-type: 寄存器类型变盘声明语句: Þ> time: 时间类型变量声明语句: /160� );> integer: 整数类型变量声明语句: );> 回r 1: 实数类理变量声明语句: );> event: 有名事件声明语句. · 棋块组项: 模块功能的描述体部分, 用来对模块的功能特点进行描述 , 在这一部 分可以出现具街行为描述性质的语句结构 ( inirial 过程块、 always 过程块或连续赋 值语句), 也可以 出现结构描述语句 ( 模块实例语句、 门级元件实例语句、 开关级 元件实例语句)0 如果在这个 "模块组项 " 中只使用了 结构描述语旬, 那么该模块 就是一个 "结构描述模块"。 • 函数和任务定义: 用 来对模块结i项内 使用 的一些函数和任务进行定义. 由于 函 数 和任务都是行为捕述性质的程序约构, 所以在 " 结构描述棋块" 内 不能使用函数 或任务. • specify 块: 用于对棋块输入、 输出端口 之间的路径延时时间量进行说明 . 同 时还 可 以 用 来 进 行 时序 检 验 。 4.1.2 模块的蹦口 一个模块往往具有多个端 口 , 它们代表了 本模块和其他模块间的接 口 . 在模块定义格 式中, 模块端 口 列 表 列 出 了 模块具有的外部可见端 口 , 这个模块端口 列表 内 的每一个端口 项都代友右一个模块端 口 . 1 . 模块端口歹IJ表 模块端口列表可以是如下两种之一: 隐式端 口 名 形式、 �h\端口名形式. ( 1 ) 隐式端 口 名 形式 这种形式的模块端 口 夕IJ衷的格式为t 《端口 表达式 l>,<�越口表达式2>,...... , di陆 n 表达式 n>) 其 中 的各个d南口表达式〉指 明 了 各个模块踹口 与模块内变量的连接关 系, 一个d描口 表达式〉 可 以 是 : · 模块内某个变iil:的标识符: · 模块 内某个矢1ll:变量的 某一位: · 模块内某个矢且;变量的某几位: • r.úû三种形式的组合. 在隐式端 口 名形式的端口列表中, 没有显式地为各个模块端口指定端口 名 , 这时各个 模块端 口 的端 口 名将按照如下规则得到隐式定义. · 如果给 出的端口 哀达式是一个变量标识符 ( 上面端 口 友达式形式的第一种情况), 则该端 口 表达式对应的端 口 名 被默认地定义为该标识符 本 身 。 队 161 \ · 如果给 出 的 端 口 表达式不 是一个 变嚣;标识符 〈 上面 端 口 表达式形式的后三 种情 况 ) , 则对应的端口将处于 " 无名状态" ( 不存在瑞 口 名 ). E例 4-1 ) 隐式端 口 名形式的模块喘 口 列表. modu�e e x 1 ( a , b , z ) : input a , b ; 。utput z; endmodule module ex2(a [ 1 ) , a ( 0 ) , z ) ; input [ 1 : 0 1 Ð : output Zi endmodule mod�e ex3 ( { a , b ) , z ) ; input a , 如 。utput Zi endmodule //端口声明语句 1 / 辅 口 声 明 说句 /1崎n jlJl!1l ì币,句 //踹口声明讷句 / / 均 口 声 明 iIf 句 //喝 口 严明 i否句 在例 4-1 中 定 义了 =气个模块 ex1、 ex2、 ex3. 这士气个模块定 义中都使用了隐式端 口 名 形式的模块端 口歹IJ农. 其中 , 棋块 ex1 的峭 口 列表 由三个标识符 a、 b、 z 组成, 它们指明棋块 ex 1 的二个端 口将分别与模块的三个 内 部变量 a、 b 和 z 相连接 , 此时这三个端口将拥有隐式定义的端 口 名 a、 b 和 z. 模块 ex2 端 口 列表中的前两个端口表达式 a[l]和 a[O]是矢盘变盘 a 的两个位, 这表明 ex2 的前两个端口将分别被连接到变盘 a 的这两个位上, 由 于这两个端口 表达式不是标识 符的形式, 所以这两个端口 将没布端 口 名 : 而端口列表中 的第三个端 口 表达式是标识符 z. 它表示模块 ex2 的第τ个端口将与模块内 部变ii1: z 相连接, 同时这个端口具有端 口 名 z. 棋块 ex.3 中岛'J口列点内的第一个端 口 边站式是两个变量 a、 b 的合并 " {a,b} 飞 它表示 棋块 ex3 的第一个踹 口将被连接到变量 a、 b 的合并 " {a.b} 飞 即 该 喘 口 的 高位将被连接到 变电� at 低位将被连接到变盘 b. 由于这个端口 表达式不是标识符的形式, 所以模块的第 一个端口没有端 口 名 : 而端 口歹IJ表中的第二个端口 表达式是标识符 Z. 它表示模块 ex.3 的 第二个端口将与 变 li\: z 相连接, 该端口具有阻式定义的端 口 名 z。 (2) 显式端口名形式 模块端门列表在这种形式下的格式为: ( . <端口名 1> (<揣川.&在i 式 1 > ) , . dil4 l..l名 2> (<局面口我达式 2>). ...._. .<琐i口�> (<峭门衣 达式n>)) 在上述格式巾, 列.<<.巾的每一项都包含扫一个瑞口名和一个端口表达式, 在饰个端口名前 面都要加一个点号 11 " 来表明它是一个端口 名 : 而端口农达式则位于端口名后面的囚括号内。 在这种端口名列表形式下, 列表中 的每一项都说明了一个端口 t 其中 的端 口 名 为该端 1 1 621 鲸 4 擎 ·翩翩跟& 口 指定 了 一 个端 口 名 , 端 口表达式则指明 了该端口与模块内 部的连接关系 . 与隐式端口名 的情况一样, 这里的端口表达式也可以是前面给出的四种端口 表达式形式之一. 在使用了显式端口名形式的模块端口 列表后, 各个模块端 口,都被显式地指定了一个端口 名 , 在进行棋块调用时可以迦过这些端口 名 来指明模块端口与外部信号端子的连接关系。 E 例 4-2) 显式端 口 名形式的模块端 口 列 表. module ex4 ( . in a ( a ) , . inb(b) , . o u t ( z ) ) ; input a , b ; //端口卢明语句 。utput z; / / � n JlJ 明 语 句 endmodule module ex5 ( . il (a [ 1 J ) , . i O ( a [ O J , .out ( z ) ) ; input [ l : O ] a; //端口声明洛句 。utput z ; //端II 卢明 语句 endmodule 在例 4-2 中 定 义 了 两个棋块 ex4 和 ex5. 这两个棋块定义部采用 了显式瑞门名形式的 端口列表。 其中模块e阔 的端口歹IJ表是由三个端 口项构成的, 其中的每一个端口项定义说明了一个 模块端 口 . 第一个端口被取名为 ina, 它与模块内 部变盘 a 相连接: 第二个端口被取名为 inb. 它与模块内 部变量b 相连接: 第三个端口被取名为 out. 它与模块内 部变lil: z 相连接. 模块 ex5 的端口列农也是由三个端口 项构成的 , 其中的每一个端口项也定义说明了一 个棋块端 口 。 第一个 端 口被取名 为 i l . 它与模块内 部变量 a 的第 l 位相连接 : 第气个端口 被取名为 iO. 它与模块内 部变量 a 的第 0 位相连接; 第三个端 口 被取名 为 out, 它 与棋块 内部变1it z 相连接. 模块定义中的端口列表也可以是由显式和隐式端 口 名 形式的端口项共同组成的 , 如下 例所示。 E例 4-3) 由显式和也| 式端口 名 形式共同组成的模块端 口 列哀。 module ex6 ( . i 1 (a) , . i O (b) , z ) input a,b; output z ; endmodu1e 在模块 ex6 中 , 第一个端口项.il(a)和第二个端口项.iO(旧是显式端 口 名形式, 那τ二个端 口 项 z 是隐式端口名形式. 它们的 端 口 名 分 别 为 i ] 、 iO束I z. 模块端 口 列表 中 可 以 出 现 与模块内 部没有任何连接的端 口 项 , 如下面的模块应义: module ex7 ( . data ( ) , .control (ctrl ) , .out (outdata) ) ; 。uput [ 8 : 0 ] outdata; input ctr1; endmodule \ 163\ 在模块 ex7 的 端 口 列 表中 , 端 口 data 所对应的表达式为空, 官表明没有任何一个内 部 变量与该端口相连接. 在模块中也可以 出 现 多 个模块端 口 与 同一 个 内 部变量相连接的情况. 如下面的模块 定义: module ex8 ( . a (ccrlin ) , . b (condout ) , . c (condout ) ) ; input ctrlin; outpuc condout; assiqn condoutactrlin; endmoduel 在模块 ex8 中 , 端 口 b 和 c 对应的端口表达式都是 condout, 这表明这两个端口都与 内 部变·监 condout 相连接. 2. 端口声明语旬 在 瑞 口 列表中出现的各个模块端口还必须 由 " 端 口卢 明 语句 " 来进行端口 方 向 的 说 明 . Verilog 语占中奋如下三种端口卢明语句: • input 输入端口声明语句: • OUtpUl 输 出 端 口 声明语句: • inoul 双向端口声明语句. 端口卢明语旬的作用对象必须是与模块端口相连的模块内部变嚣, 而不能是端口 名 〈 端 口 名 与 内 部变最标识符 同 名 的情况除外). 例 如 , 在例 4-2 中 , 模块 ex4 中 的 端 口 声 明 语句 tI input 8tb; "、 tI output z;" 的作用对象就分别是与三个瑞 n相连接的内部变盘 a、 b 和 z。 这 是 山 于 端 口 名 的作用 〈 在进行棋块调用时) 是作为棋块端口 的标志来实现与外部信 号的连攘, 在棋块内 部这些端 口 名 是不可见的. 模块内部对端口进行的输入输出操作是通 过踹口表达式巾出现的那些内 部变量进行的 〈 这些变最与对j虫的端 口 相 连 ) , 所以在摸块 内 部必须对这些内部变茧的输入输出特性进行说明. 4. 1 .3 模块的调用 本书 1.4.2 节巾已经简述了模块调用的基本概念, 在此将对模块的调用作详细介绍. 战块调用足 Verilog 结构描述 〈结构级建棋〉 的基本方式, 在本门级元件调用 、 开关 级元件调用 和用户 自 定义元件调用 ( 这些概念将在后面的章节中连一介绍 〉 部可以看做特 殊类型模块的调用. 通过模块调用, 一个复杂电路可以被捕述成是由 各级模块像搭积木一 样层层组成的 . 在对一个硬件系统进行的描述中 , 必定持在二rf一个顶级模块, 在 整个硬件 系统描述中只钉这个顶级模块不被其他模块所 调 用 , 而且他各级榄块部将被上一级模块调 用. 在 Ve时log 中 , 模块被调用后就在上一级调用模块内'1=.成 f一个模块实-if1J. 模块实例 代表,ff被调用模块电路结构在调用模块电路内 的一个拷贝. / 164� ••• 1. 模块实例语旬 Verilog 语言中用模块实例语句来实现模块调用 . 模块实例语句的基本语法格式如下: 〈模块名> <参数值列农> <实例名> (<端口连接」是》 对上述格式作如下说明. • <棋块名〉就是在进行模块定义时 C module 语句中 〉 为被调阳模块指定的模块名。 • <参数值列表〉是可选项, 它是 由一些参数值组成的一张有序列表, 这些参数值将 被传递给被调用模块实例内的各个参数. 我们将在后而对这个参数值列表进行详 细讨论。 • <实例名〉是为 本次模块调用 后所生成的棋块实例所取的一个名称, 它可以用 来对 所生成的模块实倒进行唯一标识. 如果在某个模块 内 出 现 了 多 次模块调用, 贝IJ各 次调用所 指定的实例名 必须不相同 , 在同一模块内不能出现两个相同的实例名 . 同一个 上级模块可以对多个下级棋块进行调用 , 也可以 对一个下级棋块进行多次 调用. 这样就会在同一电路中生成多个一模一样的电路结构单元, 这些电路结构 4i元就是每次模块调用后生成的模块实例. 所 以 为 了 对这些相同的电路结构单元 进行区分, 为它们所取的模块实例名应该是各不相间的. 实例名和模块名的区别 是: 模块名标志着不同的模块, 用来区分电路单元的不同种类: 而实例名则标志 着不同的模块实例 , 用 来区分电路系统中的不同硬件电路单元. • <端口连按表〉是由外部信号端子组成的一张有序列哀, 这些外部信号端子代表着 与模块实例各端口相连的外部信号. 所以〈揣口连接农〉指 明 了 模块实例端口与外 部电路的连接情况。 如果需要在萄前模块 内 对同一个被调用模块进行多次调用. 则可以采用如下的模块实 例语句格式. 〈棋块 名> <参数值列表 1> <实例名 1 > ( <实�J名 2> ( <端口连接我 2 > ) , ...... 〈参数值列表 n> <实例名 n> ( <端口 这援农 n>J ; 在上面的棋块实例语句格式中 = 叫卖块名〉指明了 被训用的是哪一个模块. 格式中的每一行 被称为一个实例项, 各个实例项之间用逗号隔开. 每个3比例项实现了被调用模块的一次调用。 整条模块实例语句实现了对同一模块的 n 次调用, 将在调用模块巾'仁成 n 个模块实例. 各个实 例项对应的实例名必须是各不相同的. 下面举例说明模块的调用来l模块实例语旬的使用. E例 4-4) 模块的调用. 11 低层憔块 : l I i集tjtt定描述 了一个由与非门构成的触发器电路 module ffnand (q, qbar, preset, c1ear) ; 队165\ d:�崎 岖应用部耐实倒刷 。utput q, qbar; /1电M*输出 峭 1 1 ,111归 inpu巳 preset, clear; Iltl!.�各输 入峭1 1 卢 19J I l ì局用 verilog 内部l!�4>:元仲 nand nand 91 (q, qbar , preset ) , 92 (qba r, q, clear ) ; endmodule //商店镇块z /!对{反应筷块叶'触发; 帆赂的仿真测试LlH'� 吨'敬叫1位 "测试凳" 一-e-T st Bench) modu1e ffnand wave; wire ou tl , out2; / / 电路输出俯 号,UIYl reg 1n1 , 1n2; /jrl1ili的驱动交f,1.)1J I�J parame巳er d - 10; /I�用低居模.tk ffnand, Jf�得其命名为 11 ff11 , I"J时捕;Elf-输入输出端1 I 与(fi \; �均 f的i1:t卖 ffnand ff (out1, out2 , 且1 , in2 ) ; /IJ主义 电路的仿真激励波形 initial begin id in1 • 0 ; in2 - 1 ; �d 1n1 • 1 : Hd 1n2 • 0 ; 邮d 1n2 • 1 : end endmodule 在例 44 rf1.低层模块 币land 是 由 两 个 与 非 门 构成的带顶置和市苓控制的触发器电路. 在高层的仿真测试模块 ITnand wave 中 . 对该触发器电路模块 ITnand 边 行 了 调 用 . 对仿真. 模块进行仿丘,的输入输出波形如l 图 牛 l 所尽. 阅 4- 1 例 4-4 银块的ω1输入输出制5 在回 4-1 巾 , f占号�;ì� f oUll 与触发器 ITnand 的端口 q 相连, out2 与端口 qbar 相连. inl 与端口 pr臼et 柑迹. in2 与 端 口 c1ear 相连. 从仿真时在IJ 1 0 到 20. inl ( 对j也 presel) 为低 电干. in2 ( 对I,ÿ_ c1ear) 为商也干. (1:此期间 oUll ( 对!但 q ) 输出 J:J高1也可7.. out2 (对应 qbar) ll: oU11 的 反 向 输 出 • J)j低Il! '1'-; 从仿真时刻 20 到 30. inl .和I in2 部沟尚IU 、1" , 在此i阴阳 out 1 ;fn out2 侃降职值不变: 从伪贞,时刻 30 到 40. inl {扯峰高Il.!. 平. in2 变为低 山、11-, 在此 JVI问 oUll 变 为 低 电 干 , Ir;Jfl1 out2 也变为i13 也 可40 11I1儿触发器 ffnand 的�斗H功能为: preset 为f页程控制端 门 , 低1l.!.'f1.有效; clear 为tti苓抑制主出 口 , 低电平有效: 叶1 preseI 和 clear 都 为自电 子时, 输111 {,圳、?原的不变. / 166/ 2. 模块调用时的端口对应方式 在进行模块调用时, 模块实伊j语句中的�口连接表〉用 来指明模块实例端 n 与外部电 路的连接情况。 端 口连接衣是由被称为 " 外部信号端子 " 的一些表达式组成的 , 其中的各 个信号端子将分别与对陆的端口相连接. 在端口连接表巾 , 可以采用如下两种方式来指定模块实例端口 与外部信号端 f之间的 连接关系. ( I ) 端 口 名 称关肤方式 在瑞 口 名称关联方式下, 端 口连接表的棉式为: ( . <峭口名 1> (<倍。峭于 1>) , . < 端 口 名 2> (<俯号揣子2>) ,…叶 . < 峭 U 名 n> (<ît� IJ'��,lf n>) ) 其lþ的信号端于可以是下面列出 的任何一种 类型: • 帘蒋器型变盘或线同型数据标ill符: · 矢最数据的某一位: • 矢7在数据的某儿位: · 前述儿种类型的 合并 ; · 数值表达式 〈 输 入端 口 )0 在端口名称关联方式下, 端口连接表内 �式地指明了 与毛球个外部信号端子相连的模块端 门名. 即d击口名 1>所代衷的端口将与〈信 号端子 1>相连接, <1lfd 口 名 2>所代表的端口将与〈 信号端于 2>相连接, … , 所代哀的主;lt口将与〈信号:'�;;ð (" n>相连接。 下ÚlÎ举例说明. E例 4-5) 端 口 名称关瞅的端 口 对应方式. module onebit full adder ( a , b , cln, $ , cout ) ; //1 位�bnl必 input a,b, c�n; 。utput 5 , cout; assign 5-(a^b) ^cin; //本位和1输111 s assign cout= (ð&b) I (b&cin) I (a&cin) ; 11进位输fll cout endmodule m。dule twobiES-full-addeE (dataO , daEa1, caZEY-In , zesult, ca ZE Y-OUE } J •., 汇 i-l。nnupPE�UPEU[争l」C[:a、4OE--]ZOYTAd- aiztneaJSOu,d ata1; ., . 。utPU←EW C aZ E v- out, ' wire wl; 选 , ,, 纺 位 果 输 输 入 山 craezszuvle -t- n ,,f ,Jf ?iw 进 优 输 山 山 earzy - o u 11两条板块实-W1ji吾句, 所采用的端口对应方式是蝙 口 名称关联方式 onebit full adderUl ( . a (dataO (01 ) , . b (datal ( 0 ) ) , . cin (carry_in) , . $ (resul t [ O ] ) , .cout (wl) ) ; 。nebit full adderU2 ( . a (dataO [ l ] ) , .b (datal [ 1 ) ) , .cin(wl ) , . s (result [ l ] ) , .cout(carry_out ) ) ; endmodule \ 167\ 如 图 4-2 所示为顶层模块 twobits full adder 的逻辑结构图。 dataD[1 d嗣1(1 oneb�_fuI_aded r.UI OI1ebl_l luI_aclôer.U2 臼"'1_0咀 剧团tl ,0] 阁 4-2 例 4-5 顶层模块 twobits_fuU_adder的逻辑结构阁 第一条模块实例语句中的端口连接表指明了模块实例 U 1 各个端口与外部信号端子的 连接如下: 模块端口 a → 信号端子 dataO[O] 模块端 口 b → 信号端子 datal [0] 棋块端 口 cm → 信号端子 car可-in 棋块端 口 s → 信号端子 r臼ult[O] 棋块端口 cout → 信号端子 w l 第二条模块实例语句中的端口连接表指明 了模块实例 U2 各个端口与外部信号端子的 连接如下: 模块端 口 a 棋块端口 b → 信号端子 dataO[I] → 信号端子 data 1[1] 模块端 口 cm → 信号端子 w l 模块端 口 s " -+ 信号端子 result[ l ) 模块端口 cout → 信号端子 carry_out 在端 口 名称关联方式下, 模块端口和信号端子的连接关系被显式地说 明 , 因此端口连 接 表 内各项的排列顺序对端 口连接关系是‘没有影响的。 例 如 , 我们可以用如下两条模块实 例语句: 。nebit fu�l adderUl ( . ci n ( carry in) , . a (dataO [O] ) , .b (datal [O] ) , .s (resu�t(O] ) , .cout(wl) ) ; 。nebit_full_adderU2 ( . cout (carry_out) , . a (daLaO [ l ) ) , .b (datal [ l ] ) , .cin(wl ) , . s (result [ 1) ) ) ; 来替换例 4-5 巾 的两条模块实例语旬, 这两组模块实例语句描述的都是相同的端口连 接情况, 在端 口 名称关联方式下 , 如 果 端 口 连接 表 内 某一项的信号端子是默认的 ( 在 "信号端 子" 位管处只出现一对空括 号 tt ( ) "), 贝。这一项 的 端 口 名 所代表的端口 将处于悬电状态。 例 如 , 下面这条模块实例语句l 护 : 1 1 68λ 。nebic_full_adderUl ( . a (dataO ( O ] ) , . b ( ) , .c幻l (carry_in ) , . s (resulc ( O ] ) , . co u c ( wl ) ) ; 端口连接表第二项内 的信号端子是默认的 〈赞括号), 这种悄况表明端口将处于恶空状态。 如果被调用筷块的某个端口不具有端 口 名 ( 该端口 处于无名状态 ), 则对该板块进行 调用时不能采用端口名称关联方式, 而只能采用下面将介绍的 " 端 口 位置关联方式". (2) 端口位置关联方式 在端口 位置关联方式下 , 端口连接表的格式为: (<信号端子 1>,<信号端子 2>, . . . . . .,<销号端子 n>) 其中, 各个 "信号端手" 可取的类型与前面讲述的 " 制 口 名称关联方式 " 时的的况相同。 在瑞口位置关联方式下, 各个信号端手按一定的次序出现在端口连接表巾, 这些信号 端手将与在 〈摸块定义时给出 的 ) " 端 口 列 衷 " 中 出现的各个模块端 口 依 次连接: 封11 口 连 接表中的第一个信号端子将 与 端 口 列 表 中 的 第一个模块端 口 相连接. 第二个信号端子将和 第二个模块端口相连接, 依此类推。 例 如 , 我们可以将例 4-5 中 的两条樵块实例语句改写 为 如 下 两 条 ( 采用端口位置关联 方式〉 模块实例语句: 。nebic_fu11_adder Ul (dataO [ O ] , dacal [ O ] , carry_in, resu1 c fO ] , wl ) ; 。nebiE-full-addez U2 {dataO [ 1 1 , datal I 1 1 , w1 , result [ 1 1 , cazry-OUE } J 在定义模块 onebit-fulLadder 时给山的端口列主更是 "(aAcitfIAcout)", 这是一个隐式端 口 名 形式的喘 口 列表, 1ι 为模块 orlebit--fuiLadder 定 义 了 五个模块端 口 . 'ι们被隐式地命 名 为 端 口 名 "a"、 Ub"、 "cin"、 US" 和 "cout". 这样 , 上面这两条模块实例语句内的各个 信 号端F将根据它们在端 口连接表中出现的次序依议与棋块端 口 气"、 "b"、 "cin "、 U s " 和 U cout" 相连接. 第一条模块实例语 句 内 的 端 口 连接表指明实例 U I 的端n ua"、 "b"、 "cin"、 tI S'" 和 Ucout " 将分别与外部信号峭子 "dataO[O] "、 U data1 [0]"、 " ca町 in"、 " result[O] "、 "w l " 依 队;相连. 第气条模块实例语句内的端 口连接农指明实例 U2 的端口 气"、 Ub"、 "cin飞 lts " 和 "cout " 将分别与外部信号端子 "dataO[ 1 ] "、 Udatal [l]"、 " w l "、 " resuIt[1 ]"、 "四πy_out" 依 次相连. �:端 口连接�巾某一项的 " 信 号端 f " 默认, 则表示这一项所对应的模块端 口 未被连 接。 例如下面这条棋块实例语句= 。nebit ful1 adder Ul (dacaO r O ) , dacal [ O J . , resu1c ( O] , wl) ; 简要注意的是. 不能在同一个端口连接表内混合使用名称关联方式和优贸关联方式. 比如下面这条模块实例谓句是非法的: 队 1 69\ 。nebit-full-addertJl {dataO {O} , data1 { 0 1 , .b {carry-in} , . s {result [0 1 } , .cout{wl} } J 其巾, 端 口 连接表内的第 1 项和第 2 项是位置关联方式的表项: 而 其中 的 第 3、 4、 5 项则是名称关联方式的表项. 3. 模块调用时的阵列调用方式 当?后要对同一个模块进行重复性的多次调用时, 我们可以采用如下所示的阵列调用方式= 〈被调用筷块名> <实例阵歹IJ名> [阵列在边界: 阵列右边界] (<峭口连接着(> ); 其 中 , " 阵列为:边界 " 和 "阵列右边界" 是两个常盘表达式, 它们用来指定调用后生 成的模快实锣IJ 阵 列 的 大 小 . E例 4-6] 使用阵列调用 方式的模块实例语句来进行结构描述. module data_change (out,ina, inb) ; input [ 3 : 0 ] ina,inb; 。utput [ 3 : 0 ] out; wire [ 3 : 0 ] out,ina, inb; nand nand_arre y [ 3 : 0 ] (out,ina, inb) ; / /陈列调用方式的筷块实例语句 endmodule //对 " 与 你 门 " i挂行n模的行为描述模块: nand module nand (ina, inb, nand out ) ; input ina, inb; output nand_outi assign nand_outc句 (ina&inb) ; endmodule 上述模块的l句:列调用方式语句"Eland nmd-町ey[3:0] (out,ina,inb);"等价子如下几条语句: nand nand_a rre y [ 3 1 nand nand_arrey [ 2 ] nand nand_arrey { l ] nand nand_arre y [ O ] (out [ 3 ] , ina [ 3 ] , inb[3 ] ) ; (out [ 2 ] , ina (2 1 , inb [ 2 ] ) ; (out [ l ] , in a [ l] , inb [ l ) ) ; (out [ O] , in a ( O ] , inb [ 0 1 ) ; 山上例可见, 在对同一模块进行较多次数的调用时, 采用阵列调用方式将会带来很大 的方便. 4 . 1 .4 在模块调用时对参数由3更改 当某个模块被另一个模块调用后, 调用模块可以对被调用模块内的参数值进行更改, 囱 此可以通过更改参数值来对被调用模块实现的功能进行控制. 比如夜们可以设计一个加法器 模块, 该加法器的位数由模块内的参数指定. 这样, 在对这个加法器模块进行调用时, 我们 只市要在调m时进行一下参数更改, 就可以将同一加法器棋块作为 8 位、 1 6 位、 32 位等任 12位数的加法器加以使用。 在棋块调用时对参数值进行更改可以通过下述两种方式实现: /170/ 第 4 1民 · 使用带有参数值的模块实例语句: · 使 用参数 重定 义语句 ( defparam 语 句 ). 1 . 使用带有参鼓值的模块实例语旬 在这种方式下, 模块实例语句内就包含有新的参数值, 这些新参数值是在 " 参数值列 表" 中 得到指定的. 参数值列表在模块实例语句内是可选项, 它 是 由 若干参数值按一定次 序组成的一张有序列衰, 其格式如下: • (<参数值1>, <参数值 2>, ...... , <参徽血{ n>J 上边格式中指明的各个〈参数值〉将分别被传递给被调用模块实例 内的各个参数 , 在只 包含一个参数值的情况下 , 括号可以省略, 即采用 "#<参数值> " 的格式. E例 4-7) 利用带有参 数值的模块实例语句进行参数值传道. 11一个 4 X 4 位乘法银. 操作数的位数囱参数WIOE1 、 WIDE2指定 module mUltibits_multiplier (datal ,data2,out) ; parameter W!DEl帽4; parameter WIDE2皿'1; input[WIDEl- l : O ) datal; input [WI DE2-1 : 0 ) data2; output [WIDEl+ WIDE2 - 1 : 0 ) out; assign out-datal-data2; endmodule /1一个 8 X 8 位采法糕 , 跑 j 过调用筷块 multib1ts_mult1plier 并修改其参数 WI DEl �¥I WIDE2 11米实现 module e1ghζ bits_multlplie r ( a , b , result) ; input [ 7 : 0 1 a , b ; output [ l S : 0 ) result; multlbl ts_mu 1tiplier * 凹 , 8 ) U l 恼 , b , result) ; I I?接参数值列表的模块3比例谓句 endmodule 11一个 1 6 X 8 位乘法 糕 , 温过调用;隧块 multiblts_multiplier �修改其参量� WIDEl 和 IIWIDE2来实现 module multiplier_16_8 (a,b, result) ; 1.nput [ 1 5 : 0 ] 8 ; input [ 7 : 0 ] b; output [ 2 3 : 0 ) result; mu�tibi ts_mult1p1ier # ( 1 6 , 的 U2 ( a , b , result ) ; I I1W参数值歹j淡的秘块�fg11语句 endmodu1e 在 模 块 multibilS_multiplier 中 参 数 WIOEl 和 WlDE2 部 被 初 始 化 为 4 : 在模块 eight_bilS_multiplier 中 参 数 WLDEl 和 WlDE2都被修改为 8; 而在模块 muJtiplier_16_8 中 , 参 敏 WLDEl ;和 WTOE2 分别被修改为 1 6 和1 8. \ 171 \ 使用带参数值的模块实例语句来实现参数传边时, 参数值列表中各个参数值的排列次 序必须与被调用模块中各个参数得到说明的次序保持一致, 并且参数值和参数的个数也必 须相同. 如果只希望对被调用模块内的个别参数进行更改, 所有不需要更改的参数值也必 须按对应参数的顺序在参数值列表中全部列出 〈原值拷贝)0 2. 使用 参戴重定义语旬 (de阳ram 语旬〉 在进行模块调用时更改被调用模块参数值的第二种方法就是利用 Verilog HDL的参数 茧定义语句一-defparam 语句. 参 数 重 定 义 语 旬 的 语法 格 式 如 下 : defparam <参敛名 l>�<参数值 口, 〈参数名 2>=<参数值 2>, 〈参数名 n>=<参数值n>i 上面格式中的每一行可 以实现对一个参数值的修改. 其中 : • defparam 是参数重定义语句的事引只: • <参数名〉用于 指l归被修改的是哪一个参数 , 该参数 名 必 须采用分级路径名 的形式, 因为在棋块兰} 队;结构中, 只有分级路径,名形式的参数才能唯一标识某个棋块实例 中的某个参数: • <参数值〉就是〈参数名〉所对应的参数将被贼予的新参数值。 E 例 4-8) 使用参数 重 定义语句实现模块参数值的更改. /1一个 4 X 4 位采法棒, 操作数的位数 也参敛WIDEl、 WIDE2 指定 module mulcibits multlplier (dacal, data2, out) ; parameter WIDE1=4 ; parameter WIDE2-4; input (WIDEl-1 : 0 1 datal; input(WIDE2-1 : 0 1 data2; output [WIDE1+ W1DE2-1 : 0 ] out; assign out=datal*data2; endmodule /1一个 8 X 8 位乘法禄, 边过调用筷块multibits_multiplier 并修改某乡数 WIDEl 和 WTDE2 //来实现 module eighc_bits_multiplier ( a , b , result) ; input ( 7 : 0 ) a , b ; 。utpu t [ 1 5 : 0 1 result; defparam Ul.WIDE1-S, //参虫!l ífcm义讯句. x.f 3比例 01 内 的多数{fU挂�r修改 01 . WIOE2-8; multibits_multiplier 01 怡 , b , result ) ; /I模快实例珩旬, 也成模j� 实 {9IJ 0 1 endm.odule /1 72 1.. .4擎 在例 4-8 的模块 eight_bits_multiplier 中 , 使用 了一条参数量定义语句: defparam U l . WIDEl=8 , U l . WIDE2"'8; 这条 defparam 语句包含两项 ( 两行), 中间用逗号隔开 ( , )。 这两项分别对两个参数 进行了参数值修改。 · 第一项 " U l .WIDEI=8 飞 指定的 参数名 为 ttUI.WlDEJ ", 它是一个分级路径名形 式的参数名 , 它表明需要进行修改的参数是当 前模块 eight_bits_multiplier 中包含 的模块实例 U I 内 的参数 "WIDE I 飞 · 第二项 lt U 1 .WIDE2=8 ", 指定的参数名 为 " U I.WIDE2", 它表明需要进行修改的 参数是当 前模块 eight_bits_multiplier 中包含的模块实例 U l 内的参 数 " WlD四"。 3. 两种参搬值更改方式的区别 在采用第一种参数值修改方式 〈 使用带有参数值的模块实例语句 〉 的情况下, 由于需 要在模块实例语句中列出新的参数值, 而模块实例语句只能对下一级模块进行调 用 , 所以 这种方式只能对本模块直接调用的下一级棋块内 的参数进行修改, 而不能对非本模块直接 调用 的模块或更低层次模块内的参数进行修改。 在采用第二种参数值修改方式 〈 使用参数重定义语句〉 的情况下, 由 于 def加aram参数 重定义语句是独立于模块实例语旬的, 并 且 由 于 defparam 参数重定义语旬内的参数名是一 种分级路径名形式的参数名。 所 以这种参数值修改方式可以用来实现更为灵活的参数值修 改操作。 下面举例说明. E 例 4-9) defparam 参数重定义语旬的灵活使用。 module top ( … ) .. .. .. ... parameter PARA 202; medium Ol (ou�, inl,in2 ) ; defparam Ul . U 2 . 1?ARA_1=3; •••••• endmodule module medium (out , i n l , i n 2 ) ; . ... .. bottom U2 (a, b , c ) ; ... . . . endmodule module bottom ( a , b , c ) ; •••••• parameter PARA_l=l; •••••• endmodule I / TJ)!屁棋块top //参数 PAAA 2 切如值为 2 //棋块实伊l语句, ;P;J用中问层筷块 medium //参蚊虫定义i否句 //巾闷启模块 medium //棋块实例语句, 调用底层秘Î_Æ bott:om 1/1夜�2:悦.tR bo巳t:om //参赞� PARA 1 的创始值为 1 队 173\ 帽Dl 应用毒摩设计实倒精瑞 module change_parai defparam top. PARA_2=10; endmodule //独立模tl! //参敏蓝定义再 i 1 J' 在例 4-9 巾 . 定 义 了 四 个模块: top、 medium 、 bonom, change_para, 其巾底层模块 bottom 内 定 义 了 一个参数 PARA-l , 其初始值被指应为 1 : 顶层模块 10p 内 定 义了一个参 数 P成A 2 , 其初始参数值被指定为 2 . 在顶层模块 top 内 有一条参数重定义语句: "defparam U l .U2.PARA_I=3;飞 其中的参 数名为 " U l .U2.PARA_1 ", 它所代表的目标参数足: 战居模块 bottom 的实WIJ U2 巾 的 参数 " PARA_1 飞 井且这个实伊� U2 足出现在 " 顶JJ棋块 10p 所 引 入的 中间丢j 帧块 medium 的实 例 U ) " 中的底层模块实例。 这样在顶挝模块 top 中实现 了对底层模块实伊:J U2 内参数的修 改. 对应的参数 " p队'A, 阳 RAJ- 1 " 将拥有新参数值 勺 " γ 3 .. 在独立棋块 chang阱e_para 中也有一条参数茧i应豆义语句: "defparam top.P成AJ= l O; ", 其中的参数 名 为 " top.P,础AJ 飞 它指明 了进行参数值修改的 目 标参数是模块 top 巾的参数 " PARA 2 飞 由于模块 change_para 和模块 10p 是相瓦独立的两个模块, 这样就实现了: 在 一个模块中定义某个参数, 而在另外一个独立模块巾对该参数进行参数值里改. 在这种情 况下, defparam 参数1[(定 义语句巾包含的参数名必须是从m层开始的一个 "金用分级 名 " 〈 比如 , 参数名 " lop.PARA 2 " 中 的第一个域 ; " top" 必 须是一个顶琴j 棋块名 ). 4.2 门级建模 门级建棋是指调用 Ve州og 内 部 自 定义的基本f J级元件 〈或者用户 白 定义基本元件〉 米对硬件电路进行结构1lt�地. 门级建模方式采用的是 a种特殊的模块调周ñi(o 此时所调用的根块是 驰而og 内 部 预先定义好的革本门级元件或者用户 自定义的幕本元什, 在这种建校方式下硬件电路将被 捕述成出一组基本门级元件的实例组成。 由于一个数字电路系统战终是由一个个迪机 f J 喋开关组成的 , 所以削逻辑fJ 单元和i开 关单元来对硬件电路的组成结构进行描述是敬在现的. 在 Verilog中可以将取本门级元件分为两太炎, 一类是 驰而og 语古本身 n惜的 , 它是 将一些常用 的基本逻辑门 单元包含到 Verilog 居 占 内 部 , 称为内盟幕本f J级元付: 另外一 类是根据不同J+J户的甫粟, 由用户 自 己定 义 , 定义þ:f以后可以像内置基本门级元件一样被 用户调用, 这类基本f J级元件称为用户 向 定义基本元件 (UDP). 4.2.1 内置基本门级元件 Verilog HDL 内舍的基本f J级元件奋 14 种 , 也抽: and ( 与 门 〉、 nand ( 与非f J )、 or (.uJU ] )、 nor (或非 f J ) 、 xor ( 异或 门 〉 、 xnor ( 异成斗在 f J ) 、 buf (缓冲器〉、 not ( 非 门 ) 、 / 1 7 4 1.i 第4擎 蜡幅画队\ buftfl ( 高电平使白色缎冲器〉、 bufifO ( 低 电平便能缓冲器件〉、 notift ( 高 电半便能非 门 〉 、 notifO ( 低电平使能非门〉、 pullup ( 上拉电阻〉、 pulldown ( 下拉电阻). 它们可以分成如下 四类加以说明. · 多输入门 : and、 nand、 or、 nor、 xor、 且nor. · 多 输 出 门 : buf、 not. · 三态 门 : bufifO、 butifl、 notifO、 notifl o · 上扰、 下拉电阻: pullup、 pulldown. 1 . 基本门组元件的调用 基本门级元件的调用是通过门级元件实例i1f句来实现的, 这种实例语旬的基本泌法格 式为t 〈门级元件名> <驱ï;lJ强度 说明> f ( <Î J级延u.j' lìt>) <实伽l名> ( 端 口 连 接 农 ) : 对上述语法格式作如下说明. • <1' J级元件名〉: 就是前面列山的 Verilog HDL 内舍的 1 4 种平本门级元件类咽巾的 任意一种, 它用于指明被二与前榄块调阔的是哪一种基本l' J级元件. • <驱动强度说明〉: 这一项是可选项, 它的格式为: 《对高rl:!.平的驱动强度>. d'tfl民[I:!.平的驱动强度》 〈驱动强度说明〉用 来对本次基本f J 级元件调用所引入的门级元件实例的输出端驱动能 力加 以说明. 这是闵 为: 在约 构建棋方式下, 一条连线可能会由多个前级输出端同时驱动, 该连线最终的逻辑状态将取决 于各个驱动端的不同驱动能力, 因此有必要对元件实例的输出 驱动能力进行说明. 对王门级元件, 驱动强度分为对高电平 (逻辑 1 ) 的驱动强度和对低电 严 〈逻制 0) 的驱动强度, 国此�ï;Jl 强1St说明〉部分由〈对高电 平的驱动强度〉和〈对低电平 的驱动强度〉这两种成分组成. 其中的捋一种驱动强度成分可以是 supply、 stTong、 pull、 weak 和 highz 巾 的 某一个等级。 |对此有如下关键字llJ现在〈驱动强度说I�]>rr: supply1 strong1 puU 1 weak1 higbz1 supplyO s衍。ngO pullO weakO higbzO 上IÜÎ第一行中.&/�<对自电 平的驱动强度〉的 五个缚在段, 第二行表示〈对低电乎的驱动 强度〉的丑个等级. 在基本门级元件实例语句的4区动强度说明>'1 1 , <对市 电 平 的驱动强度〉 和〈对低rl:!. 平 的驱动强度〉这两个成分布括号 内 的 前后位柑可以丑快, 比如: and(strongO,weak l) AND_I(out,in l ,in2); and(w四川 ,strongO) AND_2(out.in l ,in2); 其 巾 1]1 入 了 两 个 与 门实伽j AND-l 和 AND_2o 这两个实例拥有相同的输出SHj驱动强 度, 高『包半输出强度为 weak, 低 电 'T7.输出强应为 strong. 如 果 基 本 门 级元 付 实 例 活 句 中 的〈驱qJ 强 J且 说 明 〉部 分 被 省 赂 , 则 默 认 的 驱 动 强 度 为 ( strongO,strongl ). \ 175\ 应用疆靡黯懊制制 • #(<门级延时篮>): 这一项也是可以默认 的 , 它说明了信号从门级元件实例的输入 端流动到输出端时所经历的延迟时间妖皮 . 其中〈门级延时:lìÞ是由若干个延时值 组成的, 与: 它只包含一个延时值时, 其外部的囚括号可以省略, 比如: and # 1 0 AND_3(out,inl,in2); 其 中 引 入了 一 个 与 f J实例 AND_3 , 其 中 的 "例。" 部分指定了对应与门实例的门级延 时量: 实例 AND-3 的输入端到输出端的延时吐为 10 个时间单位. 当这部分默认时, 延时盘被默认为 00 请读者注意, 上述对门组元件实例的门级延时地进行指定的方式与 4.1.4 节中讲洁的对模块 参数值进行修改的第一种方式 (使用 带有参数值的棋块实例语句 〉 是相似的。 这两种情况 下, 对应的实例语句中部出现了 "# (<数值且对" 部分. 该部分内 容在模块实例语句中代 表模块参数的新参数值: 而在门级实例语句中 则代农了 门级元件实例输入输 出 端 口 间 的 门 级延时量。 在进行模块调用时不能采用像门级元件调用那样的方式指定延时值 〈 只能利用 specify 块结构来指定延时值); 而在进行基本门级元件调用时又不能像模块阳用那样对参 数值进行修改 ( 只有用 户 向 定义元件才能有参数值), 所以 上述的两种情况不要发生棍淆. • <实例名只 是为本次元件调周后生成的门级元件实例所取的一个名称. 与进行模 块调用的悄况不 同, 在进行基本门级元件调剧时, <实例名〉可以节略。 在默认〈 实例名〉的忻况下, Verilog 编译系统将 向 动 以 "<元件名x实例j书号> " 的形式为 门级元件实例取名. • ( 端 口连接农): 与模块实例语句中的端口连接表类似, 但是在进行基本门级元件 调用时只能采用端口位置关联方式. 而且与基本f J级元件实例各个端口相连的信 号端子只能是宽度 为一位的表达式或变值标识符. 如果需要对同一个在"þ.门级元件进行 多 次调用 , 则可 以采用如下所示的一种元件实�J 语句格式。 〈门级元件�> 〈驱动强度说明> # ( Oî最口连接农 1) I 〈实�J名 2> ( 端 门在 i 援农 1) I …... 〈实例名n> ( 端 门主 i 披衣 n) ; 上面这条元件调用语句对〈门级元件名〉所代点的JitË本门级元件进 行 了 n 次调用, 分到 生成了 由〈实例 名 1 > 、 … 、 〈实例名 n>标志的 n 个门级元件实例。 该调用谓句各行内 的 " 端 口 连接表" 分别说明 了 对内元件实例端 口 和 外 部倍号端子的连接关系。 其 中 的 每一个实例 项要用逗号分隔开. 例如, 下面的研句: a nd -1·l ''nu-1·l s 』← Z 。AAnNNgDD­- o''句,4‘ 倒{(。。euua←?b凰LL"句咱咱,忐忐‘, , } #1 n1 η3 n2 n4 / 176h '自 4 . 对 and ( 与 门 〉 进行了两次调用, 分别生成了取名为 AND-1 和 AND-2 的两个元件实例。 需要注意的是, 在采用上述门级元件实例语句格式的情况下, 元件调用后所生成的各个元 件实例将具有相同的门级延时盘 〈 都由语句格式中的<1'1级延时量〉进行指定〉 和输出驱动强度 〈都由语句格式中的<.动.1Jg 强度说明〉进行指定〉。 比如前面例子中所生成的两个实例 AND 1 和 AND 2 都将具有由 (strongO,w田kl ) 代表的驱动强度和 10 个时间单位的门级延时盘. 由上面的描述可以看出, 基本门级元件的调用与榄块级建模巾的棋块调用非常相似, 两者最大的区别在于: 在对内 置基本门级元件进行调用时可以指定驱动强度和门级延时 盘, 而在模块调用时不能包含这些内容. 2. �输入门 内置 多输入门包括 6 种门级元件: and、 nand、 or、 nor、 xor、 xnor. 这 6 种逻辑门的 特点都是可以有一个或多个输入, 但只能有一个输出. 这些多输入门的元件模型可以表示为: <1丁级元件名> (<输出端口>,<输入端 口 1 >,<输入端口 bJu---,〈输入端 口 n> ) 其中的〈门 级元件名〉就是上面给出的六种多输入门名称之一, 在,端 口 列 表 中 出现的第 一个端 口是输出端口, 其后是多个输入端 口。 表 4-1 列 出 了 上述 6 种多输 入 川 的逻辑其值衰, 具中 第一行和第一列代表着两个输入 端的输入状态, 而其他的农项代表着输出端的输出状态. 亵4-1 and、 nand、 。r、 nor、 xor、 xnor 元件的真值褒 and 。 x z 。 。 。 。 。 L '‘ 。 L。 E J f .、 ‘ .一 _ 3‘ 3‘ 'L 飞『 '且 3‘ ‘' z 。 '‘ J‘ x nand 。 x z 。 。 ‘J 3‘ 丁民 '‘ 3‘ ‘3 z 3‘ 且 3‘ 。, 。 。 。 3‘ '‘ z 3‘ 2‘ z 3‘ '‘ x 然 x 3‘ � 气1 77\ nor 。 3‘ z 。 。 x '‘ 。 。 。 。 x x 。 只 3‘ z x 。 3‘ 2‘ ‘Jor 。 x z 。 。 x x 。 x ‘3 3‘ 3‘ x j‘ 3‘ z x J‘ 3‘ 3‘ XI10r 。 x z 。 。 x 3‘ 。 ‘' 1‘ x 3‘ 3‘ 3‘ 3‘ z x 3‘ 1‘ ‘3 由 表 4-1 可见, 多输入门对输入逻辑状态 1IX 1J 和 Itz" 的处理方式是相同的: 多输入 门的输出状态不会是 "z"。 对多输入门进行调用 的元件实例语句将采用如下形式: 〈多输入门元件名> <驱动强度说明> t ( < 1丁级延时量>J <实倒名> 〈输入信号端子 1 > , <输入信号端子 2 > , … … , <输入信号端子 n>) ; ( <输出信号端子>, 在上述元件实例语句格式中 , 与 多输入 门元件输出端相连的外部信号端子 ( IlP<输出 信号端子》 必须出现在端口连接表的第一项中, 与多输入门 的各个输入端相连的外部信 穹·端子则只能出现在端口连接表的后面几项 内 。 这些输入信号端子将依次与 多 输入 门 的 各 个输入端相连接。 倍号'端子和元件端口之间的连接关系是采用 " 端 口位置关联方式 " 来确 定的. 比如下面几条语句: and Al(out l , inl, in2) ; or 02 ( a , b , c , d ) i xor Xl (x_out , p l , p2 ) ; 分 别 对 多输入门 and、 or 和 xor 进行了调 用 。 其 中 第一个元件实例 A l 的输出端被连接 到信号端子 out l , 两个输入端分别被连接到信号端子 in1 和 in2: 第二个元件实例 02 的输 • 出 端被连接到信号端子 也 气个输入端 口 被分别连接到信号端子 b、 c 和 d: 第三个元件实 例 汩 的输出端被连接到信号端子 x-out, 两个输入端分别被连接到信 号端子 p l 和 p2 . / 1 78h 3. 多输出门 内 置多输出 门包括两种fJ级元件: buf和 ooto 这两种逻辑门的共同特点是: 允许有多个输出, 但只能有一个输入. 这两种多输出 门的元件模型可以表示为: 〈门级元件名> (<输出端 口 1>, <输出峭 II 2>, … … , <输出销 口 0>, ……〈输入城U > ) 其 中 . <1'丁级元件名〉是元件名称 buf 和I not 之一: 端 口 列表中的最后一项是输入端 口 , 前面的其余梢 口 为输出端 口 . 表 4-2 给 出 了 这两 种 多 输 出 门 的逻制其值表。 袋 4-2 buf 和 not 元件的真值亵 har 。 。 x 3‘ 自由' 。 。 3‘ 3‘ z 3比 z 3‘ 从表 4-2 可以看出, 多 输 出 门 buf和 not 对输入状态 气 " 和 " z " 的处理方式是相同 的: 并且这两种元件的输山状态不会是 "z飞 对 多 输 出 门 进 行 调 用 的 元件 实 例 语 句 将 采 用 如 下 形 式 : 〈 多输出门元件名> <驱动强度说明 > • (< 门级延时fiÞ) <实例名 > 〈输出信号柑子 2>, … … , <输出信号瑞子 n>, <输入信号端于> ): (<输I:tl 们 可 端f 1>, 在上述格式中 , 端 口 连接 表 中 出现的最后一个信号端子将被连接到多 输 出 门 的 输 入 端 , 而排在前面的其余信号端子将 与 多 输 出 门 的各个输出端依次相连. 信 号端子和元件端 口之间的连接关系是采用 "端口位置关联方武 " 来确定的. 例如下面的语句 , 分别对非门和缓冲器进 行 了 调J+J 0 not NOT 1 (out1,out2 , in ) ; buf BOF 1 (bufou � 1 , bufout2 , bufou�3,bufin ) ; 其中, 第一个元件实{9IJ NOT_J 的两个输出端分别被连接到倍号端子 outl 和 out2. 其 输入端被连接到信号端子 in: 第气个元件实例 BUFJ 的三个输出端分别被连接到信 号端 子 bufoutl 、 bufout2 和 bufout3 . 其输入瑞被连接到信号端子 bufm. 4. 三态门 内 置三态门包括四种元件 : bufi仰、 bu1if1 、 notiro 和 notifl . 这山种逻辅门f.H来x-j主态 驱动器建模, 它们都有一个数据输出端、 一个数据输入端和一个控制输入端。 这儿种专态 门的特点是: 它们的数据输出端可以实现二态输出 . 其元件模型可以表示为: 队179\ <1丁级元件名> (<数据输出榄口>, <数据输入端 n>, <控制输入端口》 其中 , <门级元件名〉是前面给出的四种元件名称 bUfifO、 bufifl 、 noti1O 和 ootifI 之一: 端 口1tl表中的第一项是<数据输出端口>, 第二项是�据输入端口>, 最后一项是ζ控制输入端口λ 表 4-3 给出 了这四种三态门的逻辑真值表. 其中的第一行是控制输入端的各种状态, 第一列是数据输入端的各种输入状态, 其他的表项代表着数据输出端的输出状态. 真值表 中的某些表项是不确定的, 比如, ItOlz" 表示输出状态既可能取 O fïr也可能取 z 值. 褒 4-3 bufifO、 bufTf1 、 notifO 和 notif1 元件的真值褒 bufif1 。 数 。 z 撞击 z 输 '‘ z 入 z z 控制输入 3‘ z 。 Oh Ol't I /z IIz 3‘ 3‘ :‘ '‘ '‘ x bufilO 数 。 黯 输 J‘ 入 z n011n Iiiι币 数 。 据 输 '‘ 入 z 。 。 ‘J ‘' ,。 z z z z 但制'自入 3‘ z z o/z 。fz z IIz JJz z '‘ 3‘ z 3息 x 飞FL「J r fmll输入 - .,- 、 、 3尾 z IIz IIz 。 。,Jz 。但 3‘ J‘ 3‘ J‘ x x notilO 搜1M笛入 。 2‘ z 数 。 z 11ι JJz � 。 z 。h ωz 电自 3‘ 3‘ z '‘ '‘ 入 1 x z 3‘ 3‘ 从表 4-3 可 以 看 出 , 这儿种三态门元件的输出端可以被驱动到尚阻状态 ..z" ( .(1:特定 的控制j输入状态下)0 1 180;" • .4擎 对 于高电平使能缓冲器 bufifl , 若控制输入为 1 . 则输入数据被传送到政掘输出端: 若控制输入为 0, 则数据输出端处于高阻状态 "z;'0 对 F低电乎使能纽扣p器 bu日而, 若控制输入为 I , 则数据输出端处于高阻状态 "z": 若控制输入为 0, 则输入数据被传送到数据输出端. 对 f而 电平使能非门 notifo, 若控制输入为 I , 则数据输出端的逻辑状态是输入的 " 逻 辑非飞 若控制输入为 O. 则数据输出端处于高阻状态 IIZ飞 对 F低电平便能非门 notifo, 若控制输入 为 ) , 则数据输出端处于高阻状态 "z"; 若控 制输入为 0, 则数据输山端的逻辑状态是输入 的 "逻辑非". 对二态 门 进 行 调 用 的元件 实 例 语 句 具 有 如 下 所 示 的 格 式. 〈元件名> <驱动强度说明> # (<门级延时盎>) <实i9�名> (<输出倍号端 f>. <输 入信号·岛的 子>, <控制倍号端手>): 下剧的四条元件实例语句分别对四种二三态门元件进行了 调用 . bufifl B F 1 ( data bus, mem data, enable) ; bufifO BFO ( a , b , c ) ; notifl NT1(out , in,ctr l ) ; notifO NTO(addr,a bus, select ) ; 且;巾, 第一条语句对高 电 平便能缓冲椿 bufifl 进 行 了 调 用 , 引 入了 该元件的一个实例 BFl . 在i 实例的数据输出峭与信号端子 data-bus 相连: 其数据输入端与信号 端 f mem_dala 相连: 扎:控制输入端 号信号端子 enable 相连. 第二条语句对低电平使能缓冲器 bufifO 进 行 了 调 用 , 引入该元件的一个实例 BFO. 该 实例的荣立据输出端与信号踹子 a 相连: 其数据输入端与信号端 下 b 相连: 其控制输入端与 信号端 f c 相连。 第二条语句对高电乎使能非门 notifl 道行 了 调用, 引 入 了 出元件的一个实伊J NTI . 该 实例的数据输出端与信号 端 f- out 相连: 其数据输入端与信号端子 in 相连: 其控制输入端 . 与信号Jiw r ctrl 相连. tl1V4条语句对低电、F使能非门 oOli.ro 进 行 了 调 用 , 引 入 了在i 元件的一个实伊� NTO. 真i 实例的激据输出端与信 号直;插手 addr 相连: 其数据输入端与信号端f a-bus 相连: 其控制输 入端 与信号端子 select 相连. 5. 上拉、 下拉电阻 J'.机、 下拉电阻包括两种元件: puUup 和 pulldown. 上拉II.!.阻和下拉电阻这两种门级 元件占�UH-f一个输出g;� u 1(11技合·输入端口 . l:忧I'I:!.�且 将输出 且为 ) , 下拉电阻将输出 贵 为 0。 对 1...扰和下拉电阻进行调用的元件实WíJ谓句具有如下的语法格式. <驱动强度 说IPl> <实Ø1J名> (<输出信号椅子>J ; 在 1-.述棉式巾 , tiu n 连接表内 只能山现一个信 号端 于 ( 输山信号端于) , 谣 的 号 引起 子 队181 \ ., 应用理原设计实71J!Á糟讲 将被连接到元件实例的输出端 口 。 由 于上拉电阻只能输出逻辑状态 1 . 下拉电阻只能输出 逻辑状态 O. 所以在进行驱动强度说明 时 ( 在需要进行说明的情况下), 对 pullup 元件只需 指出对高电平的驱动强度, 而对 pulldown 元件则只需指出对低电平的驱动强度. 下面两条语句就分别对上拉电阻和下拉电阻进行了 调 用 。 pullup ( supplyl) 01 (power ) ; pulldown (pullO) 02(gnd ) ; 其中, 第一条语句引入了 上拉电阻的一个实例 U J . 该实例的输出端被连接到信号端 子 power; 该输出端的驱动强度为 supply l o 第二条语句引入了 下拉电阻的一个实例 U2. 该实例的输出端被连接到信号端子 gnd; 该输出端的驱动强度为 pullOo 6. 门组延时的说明 门级延时反映的是信 号的变化从门级元件的任一输入端口流动到任一输 出 端 口 所 经 历的传输延时. 门级延时可以分为如下儿类。 · 上升 延时: 表示信号从 " 0气 气" 或 " ZH 状态变化到 " 1 " 状态时受到的门传输 延时. · 下降延时: 表示信号从 " 1 飞 (, x" 或 "z" 状态变化到 "0" 状态时受到的门传输 延时。 · 截止延时 : 表示信号从 " 0"、 " 1 " 或 llX" 状态变化到 41z" 状态时受到的门传输 延时. · 割不定态的延时 : 表示信号从 1( 0" 、 " 1 " 或 "z" 状态变化到 ,( x" 状态时受到的 门传输延时. 由于多输入门 ( and、 nand、 町、 nor、 xor、 xnor) 以及多输出门 ( buf、 not ) 的输出习" 可能是高阻态 "Z", 所以 多输入门和多输出 门这两类元件没有 "截止娃时" 这类门级延时. 只能有 " 上升延R'1""、 " 下降延时" 和 " 至IJ不定态的延时" 这三种门级延时种类。 对于三态r J (butì:fO、 bufifl 、 notifO 和 notif1 ). 由 于这类元件的输出可以取所有四种 可能的迦辑状态 "0"、 " 1 飞 气 " 和 (' z 气 所以三态门这类元件可以具有全部四种门级延 时种类。 对于上拉电阻 (pullup) 和下拉电阻 ( pulldown ), 由于这两种元件没有输入端 口 , 所 以不存在从输入到输出的延时。 因此这两种元件不能有任何形式的门级延时说明。 在对门级元件进行调用时, 可以对元件实例 的门级延时进行说明, 这是通过元件实例 语句 内 的 " 门级延时说明" 部分来实现的. 如 果 " 门级延时说明" 部分被省略, 贝IJ门级延 时被默认为是苓延时。 元件实例语句 内 的 " 门级延时说明 " 部分的格式为: /182� . '目 4 1民 # ( 门 级延ll1iit ) " 门级延时盘" 是由一个或多个延时值组成的 , 它可以有如下两种表示方式: · 基本表示方式: • "最小延时"、 " 典型延时 " 和 "最大延时" 的表示方式. 下面我们将分别对门 级路时量的这两种表示方式进行讨论 , 街要注意的一点 是 : Verilog HDL 中的所有延时盘都是以 " 单位时间 " 表示的, 单位时间与实际时间的关联可 以通过'timescale 编译指令来实现。 ( 1 ) 门级延时量的基本表示方式 在这种表示方式下, " 门级延时蠢" 内 可以包含 l 个、 2 个或 3 个延时值, 下面分别对 这三种具有不同延时值个敬的情况进行说明。 ① 当 门级延时量只包含一个延时值时, 即 当 门级延时说明部分是 "制" 形式时 〈 其 巾 d 是一个给定的延时值). 延时值 "d" 将同时代表元件实例的 " t:升延时值"、 " F降延 时值"、 " 截止延时值" 和 "重IJ不定态的延时值" ( 在多输入门或多输出 门情况下没有 " 到 不定态的延时值")0 比如, 在元件实例语句 Itnotifl #20 U 1(oul,in,ctrl);" 中 , 门 级 延目时f说明部分丛i á " #但20" 其中门级延时1it "2却0" 内只包含了一个延时值 (ω20ω)0 这表明元件实例 U I 的所有樊嘲门级 延时都是20 个单位时间. ② 当 门级延时量包含两个延时值时. I1P当门级延时说明部分是 "# ( d l . 但 ) " 形式 时 ( 其中 d l 、 但 是两个给定的延时值). 元件实例 的 "上升延时值" 将由延时值 "dl " 指 定: "下降延时值" 将 由 "d2" 指定 : 而 " 梅 止延时值" 和 " 到不定态的延时值 " 将 rll "dl " 和 1(d2" 中的较小者指定. 比如, 在元件实例谓�J " notiO # ( 10. 20) U2(out,in,ctrl);" 中 , 门级延时说明部分是 1( # ( 10, 20)". 其中门级延时量 " ( 10, 20)" 内包含了 两个延时值 ( 1 0 和 20)0 这表明元 件实例 U2 将具有 10 个单位时间的 "上升延时 " 和 20 个单位时间 的 " 下降延时", 而它的 " 截 止延时值" 和 "到不定态的延时值" 将 是 10 束1 20 巾 的较小值 〈 即 10 个单位时间). ③ 当 门级延时量包含三个延时值时, l1P当门级延时说明 部 分 是 U # ( d l . d2, d3)" 形式时 〈 其 中 dl 、 d2 和 d3 是三个给定的延时值 ) , 元件实例的 "上升延时值 " 将 出 延 时 值 "dl " 指定: "下降延时值" 将 由 11d2" 扣定: "截止延时值" 将dJ "d3" 指定: 而 " 到 不定态的延时值" 将由 "d1 "、 "d2 " 和 "d3 " 中 的较小抨指定。 比如, 在元件实例语句 " notiO # ( 10. 20. 30) U3(oUl,in.c位1);" 巾 . f J级延时说明部 分 是 " # ( 10. 20. 30) ", 其巾门级延时 ;在 " ( 10. 20. 3 0 ) " 内包含了三个延时值 ( 10、 20 和 30). 这表明元件实例 U3 将具有 10 个单位时间的" 1工升延时 "、 20个单位时间 的 " 下 降延时" 以及 30 个单位时间 的 " 截止延时", 而宙的 "到不定态的延时值 " 将是 10、 20 和 30 中 的较小值 〈即 10 个单位时间). \ 183\ 应用程原设if实1JI跚讲 。) It最小延时"、 " 典型延时" 和 "最大延时" 的表示方式 除了 基本表示方式外, 门级延时量还可以采用一种更为主i杂的表示方式, 在这种表示 方式下, 门级延时盘中 的每一项将由 " 段小延时 "、 " 典型延时" 和 " 最大延时 " 气个值来 表示. 这种方式下的 " f J级延时盘" 将具有 直11下格式: # (dl_min: dl_typ: dl_m缸. d2_min: d2_typ: d2_m邸, d3_min: d3_typ: d3_m阻〉 在k述格式中 , 门级延时盘包括 了三部分 (dl 、 d2 和 d3 -:'部分), 这飞部分之间用逗 号进行分隔: 而每一部分又是由三个延时值组成的, 这些延时也之间用 胃 号分隔. 在这三 个延时值中: mm表示最小延时, 可p 表示典型延时, max 表示局大延时。 在采IW主种i<尽 方式时, 每一类门级延时 〈 七升延时、 下降延时、 截止延时军11至1)不定态的延时 〉 将相应地 由 " 地小延时"、 "典型延时" 和 "最大延时" 三个延时值共间确定. 衣 4-4 给出 了 这种衣示方式下各类门级延时值的确定方式. 、 l二 斤 ii1ø.t 下降�ø.J 到rJ;f、定念的短时 量� Ii:Un.t 褒4-4 备樊门级延时值的确定方式 .1、Jl附 典型延时 dl min dl_'YP d2 min d2 IYP min(dl_min. min(dI_ typ. d2_min. d3_m丽】 d2_ typ. d3_ ty币) d3 min ω,_typ .大锺IH dl max d2 m ax mi叫d1.mu. 位,mM. d3- mM} d3 max 比如, 在元件实例谓句 " notif1 #(2:3:4,5:6:7.1 :3:4) U4(out,in,ctrl);" 中 , 门级延时说明部 分是 It#(2:3:4,5:6:7,1:3:4)飞 其中的门级延时-I,t "(2:3:4立6:7.1 :3:4)" 包含了三部分的延时值 "2:3:4"、 .. 5:6:7" 和 It 1 :3:4". 这表明元付实伊1) U4 将具有如1< 4-5 所示的门级延Mtm兄. 上11必时 F降,li01 到j不定;s{l!J,li8-t 很11:锺胃.1 褒 4-5 元件实例U4 所具有的门级延时 '量小延时 A4l延时 2 3 5 6 3 3 』匾欠盖面的 4 7 4 4 �撑使用哪种 延时 〈 最小延时 、 典型延时或最大延n.t ) 足仿点运行n.t的一个�J!页 , 在 们可以通过设置该选项来选择使用 某一种延时 . 相应的仿真运行过程可 以看做iit挝好情况 分析、 典咀俯况分析和战坏忻况分析. 7. 门组建模举例 前面已经对各种内 咒基本f J级元件及它们的调用方法进行 f介绍, 下山将综合使用这 吨元件米进行门级建模。 / 1 84/ 如困 4-3 所示是一个 l 位全加器, 其 中 Ila in"、 " b in" 是数据输入端, " c in" 是进 位输入端, " SJUt" 和 (1c_out" 分别是和输出端和进位,输出端。 例 4- 1 0 给 出 了这个仓加器 的门级描述. ab-lnll 〉〉-:=Jh ι协 -J·:1t \ J c i闹 '-" I I c,_., 崎 阳"_- "\�" . 01师' T手;二-户J 飞C out R" i> U 阳'』f〉s-M 因 4-3 I 位全加吉普逻鹅框图 E 例 4-10) I 位全加器的门级建模. rn。dul e fu ll-adder tc-。ut , s-OUE , a-in, b-in , c-in} J output c-out, s-。utJ input a_in,b_in,c_in; wire wl,w2,w3; paramet.er AND_DELAY=2 ; parameter OR_DELAY=2 ; parameter XOR_OBLAY=4; and • AND DELAY A l ( wl , a in,b i n ) ; and f AND DELAY A2(w2,b in,c in) ; and ' AND DELAY A 3 ( w3 , c in,a in) ; 。r • OR DELAY Ol (c out , w l , w2 , w3 ) ; xor • XOR DELAY Xl (s out,a in,b in,c in) ; endmodule 在例 4-10 所示的结构描述模块 " full-adder,, 中 , 与 门 "and" 得到了三次调闸 , 分别 生成了三个与门实'{9iJ "A 1 "、 "A2" 和 "A3"; 或门 uor" 得到了一次调用, 生成了一个或 门实例 " 0 1 "; 异必门 " xor" 得 到 了一次调 用 , 生成 了一个异或门实例 " X l "。 各个实例 之间的连接关系山各 条元件实暂IJ语句 内的制口连接表共同确定。 下面再来看看如图 4-4 所示的一个 2-4 译码器, 其中 "aO" 和 "a l " 是译码代码输入 端, "enable" 是便能控制端, 而 "yO"、 " y l "、 " 民 " 和 " y3" 则是 4 个译码结果输出端. 该译间糟的输入输出其值及虫"表 4-6 所示• . 队 185\ '由 入 .1 .。 。 。 。 。 enable 80 a1 褒 4-6 2-4 译码榻的输入输出真值理是 • øs y3 y2 yl 。 ' 回 .. • 。 .1 。 。 "''.'- OUT1 ,。 。 y3 '恤3由 1T1 y2 NA2:0UT1 y1 '恤, 。 町, YO 阁 4-4 2-4 译码榄逻钝挺111 E例4-11 ) 1 位 2-4 坪码器的门级建模。 module decoder (yO, yl, y2, y3, aO, a 1 , enable) ; output yO, y1 , y2 , y3 ; input aO,a1, enable; wire w1,回2; not ' (1 , 2 ) N 1 ( w l , aO ) , N2 (w2 , a1 ) ; nand ' ( 4 , 3) NA1(yO, enable , w l , w2 ) , NA2 (yl, enable , wl , a l ) , NA3 ( y 2 , enable , a O , w2 } , NA4 (y3, enable, a O , a l ) ; endmodule /186/ . 4 1但 在上例给出的模块 " de∞der" 中 , 通过各条元件实例语句 引 入 了 : · 两 个非 门实例, 即 "N1 " 和 "N2 ": • 四个与非门实例, 即 " NA l 飞 "NA2"、 " NA3 " 和 "NA4"。 这 些 门 级 元 件 实例 之 间 的 连 接 关 系 由 各 条 实 例 语 句 中 的 端 口 连 接 表 共 同 确 定 。 最后再举一个对 " 0 型主从触发器" 进行门级建模的 Verìlog 结构描述模块的例子。 {9IJ 4-1 2 给 出 了 它 的 门级描述。 E 倒 4-12) D 型主从触发糙的门级建模。 module d_flop ( d , c l k , c l r , q , g二bar) ; input d, clk,clr; output q, q_bar; wire wl,w2,w3,w4,w5,w6,d bar, clk bar; nand tlO NA1 (wl,clr,d, clk) , NA2 ( w 2 , c l k , d bar) , NA4 (w4,w3,w2,cl r l , NA5 (w5,w3, clk bar) , Nλ6 (w6,w4, clk_bar) , NA8 (q←ba r , g , w 6 , clr) ; nand ,119 NA3 ( w 3 , w l , w4 ) , NA4 (q,时5, q_bar ) ; 伽 U UM 唱罚·,&‘ 、牛 -K pH n not od UO N d Nω -、A huar'd bA­bar ' c n . c。 4.2.2 罔户自定义基本元件 ( UDP ) Veri10g HDL 语言中 除了 自 带 的 内置基本门级元件或开关级元件, 还为用户提供了 自 己进行元件定义的方法, 也就是下面将介绍的用户 自 定 义基本元件 ( UDP: User Oefined Primitive). UOP 元件的定义是通过真值表的形式来进行的, 可 以 用真值表来描述组合逻 辑 UDP 元件和时序逻辑 UDP 元件的逻辑功能. 用 户 自 定 义元件一旦定义好后, 就可以像 调用 VeriJog 内 置基本元件一样来对它进行调用 了 。 1 . UDP的定义 UDP 的 定 义 是 由 一 个 独 立 的 定 义 模 块 构 成 的 , 该模 块 由 关 键 词 " prìmitive " 和 "eodprimitive" 界定, 其语法格式如下t pr:irnitive <元件名称;. (<输出瑞口名>, 输入端口名1>, <输入揣μ名 2>, ……, <输入端口 名 n》 J \ 187\ 噩黯雹摩设i十实部精读 输出端 口 樊型说明 (output) i 输入编 口 类型说明 (input) i 输出端寄存纷变量说明 (reg) ; 元件初始状态说明 (initial) i table < table 表项 1>: < table 表项 2>: ...... < table 袤JW n>: endtable endpr主m主tive 对上述语法格式作如下说明。 • UDP 定 义模块不能出现在其他模块内 . UDP 定义模块和其他模块具有相同的语法 结构地位 , 它的定义必须独立于其他模块结构成分。 所以 UD.P 定义模块必须出现 在其他模块之外, 同时它也可以出现在独立的文件中。 · 在 UDP 定 义棋块的第一行 , 关键词 句rimitive" 标志着定义模块的开始: 其后 出 现的〈元件名称〉是为被定义 UDP 元f阳 t f取的一个名 字: 后 面出现的端口列表指明 了 UDP 元件的输入输 出 端 口 , 该端口列表由若干个端口组成, 其 中 只能有一个输 出端 口 , 并且该输出端口必须是端口列表中的第一项, 而 UDP 输入端 口 数 目 可 以 是一个或多个, 一般对时序的 UDP 最 多 允许奋 9 个输入端, 对组合电路的 UDP 最多允许有 10 个输入端. 必须注意在定义 UDP 元件时所有输入端 口和输出端口 都只能是 1 位的标盘·. • It输出端口类型说明 " 是对 UDP 元件的输出端口进行说明, 这和普通模块定义中 的输出端 口 说明一样是通过关键词 Itoutput " 来进行的, 比 如 : output out: 就说明了端口 out 是一个输 出 端 口 。 • 11输入端 口类型说 明 " 是对 UDP 元件的输出端口进行说明, 这和普通模块定义中 的输出端口说明一样是通过关键词 (( input" 来进行的, 比如: input a , b : 就 说 明 了 端 口 a 和端口 b 是两个输入 端 口 。 • tI输出端寄存器变最说明 " 是在对时序逻辑 UDP 元件进行定义时, 为 了对输出端 口 寄有,苦苦变量类型进行说明而引入的. 寄存器变量用于描述时序电路 UDP 巾 的 内 部状态. 要注嚣的是只有在被定义的元件是时序逻辑元件时才能将输出端口定义 成害存器类变盘 。 寄存器变量说明用关键词 11reg" 实现, 比如: reg out: /188� 第4. 翩翩翩队\ 就将 UDP 输 出 端 口 out 定义为一个寄存器变量。 • "元件初始状态说明" 也是在对时序逻辑 UDP 元件进行定义时引 入的. 它的作用 是对时序电路上电时刻 ( 即 0 时刻 〉 的初始状态进行定义 , 只允许有 "0"、 11 ] "、 II X" 三种逻辑值, 不允许出现高阻态 "z", 默认为 " x " 态。 元件初始状态说明用 initial 过程块来实现, 比 如 : initial 。ut�x: 就将时序逻辑 UDP元件的初始状态定 义为 气"。 • 由关键词 .. table" 和 "endtable" 界 定 的 多 个 table 表项构成了 UDP 元件定义棋块 内 的一个输入输出 真值表。 在 table 衰项中只允许出现 "0"、 " 1 "、 .,x" 三种逻辑 值, 不允许出现商阻态 "z飞 组合电路 UDP 定 义模块和时序电路 UDP 定义棋块 内 的 table 表项格式是不同的o table 表项构成了 UDP元件输入、 输出 以及内部状 态 〈 时序逻辑电路情况〉 间的一张 "逻辑其值表"。 对不同逻辑功能的 UDP 元件 进行定义时的差别将体现在不同的 table 表项描述上。 • 关键词 11 endprimitive" 出现在定义模块的末尾, 它标志着 UDP 定义模块的结束。 下面i举例说明 UDP 的定义. E 例 4-13) 将 4 选 1 多路选择器定 义成 UDP 元件• l · 旧 L L 鸣,- -m A鸣 p -l m Eiv m 叫 -1 μ &3 n ·l n , eJ 口 3 , , t Z ­., 品自咱 c "凰← z ei气 ‘,饨 ., c Ouqp旧 t 0 M ; --n put ·川 L i n n 3 2 i i' J ' u ta ble n 1 c E t L -4 r 、 ,, J // in l. 日 2 // 司 tr m川 脚 in3 in4 c巳7:11 ctr12: 。ut 沌释行, 用于保证表项中铃顶的正确 《U o ? ? - ? nu nu l ? 9 · ? un 、4 ? 0 ? - ? nv ? 19 · ? nu 、.hu· ? ? 0 ? -- •. •. .• .• .. ? ? 1 ? ··1 nu ? ? 9 · 0 T‘ .. 、aa、 ? ? ? 1 ,. .• •. . en dta 巾 -u . ., nu., 咽,‘., 《U., 唱4., AU., 咱A., n『u4., e n d 归OL mit ·1 w 在例 4-13 中 , 输入端 口 中 的 inl-in4 为 四 个输入端 口 , ctrl l 和 ctrl2 为选通控制信 号: 当这两个值为 00、 0 1 、 10、 I I 时将分别逃迦 in1 - in2, in3、 in4 信号到输出端口 out. 例 中 的 table 表由 8 个表项组成, 它们构成了该 4 选 i 多路选择器的逻辑真值表。 表项中的 � 189\ 应用疆摩设ìt实倒精讲 " ? " 字符代表不必关心相应变量的具体取值, 即它可以是 0、 l 或 Xo 垃意不能将控制信 号定义成一个 2 位的输入端 口 , 即不能采用如下定义方式: E例 4-14) 错例. pimitive mux4_1 (out , i n1,in2, in3,in4, ctrll , ctr12 ) ; out.put out; 1nput 1n1,in2,in3,in4; input [ 1 : 0 ] ctrl: /1雕英. 在 UDP定义中端口只能是 1 位的标最 table 111n1 i02 in3 in4 ctr1 。 ? ? ? 00 1 ? ? ? 00 ? 0 ? ? 01 • out .. 0; .. 1; . 0; ? 1 ? ? 01 ' 俑, · n u ? 10 , 内,. 1 ? 1 0 9• ,.帽 ? 0 1 1 , ? ? 1 11 endtable .. 1; .. 0; .. 1; . 0; .. 1; endprimit.ive 2. 组合逻辑电路UDP 对组合逻辑电路的UDP 元件的描述相 当 于 直接把电路的逻辑真值表搬到 UDP描述的 table 表 中 。 组合逻辑电路 UDP 定义时的 table 表项的格式为: 〈输入 1 逻辑值〉 ξ输入 r 迦锦倪〉 …… 〈输入 n 逻 i 辑值> : <输出迎籍值〉 对于上述表项格式, 必须注意: · 各输 入 、 输出逻辑值只能是 0、 l 、 x 或? 中 的一个, 不能取高阻态 "z飞 · 输出端 口�E primitive 定义语句的端 口 表项中列第一的位置 , 而输出逻辑值在 table 表项内则是位于最后一项。 · 在-:&项中 要用 空格分|嘀开不同的输入理辑值, 各个输入端 口在 table 表项中的排列 顺序必须与它们在 primitive 定义语句中端口表项内 的排列顺序保持严格一致。 • table 表项中的输入部分与输出部分之间要用一个冒号隔开。 • 为 了 明 确观察输入输出相互关系和各项排列顺序是否正确, 通常在 table 表项的第 一栏中插入一 条注释语句 , 比如例 4- 1 3 中 的注释行 : // in1 in2 1n3 in4 ctr11 ctr12: out UDP 元件的逻辑功能是 由 UDP 定义模块内关键词 II table " 和 IIendtable " 之间的 table 表 的 内 容所决定的, table 表相当于构成了 UDP 元件输入输出的一个真值表。 在进行仿真 / 190 1.4 . 4 J民 剿崛蹦跳\ 时, 当 仿 真器发现 UDP 的某个输入发生改变时, 将 会 自 动迸入 table 衷于吃找相匹配的 table 表项, 再把查到的输出逻辑值赋给输 出 端 口 . 如果在 UDP 定义棋块的 table 表巾找不到与 当前输入相匹配的 table 表项, 贝IJ输出将取不定态 " x 飞 因此, 在进行 UDP 元件描述时, 应当将尽可能多 的输入状态没置到 table 哀项中. 以 设 计一个一位的全加器为例 , 表 4-7 是它的本位和与ill忧的逻辑 真值表, 由 于一个 UDP 元件只允许有一个一位的输出 . 所以要分别应义两个 UDP 元件来实现全加端的水位 和与进位. 把它们的真值及分别移植到l两个 UDP描述的 table 哀巾, 就得到 了 例 4-15 所示 的全加器的UDP描述。 褒 4-7 全加精本位和与迸位的逻锦真值袋 CID • 。 。 b SIII' 。OUI 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 E例 4-15 ) 全加器的 UDP 捕挫. 剧 川/h 险 如 山 n 定 义 -- M L -­ pc i U 回 mz r y( e 。 u c n 叫2 b o 川 归tc ou tJ i 叩 川 a 町 b' c i n J t曲 M / h -u i a b .• cout o oo •. 0; o ol 0; o o l 、咆h自E‘a o •. - . 0. 0; 1; - u 《 1 •. 0; e时 甸en E-M 和// E 凶 l 阳 旧h e 1v·山i e U 、 4 咱自牟 .. •0 . 1 . • 1; 1; 1; l刷 u m 定 4 」 白泸 - - M c -l PE iU t J t 趴 m 回 ­s川 u m n a b 。川 机 比 sum; \ 191 \ ínput a , b , cin; table /Icin 0 0 0 0 .• 、 l、喃自4& a o b •. o o1n·& .• •. 1 l o u '·· nu •• .• o '·-· - nu .• •. l 1 .. sm oJ -J -J oJ lJ oJ oJ --J endtable endprimitive 在例 4-15 中的 table 表没有考虑到输入为 x 时的情况, 因此在某个输入为 x 时 , 仿其 器找不到对应的 table 表项, 输出将为 cout=x, sum司。 而实际上对于进位 ∞ut 而言, 只 要三个输入项 ( cin、 a 和 b) 中有两个值为 1 . 则不管第三个的值是什么 (0、 1 :或 川. cout 一定为 1 : 反之, 如果输入中有两个为 0, 贝IJ cout 也一定为 0。 为 了表示出进位的这一恃 征, 可 以 在 cout 对应的 UDP 定 义 table 表 内 用 " ? " 来替代第三个值对应表项, 得到例 4-16 的定义描述. 【例 4-16) 考虑了输入状态 Ilx" 后的金加器的 UDP 描述. //进位的 UDP定义 primit主ve carry ( cout, cin, a , b ) ; output cout; input:. a , b, cin; table /Icout 对应的表项, 比例 4-1 5 的情况有所稍简 I/cin 0 0 ab o 9· ? nu •. cout •. 0 ; .. 0 ; 9 1 1 9 。。 1 4 ,. 9· 、.• 1 、,‘ .• .• .. •. 0; 1; 1; 1; endtable endprimitive 3. 时序逻辖电路 UDP 与组合逻辑电路相 比, 时序逻辑电路元件的输出 除 了 与 当 前的输入状态有 关 , 连与时 J子元件本身 的 内 部状态有关。 对时序逻辑电路 UDP进行定义时的 table 表项格式为: 〈输入 1 逻辑值> <输入 2 逻钝值〉 … … 〈输入n 埋辑值> : < 内 部状态> : <输出逻辑也〉 / 192� 第 4 . .唰翻除\ 与组合逻辑 UDP 的定义一样, 时序逻辑电路 UDP 定义模块中各个输入踹 口 在 table 表项中的排列顺序必须与它们在 prirnitive 定义语句中的端口表项内 的排列顺序保持严格 一致: 在表项中要用空格分隔开不同的输入逻辑但. 时序逻辑电路 UDP 定义时的 table :/<.项格式与组合逻辑电路 UDP 的我项格式的不同 之处在于: · 表项中 多 了关于元件内 部状态的描述. · 要用 两个 自 导分别将输入逻辑值部分 与元件 内 部状态 , 元件内部状态与输出逻辑 值部分隔开. · 在构建 table 表项时要把元件内部状态对输出的影响考虑进去. 时序逻辑电路元件可根据触发万式分为电平触发 与边沿触发两类. 它们对应的 table 表项格式虽然都是上面给出的格式 , 但是 table 衣项巾输入输出信号可取的状态在两种电 路类别下是不同的. ( 1 ) 初始化状态寄存器 因 为时序逻辑电路元件有 自 己的 内 部状态, 所以必须有一个吁非器变;在来保持其 内 部 状态。 在时序逻辑电路 UDP 的定义棋块中必须将输 出 端 口 定义为寄存措类型 , 所 以 如 前 所述, 时序逻辑电路 UDP 的定 义模块中必须增加 " 输出端寄梓器变:a说明 " 这一项来将 输 出 端 口 说明成寄存器变盘类型。 在某些情况下必须对 七电时刻 ( 即 0 时刻 〉 元件的初始状态值加以指定. 所以在时序 逻辑电路 UDP 的定义模块巾坯可以增加 " 元件初始状态说明 ", 这一项边过 initai l 过程块 来指定元件上电时刻的初始状态 (0、 l 或 x). 如果该说明项 ( iniri创 语句〉 默认, 贝IJ元件 的初始状态被默认为不定态 ux". ( 2 ) 电'JT.触发时序电路 UDP 电平触发时序电路 UDP 的特点是Jt 内 部状态改变是 由某一输入伯 号Il!.'严触发的 。 比 如一个电平触发的锁存辘, 其真值表示于我 4"8 中. 当官的时钟输入信号 clk 为迦辑 0 时 , 锁在器的状态及输出时刻保持与输入信号. d in 相 同 : 鸣时钟输入信号为逻辑 l 时, 锁存器 进入锁存状态 , 其 内部状态及输出保持不变. 例 4- 1 7 给 出 了 电平触发锁布姆的 UDP描述。 d画 。 O � I 且应 采 0 !!l( 1 且J1 x 褒�8 电平触发锁存稽的逻辘真值衰 dk C圃,aII .." 。 O !或 I 求! x 。 O !llt I 或J x 。 鹏飞刷'叫q) 。 。 E例 4"17 } 电平触发锁存端的 UDP 描述. primitive lacch (q,clk,d_i n) ; \ 193\ 应用噩靡设ìf:实倒黯诩 output q ; reg q ; input clk,d_in; initial q= l ' b O ; tab1e Ilclk d in : current state : next state o 1: 。 • o 0: ' .• 1; .. 0; 1 ?• ? .. _; // ,, _ .. .&示输出状态不变 endtable endprimitive 例 4-17 中&后一个 table 项 内 引 入 了一个新的标记 " ·飞 它的含义就是 UDP 的 内 部状 态 ( 也就是输出状态〉 将保持原有状态不变. 表项中的 " ? " 仍代表 "任意态". 例 4-17 '1'第一个 table 哀项对应于J'.t值表中第二行的情况, 第二个 table 表项对应于其值农rl'第一 行的情况, 第二个 table 农项对应于且也农中第三 、 四行的情况, 此时 cLk-l . 不管输入数 据 d in 的值为多少, 锁有,器将保持原来的状态不变, 处于锁存状态. ( 3 ) 边沿触发时序电路 UDP itl沿触发时J予电路 UDP 的特点是其内部状态的改变是由输入时钟的有效边沿 〈 七升沿 � F降沿) 触及的, 而与时钟1,1号稳定时的输入状况无关。 所以对边沿触发时序逻辑元件的 描述中就需要对输入信号 的变化和变化方式加 以 考 虑 . 仿真器只有在战测到输入信号发生跳 变时才会搜索 table 表得到新的内 部状态值和输出逻辑值. 这样 table 衣项中 的输入逻辑值部 分市要列出输入逻辑值的变化悄况即眺变悄况. 在 Verilog 巾用一对括 号 括起来的两个数字 " (VW)" 的形式来表示从一个状态重IJ另一个状态的变化, 其 中 v 、 w 可以分别是 0、 l 、 x、 ? 之一. 而 (01 ) 代友的就是由 0 到 1 的 l二升沿正跳变. ( 10) 则代表下降站负跳变. ( Ix) 代 -l<. 由 l 往不定态的跳变, ( 11) 代表在 0、 l 、 x 三状态之间的任意跳变. 必须注意 Verilog 中 剧也 在每一条 table 表项巾地多只允 碎一个输入信号处于眺变状态, 比如: / /clk dat:a : stat:e : next. state (01) (10) : 0 .• 0; 点示的这条 table 表项是不允许的, 因为其中有两个输入íJ 号 clk 和 data 同时发生了跳变. 以设计一个 七升沿 丁 触发器为例, 抖其,值表示于我牛9 中 。 clk (01) (01) <01 ) (01) 褒4-9 上升沿 T 触发篷的逻锦真值袤 '也 cu理 rm r s 幅 幅 。 。 。 。 next.,幽 ! 幽 。 。 / 1 9414 .4. =: 二三、 CIk (10) ( 10) ( 10) ( 10) O 战L 1 戚 x O !OC 1 !'i x t_ìD 。 。 ( ??) ( ??) 饵8._. .… 。 。 。 IIIX ... 。 续袤 。 。 页, 但表的第 1-4 行说明 了 在时钟倍 号 clk 发 生Jf跳变时, 若输入 Lin 为 0 则触发器输 出状态保持不变, 而若 clk 正跳变时Lin 为 1 贝IJ触发器状态翻转 : 真值表的第 5-8 行说明 了时钟信号 clk 发生负跳变时, 不管输入 t in 为何缸, 触及器状态保持不变: 真.缸袤的第 9- 10 行说明在时制'信 号 clk 处于稳定值但 t in 发生跳变肘, 触及器状态保持不变: 将其值 衣巾的各种情况加 以简化并移植到 VDP描述的 table 表中可以得到例 4-1 8 所示的上升沿 T 触发器的 UDP描述. E例 4-18】 上升沿 T 触友稽的 UDP 描述. primitive t-tziqge z (q,elk, t-in} J 。utput q; reg q; ìnput t i_n,c1k; tab1e / / c1k t in S -L a 国 ? (01 ) 0 .. 0 (01) 1 •. 1 (01) 1 • • ? (10) 9 •• ? (Ox) 。 •• ? (1x) 。 •• ? ? ( ? ? ) •• q .. 1 ; • ••• 0; •• •• .. endtab1e endprimitive 上例中 table 表中的第 l 项与真值表的第 l 、 2 两行对内l: table 表巾的第 2、 3 项分别 与桌{û表的第 3、 4 两行对应: table 表巾的第 4 项与真值衰的第 5-8 行对应: table <<.巾的 第 5 、 6 项 内 容 的 n 的是为 了把尽可能的定态输山的况考虑地丘。 它们.(1:今; 例 中 的含义是, 吗M钟从 0 状态变化到不应态 x 时或从 l 状态变化剑不定态 x 时 , 如果输入 t-in 为 O. 贝IJ UDP 元件状态及输出逻辑值保持原来的取值不变: table 表中的最后一项与 真值表的第 9、 10 两行对应 , 注意这项是捎述一个 T 触发器所必;后的 , 因 为只要在 table 表 中 出现 了 ·个 含有输入逻辑值跳变的表项, 仿真,器就会对任何一个输入信 号的跳变作山反应, 进入 table 队 195\ 表查找相应的我项, 如果上例中没有这条表项来对敏据输入端 Lin 发生跳变时元件输出端 对应的逻辑取值进行说明, 仿真其.器就将会肉为找不到对应的说明项而输出一个不定态 " 气x " 所以在进行边沿触发时序电路UDP描述时j应j豆E该对每一个输入端发生的任轩何I跳变情况加以考 虑, 并将这些跳变状态以及对应的输出端逻辑状态作为一个 t.able 表项添加到 t.able 表巾去。 为 了 简化 UDP 元件定义模块中 t.able 表项的描述. 以 及 为 了 加 强 table 的可读性. Ve州og 在对 UDP 进行定义时引 入 了 一些缩记符号来描述 table 表项, 这些符 号 列 于 表 4- 1 0 之 中 , 利用这些缩记符号 . �J 4-18 可以改写成例 4-19的形式. ..e. .项籍记符号 。 及 li X . ? b 成 ! B (vw) r�R f�F p !求 F n 1或 N \\I • 褒 4-10 UDP 定义时的缩记符号 )Î! 义 Il 明! 理剿0 逻钳 I 'J4、��革 能JU r'lìi�输入、 输tIl .ll �; 能fHJ�描述编入、 输111岱可 能刷 子描述编入、 始1I1 1J I� '如11状态保持不变 只能用于描述时序逻辑也� UDP 的'由111状态 。 成 I lI.i x (任意态〉 不能用来对编tIl.ilHH苗.t! O !成 1 不能m来对输111边仔描述 输入从逻 i 辑I倪v 变化到边�lHIi w 不能fII来对锦llI.iJ:J lf梢泌. Jt斗'阳J v.w N:. 0.1.)(.1 吗1 的任意4个 于T 价 J' (01). 友,民输入1'l'1.iEi1�变附 不能Jl]来对输IHillfi'拙� 等价1;' (10), �延示输入的负跳交泊 不能JIj米时输111.l1Hi'l越远 (01). (0川、 {XJ} 中的任一个. .&,苟Z输入 确的也含 氧 �的正在是变 不能附来 对电自III.ilH于指巡 <10>. ( 1 川 、 (xO> 中的任二-1', .J(1�f '自入 峭的也含x 恋的负跳变 输 事? 价J' (??>. <<示 入竭 的任愈变化 i .'.j B:!JII来;;ti 输1111庄tr他还 、气 Ii 4';能用米对输 :Il.ilHf战法 E例 4-19】 使用缩记符号后的上升沿 T 触发端的 UDP 描述. primitive t_trigge r ( q , c l k , t_in) ; 。utput q ; reg q; 1nput: t. in, cl k; t:able // clk E r z f E 'l n o- •• s bL ar­ e ? . . l 0 l .. 1 ? 9· •• q •••• 1; •••• 0 ; (?? ) 气, 。 ( ? ? ) .• 『f ,. .. _ ,. endt:able endprimitive /196/ 第4意 翁精翩\ (4) 电平和边沿触发现合的时序电路 UDP 有些时j乎逻辑电路巾 的状态改变既受电平触发, 又受边沿触发. 这种电路称为It.!.平触 及和边沿触发混合的时序电路. 例 如一个带有异步消苓输入和异步世位输入的触友掘, 泊 �和置位操作时要求电平触发, 而触发锵本身却是边沿触发的。 在这种混合触及:形式时序 电路类型的 UDP 定义棋块巾, 稳定 的输入状态和输入信号的跳变悄况都将对元件的输出 和元件内 部状态的改变产生影响. 肉此在进行 UDP 定义描述时而要同时对输入的也走取 值和变化状态加以考虑. 在 table 表项111耍同时包括有稳定输入状态和输入眺变状态 . 例 4-20 描述的就足一个具有异步消零功能的下降沿 D 触及器. E 例 4-20) 具有异 步泊�功能的 下降措 D 触发器的 UDP 描述. pr幻nitive dff ( q , d , clk,clI) ; 。utput q; input clk,clr,d; reg q; initial q=O; table Ild clk clr : state : q 1 1 泊 零情况 ? ? 0: ? 0; 11正常触发 1-"A B; Endmodule 在本例 巾 , 变量 C 是reg 类型, 所以 综合结果为无符号的比较器. 如图 5-12 所石为在 Quartus U下综合的结 果 . 由 于 A 比 B 少一位宽皮, 所 以综合器将 A 扩展成 3 位宽l监〈商 忧补 0). Less1'田l"O 岖句 γ,曲, αn C 1E$lt-怡,咱 因5-12 无符号比绞苦苦馆仆约果 如果程序中使用 integer 变量, 则会综合出有符号关系运算逻辑, 如例 5-8所'J二. 在 Quartus ll 下综合的 RTL 结果如图 5-1 3 所示. E例5-8)有符号比较端. module test(λ, B, C); input [ 2 : 0 ) A, B; 。utput C; \207\ 应用程摩设计实例精讲 reg C; integer S ignedTemp; always @(A or B)begin = SignedTemp -A; C = Si.gnedTemp > B; end endmodule 在妙。 t属sll睛。 19'1'11捕。时'∞. 甜削怦怦怦萨· αJT: C αJIl32..qI I I1�1-'l 芷霄,、"田。"回01 - L.ESS 1r执N 刽X克R 闯5-13 有符号比较吉普综合结果 从圈 子13 可 以 看 出 , 为了实现有符号敬的 比较器 (其他关系运算类似 ), 通常都要先 将无符号数 转换成二进制补码表示的 有 符号数 , 然 后对气迸甘苦j补码进行比较,闺中的 add-O 〈加法器〉 及符号扩展等逻辑完成 了数据格式 的转换. 而 L essTh an-O ( 小于运算〉 单元则 最终实现了 比较功能。 5.7 移位(shi伐〉运算符综合 VeriJog HDL 语言综合器支持左移 (<<)和右移 (>>)运算, 移空的位补0。 移位运 算符右地的 操作数可以是常数 (constant ), 也可以是变盘 ( variabl e), {.口综合的结果都是 组合逻辑 (combinat:oi nal logic)。 如果移位操作次数 是 常数 ,则综合结果仅仅是根据移位次数 将输入变盘简单的连接到 输出变盘。 例 5-9描述了常数 移位运算实 例 , 综合结果 如 图 5-14 ffr/j,-。 E倒 5 -91 常数 移 位运算实例 。 module ConstShi ftOpera'tion (A, C ); input [2:0] A; output (4:0] C; reg [4:0) C; always @(A )begin =C A << 2; end endmodule /208!. 第5. Ve付IogHDl 司lO 圈子14 常敷移位运u综合结巢 从图 5-14 的综合结果可以看出: 变盘 A (3 位〉 直接连接到变母 C 的 高 3 位 , 变量 C 的低 2 位补o. 关于移位运算需要注意的是移位赋值的 源变量和日标变蓝 的位觉不同 的问 题 〈 如本伤的。 可以这样来理解: · 首先 , 将濒变iil:赋值给目 标变iE. 如果源变电位宽少, 贝IJ F1标变旺阿位补 0; 反 之, 对源变吭高位截断赋给目标变且·. · 然后 , 梗据移位 (7(数对目标变盘移位 , 移空的位补 o IìlP可. 如 果 移位次数趋 变链 , 则综合结果为一个通周移位器. 如例 5-10 所尽, 综合结果如国 5 -15 所示. E 例 5-10 】通用移位器 . module GeneralShiftOpertaion(A, B, C); input [ 2 : 0) A; input [ 1 : 0 ) B; output [ 4 : 0 ) C ; reg [ 4 : 0 ) C; always @(A or B) C - A << B; endmodule • d吨d『 14qq 'dq -n 吨A q C[4:0] 自5.15 淄川j移位报踪合纺织 5.8 位选择综合 位选择(bit-selects) 指的是引用一个矢址 ( vector) 的某一位 〈 琪儿仪 ) , !&)(才一个矢 母的部分位赋值. 优选择支持常盘索引(con ts ant inde x), 也支持可 变索引 ( non-const a.nt index )。 例5-1 1描述了?if血�i引的优选撑实例. 虫111组 5- 16所示为其综合tNW:. E 例 5-11 1 常.w:摇号| 位选择实例. module BitSelectl(A, B, C ) ; . \209\ A踊画缸"比 血牺靡酣实俯瞰 input [ 2 : 0 ] A; input. [ 2 : 0 ] B; output [ 2 : 0 ] C; reg [2:0] C; a1ways @(A or B) C [ 2 :0] = (11.[1:0], B [ O ] } ; endmodu1e 因5-16 常量续引位远销综合结果 对F可变索引的位选择操作 , 若位选择出现 在源变量则综合 出多路开关 ( multiple ex r ) : 若位选择出现在目标变量则综合出译码错 (decoder). 例 5- 1 2 描 述了 多路开关的实例 , 在 Qua付出11 下的综合结 果 如 圈 子17 所示. E例 5-1 2】可变索引位选择描 述的多路开关. modu1e BitSe1ect2 (Din, BitSe1, Dout); input ( 3 : 0 ] Oin; input. [1 : 0 ] Bit.Se1; output. Oout; reg Dout; a1ways @ (Din or BitSe1) Oout. ø Oin[Bit.Se1]: Endmodu1e M<<-。 自1lS9(1.. 。r(3. I�t..q l队T吨耳。q Do.且 MJX 阁5-17 可变索引位选择描述的多路开关综合约·果 例 5-13 描 述了可变索引位选择实现译码器的综合实例, 在 Qu ar阳s 1[下的综合结果如 国 5-18所 示 。 E例 5 -1 3 ) 可变索引位选择实现译码棒。 modu1e Bit.SelectDecoder (BitSe1, input. 01n; 1nput ( 1 : 0 ) BitSel; 。utput [ 3 : 0 ] Dout: reg [3:0) Dout; Oin, Oout); 1210� always @ ( Bi巳Sel or Oin) Oout(BitSel] - Oin; endmodule Oec:ola咱 8蝇飞 rv:rxx:回 第5章Veri崎帽兑 阳.t(3ja甜、 阳AI甸徊。、 α:ú(3..0! Dtú问5etch 图5-18 可变黛寻|位主运梯描述的译间端黯含纺织 5.9 条件表达式的综合 条件表达式的语法如下 , 若条件为真则选取表达式 1 , 否则选取表达式 2. 〈条件> ? <友�式1> : <发达式2> 例 5- 14 展示了条件表达式的使用 , 综合结 果如国5- 19 所示­ E例 5-14 1 条件表达式 的使用 。 modu1e ConditionalExpressionl(Oin, C1, C2, Oout ) ; input Oin, Cl, C2; 。ut.put Oout; A assiqn Oout - (Cl C2) ? Oin : 0; endmodule Dolt1 。out 圄5-19 条件表达式实例综合约架 队211 \ 应用程摩黯愤偶篇讲 在实际应 用 中 , 有时会把条件表达式 级联起 来, 用 以表达很复杂的条 件。 例 5-15 描 述 了这样的实例, 在Qua rut s 11下的综合结果如阁 5-20 所示。 E例 5- 1 5 】条件表达式 级联。 module ConditionalExpression2 (Dinl, Oin2, C 1 , C2, Oout ) ; input 01n1, 01n2, Cl, C2; 。utput Dout: assign Oout - (C1) ? (Oin1 & Oin2) : / /商优先权 (!C2) ? (Oin1 I Oin2) : (Oin1 ^ Oin2 ) ; endmodule 胁1 臼'12 Iht Iht-.... : , 〈case-item-expressionB2〉 ,... : 〈stateIRentB〉 default endcase 对上面的陆法行两点说明: • "defauI t" 语句是可选的, 但是在一个..ca se " 语句巾最多也只能山现一个. • " case" 讯句巾 , 条 件 表 达 式 ( case exp ression) 和选择项表达式 ( ca se item exp ers sion ) 可 以使用常量表达式 (co Dstanl expre ssion ) , 但是只能在其巾 一个使用 。 case语 句可以看做是嵌套 的 i f语旬, 从那 ·个选摊项 表达式开始往下披露lj条件表达 式相匹配的项, 然后执行第一个满足条件 的语句 , 而 不考虑其余任何的可能性. 例 子20 /216/ 第5章 是一个简单的 case 语句实例, 在Quartus II下的综合结果如圄5-27 所示. E例 5-201 c路e 语 句实例. modu!e caseStatemt(A, B, state, q ) : input A, B: input [ 1 : 0 ) state: 。utput q; reg q; always @ (state or A or B) case (state) // 此处的case 语句等价子下面的ifì污句 2 ' bOO: q � A & B; 2 ' bOl: q罩A I B; / 1 if (state 霄- 2'bOO) q - A & B; 11 else if (state -= 2'b01) q A - I B; 2 ' blO: q - A ^ B; // else if (state草- 2'b10) q - A ^ B; 2'bll: q = 0; / 1 else i f (state 草草 2'bll) q = 0 ; endcase endmodule oec军曲-<> S嗣峙。 刷刷刊 A E ISB�q r..._ q "王xx涯R !ÐS:ICR 因5-27 ωse i弱句实'�J结果 在通常情况下, case 语句描述的功能可以用江语句来实现. 但是C岱e 语句使得程序代 码更简洁、 明 了 。 5.12.1 从case语句综合出锁存器 和 if 语句一样 , 不完盟的 c路e 分支语句也 会导致锁存桔的综合, 具体原则是: 如 果某 个变由;并没有在所有可能的分支中被赋值, 也即在有的分支没街被赋值, 那 么 会为此变最 综合出锁存器. 对例 5-20 作一点修改就可得到 从 ca se语句综合出锁布榕的实例, 如例 5-21 所示, 综 合结果如圈 子28 所示. 队217\ E例 5-21 1 能综合出锁存器的 case 语句 实例 . module ImcompleteCase (A, B , state, q ) ; input A, B; input [ 1 : 01 state; output q; reg q; always @ ( state o r A or B ) case(state) 11 此处的case语句等价子下面的 ifÎ托句 2 ' bO O : q = A & B; 2 ' bO l : q a A I B; 11 if(state == 2 ' b O O ) q � A品8; 11 else i f ( state == 2'bOl) q - A I B; 2 ' blO: q帽 A ^ B; endcase 11 else if (state == 2'blO) q - A ^ B; endmodule 四11 state 4 q_2 q q_1 q_3 四、1 state 3 q_4 副5-28 case 语句结合H;l锁存锵实例结果 和证 语句一样, 当有锁存器被推断 出 时 , 综合工具都会有报警提示. 如本例在 Syplify Pro下综合时, 会有如下警告信息: " Latch generated from always block for signalq, probably caused by a missing assψlment in an if or ωse smi-- ". 意思是说, 从 always 语句中为变 量q 生成了锁存器, 可能是因为在 i f 或者 case 语句中 没有赋值。 在图 5-28 中 , 锁存器 q Up 是 由 不完整的 case 语 句 造 成 的 . 要想避免从 c臼e 语句 中 综合出锁存器, 有下面几种街 效措施. ( 1 ) 在 case 语句之前, 对 case 语句中要赋值的变量赋以初值. 伽� 5-22 展示了 用赋初值的 办法避免综合山锁蒋器的实例, 综合结果如阉5-29 所示. /218/4 '自5. Ver散布 E 例 5-22 ) 赋初值避兔综合出锁存器实例 。 module InitBeforeCase(A, B, state, q); input A, B; input [2 : 0) state; 。utput q; reg q; always @ ( s tate or A or B ) begin q = 0; 11此处. 对q 赋以初缸, 从而远兔了综合也锁存楼 case(state) 3 ' bOOO: q .. AιB; - 3'b001: q A I B; 3'b010: q = A ^ B; endcase end endmodule q_3 A q_4 q q_5 q_13 1S11_q14_1 回5-29 赋初J值磁兔综合出锁存部实例锦合纺织 ( 2 ) 使用 defau lt分支语句, 并在该语句中对所有在case 语句中赋值的变量赋以默认值. 例 $-23 展示了用 defau 1t分支语句的办法避免综合出锁非器的实例,综合结果如图 5-30所示 ­ E 例 5-23 ) 用 default 分支语句避免综合出锁存 锯. module DefaultCase(A, B, state, q ) ; input A , B; input [2:0] state; 队219\ 。utput q; reg q; always @ ( state or A or B)begin case(state) 3'bOOO: q - A & B; 3 ' bOOl: q = A I B; 3 ' bOl0: q = A ^ B; default: q .. 0; endcase end //此处. 用default赋默认值,从而准兔了综合出锁存器 endmodule q_2 q_3 q q_14 111 飞4 q_13 I un1_q14_1 q_12 阁5-30 在default分支中赋默认债来避免综合I封锁存:!!t实例综合结果 比较圈 子29 和图 5-30 , 会发现上面两种 不同的方法 沾剑了 同样的效果, 而且综合结 果 也完全一样 (即相同的硬件电路〉。 ( 3 ) 使用.. full_case "综合指令. 具体用法是:在 程序巾 " case " 关键字行 的注释中插 入指令 "syolh臼is full-case". 例 5-24 展示了使用 "创J I臼se" 指令避免综合出锁在嚣的实例, 综合结果如困5-31 所示。 /220!,j 第5章时啕H肌 '制-& E例 5 -24) 使用 t lfuJl_c臼e "指令避免综合出锁存器。 module FullCase(A, B, state, q); input input [ 2 : 0 ] A, B; state; 。utput q; reg q; always @(state or A Or B ) begi n case (state) 3 ' bOOO: q .. A 岳 B; 3 ' b001: q - A I B; 3 ' b 0 1 0 : q = A ^ B; endcase /* synthesis full_case 舍/ end endmodule ...,1_5饱te_2 飞2 q 飞3 q_4 阁5-31 使用" full_;ωse"综合指令迹兔综合出锁存格实例综合结果 从国5-3 1 可以看出, 其硬件逻辑比国5-3 0 少 。 要想知道其中的不同, 有 必要弄清楚 "full c臼e" 综合指令的具体含义, 以及综合工具对 其的处理o It fu U case" 的意思是说, 当 前 的 case 语旬的条件表达式仅有 列 出 的几个取值。 比如在例 5-24 中, Sta.le 变量仅有 勺'bOOO 飞勺'b 001 "、勺' bOIO" 三种取悦, 并且永远不 会出现别的取值。 既然 case 语旬 的 条件 仅有列出 的几个取值. 就不存在没 有贼值的分支, 所 以 , 也就不会综合出锁存器. " full -use " 综合指令 (包括 其他的指令, 如14 par all el_c部e" 等 〉是一段特殊的代码, 并且以注释的形式出现。 当综合工具看到 " full -C槌e" 指令, 就知道 c臼e 条件表达式的所 有取值都已列出, 因此, 不会再为ca se语句中的输出变盘综合锁存器。 5.12.2 ωsez和ωsex语甸的综合 在 VerilogHDL语言中, 还提供了另外两个用于处理无关紧要CdOD't -care)制牛的 case语句。 队221 \ • casez 语句: 在该语句 中 将 高阻 (high-impedance ) 值 (z ) 视做无关紧要条件. · ω民x 语句: 在该语句中将高阻值 (z ) 和未知(unkonwn ) 伯 ( x ) 现做无关紧要条件. 这两个C部e 语句与传统的 c臼e 语句用 法完全一样 , 只是关键字和特殊值略 有区别而 已 . 在使用时,无关紧要值 (z 或者 x ) 既可以出现在 C部e 语句条件 衣达式的任意位 ( bit), 又可以出现在选择表达式的任意位。 在比较过科中 . 出现无关紧要值的位不会槛考虑. 在 语法上, 可以用 "7俨n字符表示 高阻值 "气z扩" 例 5乞-2挡5 展示了 c臼e臼z 语句的建模实例 ' 该程序代码完成指令 〈变最 lR) 译俐, 并执行 相应的操作。 综合出的结果如阁 5-32 所示。 E例 5-25) c臼ez 语句 ij!棋. module CasezState.ment (OpA, OpB, IR, Dout: ) ; input OpA, OpB; input (2:0J IR; 。utput: Dout:; reg Dout; always @ (OpA Or OpB or IR) casez(工时 //邻价的 if滔句是 -- 3 ' bzzl : Dout - OpA&OpB; //if(IR [Ol 1) Dout - OpA 晶 。pB; 3'bzlO:Dout - OpA I OpB; //else i f (IR ( 1 : 0 ) --2'blOI Dout: - OpA I OpB; 3 ' blOO:Dout - OpA^OpB;//e1se i f ( IR==3'blOO) Dout = OpA ^ OpB; endcase endmodule Oo Lt 2 Oo Lt 3 /222h 00 咀 4 I 1 。0.主.题. 。J 回'_Dol且10 00咀.10 阁5-32 ωez mt.J也核实例结果 第5章V嗣同"。ι 从该闺中可以看到j译码器 Dout-l 对输入变量 lR 译 码, 用 于控制两操作数 Op A 与 OpB 运算通道的选择。 接下来再看看C创e x 语旬的使用, 例 5-26 展示了C臼e x 语句 的 建 模 实例 , 该程序代码 完成指令译码, 变量皿与 掩码mask It逻辑与" 的值作为 casex i吾句的条件, 根据 译码结 果执行相应的操作。 综合的结果如图 5-33 所示。 E例 5-26) c臼ex 语句建模。 module CasexStatement(OpA, OpB, IR, Dout); parameter mask = 3'bxl1; input OpA, OpB; input ( 2: 0 ] IR; output Dout; reg Dout; always @(OpA or OpB or IR) casex(IR & mask)//此处使用mask参数是为了说明无关紧要值既可扇子条件表达式中 = 3'bxxl: Dout OpA & OpB; //也可出现在选择项表达式中 3'bxlO: Dout = OpA I OpB; 3'blOO: Dout = OpA ^ Op6; //由于存在系完丰富的case赋值, 综合出了锁存吉普 ndcase endmodule Dout 3 。out 1 。out 2 山1 IR 困5-33 凶se.且语句地棋实例结果 5.12.3 并行的case语句 前面 说过, 在通常情况下, 一个 c路e谓合ù ( 和江陆台j一样 〉 会综合出带有优先 权解码 的创件电路, 也即对首先 解码的选择项具有较高的优先级。因为 case 语句是从第一个选择 项表达式开始搜索, 所以从上到下选择项的优先级逐渐降低. 例 5-27 给 出 了 case 语旬综合出优先级解码辑的实例 , 在 Qua trus n下综合 出的结果如 圈 子34 所示, 总兵用到 了 5 个逻辑单元 ( Iogic ele ment)。 队223\ 4墨画呈阳比 应睡附+跚跚唰 E例 5-271 case 语句综合出优先 级解码器。 module PriorityCase(key, decoder}; input (3:0] key; output [1:0] decoder; reg [1:0] decoder; always @(key) casex (key) 4'bxxx1: decoder = 0; 4'bxx1x: decoder = 1; 4'bx1xx: decoder = 2; 4'b1xxx: decoder = 3; endcase endmodule //等价的 if iâ句如下 /1 if(key[O]) /1 else if(key[l]) 11 else if(key[2J) 11 else if(key[31) c decoder 0; decoder = 1 ; decoder 且 2; decoder = 3; 除缸XIer-O key[3.. cr{) 倍以由11JSàd1 DECO:四 o 0 副 A 1..0) CLR 似拟制qSllct、 闯5-34 case且讷句描述的优先级解码苦苦约泉 从图 5-34 可以看出, De coder-{l剧于实现对输入变量key 优先 级解码, 解码的值通过 组合逻辑赋给输出变量 decoder. 由于存 在 不完整的C部e 赋值, 所以综合出了锁存器用于 存放 decoder 的值。 但是, 如 果 设计者已经知道C路e 语句巾 的所有远择项是li.斥的 ( mutually exclusive ), 这个时 候就不希望出现优先 级解向逻辑 ( priori yt logic )。 通过使用tt para Uel_ca 回"综合指 令, 就可以满足 仨面的要求。 例 5-28给 出 了 tt parallel_case " 的使用 实例, 在 该 例 巾 没有综合出优先 级解 码器, 在 Qua nus n下综合 出 的结果如图 5-35 所示, 总共用到了3 个逻辑单元。 可见, 确实减少f 不必要的硬件 资源的使用 . E例 5 -281 使用"para Uel_case" 综合 指令. module ParallelCase(key, decoder); input [3:0J key; output [1:0] decoder; I 224!J reg ( 1 : 0 ) decoder; always @ ( key) casex (key) 4'bxxx1: decoder = 0 ; 4'bxx1x: decoder = 1 ; 4 ' bx1xx: decoder = 2; 4'blxxx: decoder = 3; endcase endrnodu1e kE可 (3.. IU'"() // synthesis paral1e1 case // 等价的 if语句: if (key(Oj) decoder= 0; // if(key [ l ) ) decoder = 1; 1/ if (key ( 2 ) ) decoder = 2; // i f (key [ 3 ] ) decoder = 3 ; 也双汩t1)Slæch o a ENA ClR UlI d部α如I句$le虚伪 吁 oa B唰L ClR 阁5-35 使m "par.ùlel_case" 综合指令撞兔结合出优先级解码怨实例结果 5.12.4 条件表达式使用常量的臼se语句 在 Verilog HDL 语言中 , 允评把常量 (constant) 作为 case 语甸的条件 表达式, 而在选 择项表达式中使用变量。 常量表达式常和位选择 ( bit-selects ) 运算 一起使用 , 使得程序代 码更简洁、 明了。 例 5-29展示 了 C臼e 语句的条件表达式使用 常量的 实例 , {l二该例 小还使 用 了位选择运 算 , 实现 了 一个简单的 译码器。 在 Quartus 11下综合出的结果如阁 5-36 所示, 共用 了 6 个 逻辑单元。 E例 5-29】C臼e 语句的条件表达式使用 常 盘描述 译码器 。 module ConstantCase( key, decoder) ; input [ 3 : 0) key; 。utput [ 1 : 0 ) decoder; reg (1 : 0 ) decoder; always @ (key) case ( 1 ) ke y ( O ) : decoder = 0; key( 1 ] : decoder = 1; • �225\ 应用程摩设计实侧耐 key [ 2 ] : decoder = 2; key [ 3 ] : decoder = 3; endcase endmodule 陶(3., "如' '50--3 反)-<1 @阻四"扭曲 1,明 罔5-36 case语甸的条件表达式使用常意描述译码苦苦约果 从图 5-36 可知, 有锁存器综合 出 来. 原因是条件表达式用常量表示, 所以综合工具不 能确 认到底有多 少 个选择分支, 只 能当做不完备的 case 赋值语句。 要 想 解决这个问题, 可 以参考下例所示。 伊IJ 5-30 展示了 lt full ωe" 综合指令 用 于条件表达式使用常量的 case 语旬的实例, 在 Quartus rr下综合出的结果如 圈 子37 所示, 总 共 仅用到 了 2 个逻辑单元, 节约了锁存器硬 件 资源。 E 例 5-30) 将 " full-case" 综合指令 用 于条件表达式使用 常蠢的 case 语 句。 module FullConstantCase (key, decoder ) ; �nput [ 3 : 0] key; output [ 1 : 0 ] decoder ; reg [ 1 :01 decoder; always @ (key) 毛ase ( 1 ) /1 synthesis full_case key [ O ] : decoder = 0 ; key [l ] : decoder = 1 ; key(2 ) : decoder = 2; key ( 3 ] : decoder = 3 ; endcase endmodule W队. 做翻(1.,0] 倒5-37 将unIll-me"综合指令用r条件表达式使用常垦的case语句滥兔综合出锁存撼的实例主自主� /226� 第5. VeriIog 用比 5.13 锁存器的综合 前面介绍了组合逻辑的 建模和综合, 这一节主要 讨论关于锁存器的更深入的问题. 迦 常锁再器的综合可有 以 下两种情况: · 有意识的 (intentional): · 无意识的 ( accidental)0 有时候, 所 设 计的硬件电路中 确 实需要对锁存器进行建棋, 这就是有意识的锁在辑综 合, 如下WtJ所示. 例 5-31 描述了一个 l 位 SRAM 的 实例 , 在硬件电路中就需要用到锁存 稽。 在该电路中, 片地信号CS (低有 效〉 和诙写信 号 WR控制 SRAM 的操作. 综合出的 结果如国5-38 所示. E例 5-31] 1 位 SRAM。 module IntentionaLLatch(Din, CS, WR, Dout ) ; input CS, WR; input Oin; output Dout; reg Dout; always @ (CS or WR or Oin) if (!CS) if(WR) Oout = Oin; /1写操作 else Dout - Dout; /1埃操作 else 。out .. l'bz; //输出自民i Endmodule latrs o C R Q sI eI Doul I .斗三F←一一-f5ë面 I Dout_2 DMh b u CQ R 因5-38 I位SRAM 综合出的RTL槐闯 们是也有很多时候, 由于疏忽旦旦盲目地边>J(代码简洁, 确 实综合11\ r不必要的锁有-器. 队227\ 这些都可以看做无意识的锁存器综合, 前 面 已经街过很多这种例子, 在此不再赘述. 下 面 针对锁存器, 深入的讨论更多 的技术细节。 ( 1 ) 如果在 ωm 语句或 if语句中对变量赋值不完整, 也即不是对输入变量的所有取值 情况输出变盘都进行赋值的话, 那么将会给输出变量综合出锁存器. ( 2 ) 当条件操作符 ( ? ... : . . . ) 以反馈形式实现时, 也能导出一个锁存端的功能。 例 5-32 描 述了用条件操作符 实现的 1 位锁存器实例, 在该电路中, 锁存信号 latch ( 高 有效) 控制锁布器的操作。 综合出的 RTL视国如 图 5-39 所示。 E 例 5-32 ) 用条件操作符 实现 1 位锁存器. module Conditiona�Latch(Oìn, latch, Oout ) ; input latch, Oin; 。utput Oout; assign Dout = (la�ch) ? Oin : Dout; endmodule lat 3 Q ←一面 阁 5-39 条件操作符实现的 l 位锁存器踉合结果 ( 3 )对于 always语句内部定义的局部变量, 如 果也是在不完整的条件分支(if或者回se) 语句中赋值, 那么 也会综合出锁存器. iÝlJ 5-33 描 述了局部变量综合出锁存 器 实例, 综合结果 如 困5-40所示­ E 例 5-33 ) 局部变量综合出锁存器。 module LocalVariableLatch(D1n, input latch; input [ 3 : 0 ] 01n; output [ 3 : 0 ] Dout; reg [ 3 : 0 ] Dout; latch, Dout) ; always @ ( latch or Din)begìn:Ll reg ( 3 : 0 ] temp; i f (la�ch) temp = Din; Dou� = temp ; end endmodu�e // 此处的标号足为了 能够定义f.lnß受盘 I2.28 h l1.18T树q 院。 o 0 8 恤 α R l1.18T咧η gJ5:1挺 V町ilog H。也 W咿-.3 terrc>-壶 ter鸣F咱 t回'p" Result - Result + DatalReg; DatalReg - Data1Reg << 1 ; Data2Reg = Data2Reg >> 1; shift count = shift count + 1 ; end end endrnodule 由 于 Quar阳s ll 不支持非静态循环, 例 子38 在 SynpLify pro 下综合生成 " .vqm" 基 于 atom 的 Ve副og HDL结果文件, 再由 Qua冈山 H 对结果文件进行编译. 最终, 在 Quartus ll 下的时序仿真结果如阁 5-45 所示. 从仿页.波形中可以看到, 当 乘 数 Oata2 为 o (UP二进制 " ∞。0") 时. 循环移位 0 次 ( shift cOunl 待于 0)0 当乘数 Oata2 为 I ( Illl 二进制 Il 0001 )" 时, 循环移位 i 忱。 随带 Oata2 增大, 移位狄数增加. 队233\ , /军W问 毗 蹄回话柱十跚跚瑞 阁 5-45 1位静态循环实现的无符号二边很}乘泌然仿;rt被形 5.1 5 阻塞和非阻塞赋值 在前面介绍阻塞和非 阻塞i轩句时曾经建议: 用阻盛语句建模组合逻辑, 非阻塞语句也 棋时序逻辑。 但是, 有时候混合使用两种语句使得应模更容 易 。 为 了 能让读者熟练地掌握 阻惑和非阻塞赋值语旬 , 本节君在入介绍二 者的区别 。 对于阻来赋值语旬, 赋值语句左边的变罩在下一条顺序语句执行之前进行赋值操作. 但 是对于非阻塞赋值语句, 赋值语句先计算赋值表达式的值, 在仿真周期结束 的时候将该值赋 给丘边的变盘 〈所有非阻辈革语句同时赋值〉。 首先, 给出一个阻塞和非�ID�语句施舍使用实 例 , 程序代码如例 5-39 月IT示, 综合出的结果如国 5-46 所示, 仿真被%J如国 5-47 所示。 E倒 5-39) 混合使用阻塞和非阻来语句实例 1 . module NonblockingAndBlockingl (clk, Oin, input clk, Oin; output RegANO, Reg。氏, RegXOR; reg RegANO, RegOR, RegXOR; RegANO, RegOR, RegXOR) ; always @ (posedge clk) begin RegXOR = RegXOR ^ Oin; RegOR <- RegXOR 1 Oin; RegAND <= RegOR 晶 。in; end endmodule 1/ 语句 1 . 陋恋赋伯语句 // i否句 2. 非I\UZ�赋伯语句 // 语句 3, 4�阻鑫赋值语句 R销协NO /234h R句j)(OR 回 5-46 �昆合使用 阪黎和非阻笨语句实例 RTL 视剧 第5意 削1吨 HDL翩翩舍 、 ‘嘟 clk Din RegAlDl Re&OR RecIOR • 图 5-47 混合使用阻塞和非阻塞语句实例仿页,被形 • 在上例的 always 顺序语句块中, 第 1 '条语句为阻寒赋值语旬, 随后的两条语句都为非 阻塞语句。 由于所有赋值对时钟边沿敏感, 所以寄存器变量 RegXOR 、 RegOR、 RegAND 都被综合成触发器。 因为对寄存器变量 RegXOR 进行的是阻塞赋值, 所以Ä值立 即 旦 新 , 所以后面的语句引用的是 RegXOR 的新值。 也就是说, 对 RegXOR 赋值的表达式综合出 的组合逻辑的输出 〈 囱 5-46 中 "异或门 " 输 出 端 ) , 被馈送到引用它的赋值语句 ( 语 句 2 ) 综合山 的组合逻辑的输入端 ( 图 5-46 中 的 " 或 门 " 输入端 〉。 但是, 对变盘 RegOR 进行的 是非阻塞赋值, 它的新值与其后的 非阻塞赋值语句 〈 语句 3 ) 同时更新。 所 以 , 语句 3 对 RegAND 赋值的语句引用的是 RegOR 前一个时钟的值。 也就是说, RegOR 触发器的输i甘. 被锁送到引用它 的赋值语句综合出的组合逻辑的输入端 〈 图 5-46 中 的 " 与 门 " 的输入端). 从上例可以看出, 阻器和非阻盘语句的最主要的区别在其后的引用它的语句的电路结 构上a · 对于阻器语句, 其综合出的组合逻辑的输出 , 被馈送到其后引用它的语句的组合 逻辑的输入端, 也即后面的语句引用其新值. · 对 于非阻塞语句 , 其综合 山 的触发器的输出 , 被i"Ø!送到其后引 用 它的语。J的组合 逻辑的输入端, 也即后面的语句引用其|日值。 为 了 加深理解, 下面再来看在例 5-39 基础上, 稍搬修改赋值语句后 的例 5-40. 程序 代码如下所示, 综合出的结果如图 5-48 所示。 E例 5-40 ] 混合使用阻塞和非阻塞语句实例 2。 module Nonbl oc klngAndBl ocking2 (clk, Oin, RegAND, RegOR, RegXO民) ; input clk; input Oin; output RegANO, RegOR, RegXOR; reg RegANO, RegOR, RegXOR; always @ (posedge clk) begin RegOR <- RegXOR I Oin; RegXOR .. RegXOR ^ Oin; // 语句 1 . �F阻寨赋值 /1 商句 2 . 阻2墨赋值 \ 235\ RegAND <= RegXOR & Din; end endmodule // 语句 3. 非阻II赋值 R呗�OR R吨。R 2 只创队ND_2 RegAND 固 5-48 滋合使用阻鑫和非阻黎语句实例 2 的 RTL 视图 将例 5-40 的 always 块语句中的语句 l 改为阻塞赋值语旬 , 得到如例 5-41 所示的程序 代码, 综合结果如 图 5-49 所示。 E 例 5-41 ) 泪合使用阻塞和非阻塞语句实例 30 module NonblockingAndBlocking3 (clk, Din, RegAND, RegOR, RegXOR) ; input clk; input Din; output RegAND, RegOR, RegXOR; reg RegAND, RegOR, RegXOR; always @ ( posedge clk) begin RegOR = RegXOR I Din; RegXOR = RegXOR ^ Din; RegAND <= RegXOR & Din; end endmodule // 语句 1. 非阻鑫赋值 // 语句 2. 阻塞赋值 // 语句 3. 非阻�赋 值 R句XOR RegOR 2 只句。R /2364 R创�ND_2 R吨AND 囱 5-49 混合使用陋寨和l非阻搭话何实例 3 的 RTL视阁 第5意 Vefilog毗'唰脯除\ 从例 5-40 和例 5-41 可以看到, 虽然语句 1 分别使用非阻器和阻塞赋值 , 但是却得 到相同的综合结果 . 这再次说明 了 , 在边沿敏感周期行为 always 顺序块中使用阻忠、 非 阻塞赋值语句, 只对其后引用其值的语句产生影响. 通过上面的三个例子, 还可以得下 面的结论: ( I ) 不管是阻塞还是非阻塞赋值语旬, 若在该语句之前对其值 〈 除纯粹的临时变盘〉 进行引用, 则只能引用其上个时钟周期赋予的旧值. ( 2 ) 在边沿敏感的周期行为 always 块爵句中, 若变量被某条语句引用上个时钟剧期贼 的值 〈 旧 值 ) , 贝IJ 哀ì 变:m:综合 出的触发糕的输出端被馈送到引用它的谓句的输入踹: 若变 "被某条语句 号 | 用 当前时钟f古H归赋的值 (新值), 贝IH在变lil:综合出的组合逻辑的输山端被 锁送到引用它的语句的输入端. 5.16 函数的综合 在 Verilog HDL 语句巾, 函数代表了纯组合逻辑. 函数在综合的时候, 被蜒开成 了 内 联的 ( in-lioe ) 代码。 任何在函数中定 义的局部变盐都被当做纯粹的临时变茧, 仅被综合 成导线. 例 子42 给 出 了 一个函数的实例, 函数 Parity 完成对输入数据的奇偶检验. 若 i 的个数 为奇数则输出 I , 否则输出 为 Oð 综合结果如圈 子50 所示。 E例 5-42 ) 一个有关函数的实例. mo du 1e Functio nApp (Oata I口, O dd_Eve n ) ; input [ 3 : 0 ) OataIn; 。utpu t 。dd Eve n; function P arity; 1nput [ 3 : 0 ) Oin ; i n teger i; begin Parity - 0; for( i -O; 1<<1; 主:i+1 ) end � i f (01n ( i ] ) Pa rity Pa r1ty + 1 ; e n dfu n ct i o n assign Odd_Eve n a P arity (Oataln); e n dmodule • \ 237\ A雨雨地 翩鹏也愤慨调 Pa前y_10 Pa时ty_13 Od_d Even 困 5-50 函数实例饵合出的RTL槐阁 在上例 巾 , 前数 Parity 被综合工具展开成内联的代码, 具有如下形式: = Parity 0; i f (Din ( O ] ) Parity = Parity + 1; i f (Oin [ 1 ] ) Parity = P arity + 1 ; if(Din [2 ] ) Parity = Parity + 1; i f (Oin [ 3 ] ) Parity = Parity + 1 ; 5.1 7 任务的综合 任务既可以用 来表示组合逻辑也可以表示时序逻辑。 例 如 , 任务在地沿敏感周期行为 always 语句中被调用, 则任务的输出参数被综合成触发器. 与函数调用类似, 任务调用在 综合时也会被展开成内联的代码, 所以不会为主i:保留层次结构 ( hierarchy )。 例 5-43 给 出 了任务调用实例 , 任务 BixXOR 完成了两个 4 位二进制敬的战优异或运 算 . 肉 为任务在钟控的 always 语句中被调用 , 所 以 其输出参数被综合成触发器, 代表了时 序逻辑. 综合的结果如回 5-51 所示. E例 5-431 任务调月1实例. module Tas kApp (A, B, clk, input clk; input ( 3 : 0] }气, B; 。utput [ 3 : 0 ) OataOut; OataOut ) ; task BitXOR; input ( 3 : 0 ] Oin1, Oin2; 。utput ( 3 : 0 ] Oouc; integer i; begin for(i-O; i<-3; i-i+1) Oout [ i ] = Oin1 [ i 1 '、01n2 [ 1 ] ; end endtask reg ( 3 : 0 ] OataOut; • /238 / always @ (posedge clk) BitXOR(A, B, DataOut ) ; endmodule '可3.. 四3.. 第5章 Veril啕毗刷刷丽、λ �aru(3..OJ咽'p o c α噩arul3..� C:II 阁 5-51 任务词用'_!k例结合 州 的 RTL 训ÆI 例 5-43 巾的任务在综合时被展开成如 F 的 内 联代销: DataOut ( O ) - A ( O ) ^B ( O ) ; DataOut ( l ) - A ( l ) ^B { l J ; DataOut ( 2 ) = A (2 ) ^ B [2 ] ; DataOut ( 3 ) - A ( 3 ) ^B ( 3 ] ; 5.1 8 任意值/高阻的综合 在 Verilog HDL 语 言 中 , 有两个非逻辅值: X ( 任意值〉 和 z ( 商阻 〉 值. 本节将会介 绍这两个值的综合 , 以及使用时的注意事项. 值 " x " 可以赋给任何变虫, 此时 x 农示无关紧要值, 抑、什工具将会根据优化原则选 摔逻辑 tlQ" 或逻辑 " 1 " 赋给变革。 例如: ResetValue - 2' bxx; //琼�T.n企 niJ选J 衍,逻辑 " 0 " 必逻辑 ú 1 " 赋给交 lii 使用值 气" 时, 需要特别注意的是: 如果值 " x" 剧凸在i cωas臼e 语句的选择I项员衣达式 则相!阳恒的此条件分支y永k远不会被执行. 例 5-44 给 出 了 在 c邸e 谓句巾使用 " x " 囚的实例, 综合的结果如!回 5-52 所示. 从该 国 巾 吁 以 看 出 , 语句 " 2'bxx: DataOul = A+贱" 没有被综合H\ • E例 S-44 J 在 臼se 语句中使用 U x" 值的实例. module ImproperValueX (A, B, Op, DataOut) ; input ( 1 : 0 1 Op; input A, B; \239\ output DataOut; reg DataOut ; always @ (A or B or Op) case (Op) 2 ' bOO: DataOut - A I B ; 2 ' bO l : DataOut - A&B; 2 ' bxx: DataOut = A+B; default: DataOut a 0; endcase endmodule D哩Z赠Ml Q:(1.. A 0ECa克R // 此条件分支己被综合工具忽略 S曲回-0 I[执T叫� Sa.eC:n::A. 。回lIO.I 回 5-52 case语句中 使用 气" 真{ 实'例的 RTL 视图 通常在 c部e 语句中使用 气 " 值时, 综合工具都会给出报管提示。 例如, 例 5-44 在 Quartus n 下综合有如下的报警: "Waming: Verilog HDL CaseStatement error at study.v(l l ): case Îtem expression never matches the case expr臼sion because it contains aD 'x' or ''Z! valoe. " 下面再详细介绍关于 It z " 值综合的细节。 在 Verilog HDL 语言中, Itz" 值用 来对三态 门 进行建棋。 在使用 "z " 值时, 应注意下面一些细节: • " z " 值可以用在任何赋值语句中, 但前提是必须要在条件酷值语句 ( 例 如 , if、 C挡回、 casex 等语句 ) 中对变最赋值。 例 5-45 描述 了在条件赋值语句 中, 利用 "z" 值来对三态门进行建模 . 综合结果如 图 5-53 所示。 E倒 5-451 " z " 值建模二态门实例。 module Tristate (A, B, OE, input OE; input [ 1 : 0 ) A, B; output [ 1 : 0 ) DataOut; DataOut) ; assign DataOut = (OE) ? A + B : 2 ' bz z ; endmodule /240� 第5章 Ve时'啕 HOL g妙。 '电1. �1 OetaC主且-1 NX克R 民量反革且句。 阁 5-53 气" 值建楼二三态门实例 的 RTL 视图 · 与 " x " 值使用一样, 如果在 case 语句 ( 而不是 c臼ez 或者 C剧院 语 句 〉 的选择项 表达式中使用 "2" 值, 则相应的该条件分支永远不会被执行. · 如果综合工具为 某个变量综合出 三态门触发器, 并 且该变量在 always 语句的某条 件赋值语句中被赋予 "z" 值, 则综合工具同样会为该三态门输出控制逻辑综合出 触发器, 用 以保有.该控制信号的值. 例 5-46 给 出 了三态门触发器建模实例 . 在该例中 , 变量 OE 为三态门的输出允许信号。 综合结果如圈 子54 所示。 E 例 5-46) 三态 门 触发器建模实例 . module TristateFlipflopl(A, B, clk, OE, DataOut ) ; input clk, OE; input A, B; output DataOut; reg DataOut; always @ (posedge clk) � if (OE) DataOut A ^ B; else DataOut � l ' bzz; endmodule AC二二>­ BC=>- •• fINIi份。 DetaQJ-f唰 制,必-1 Det反主且 C:II 阁 5-54 丘态门触:a�U!模实例的 RTL 极因 队241 \ F丽帽比 噩醺摩也十实懈诩 从图 5-54 综合结果可 以看出 , 综合工具综合出 了 两个触发器: 一个触及; 母 ( 圈 中的触 发器: DataOut-陀的〉 用于存储输出变:i:i1 DataOut 的值: 另一个触发器 ( 剧 中的触发器: alwaysO-regO) 用 于存储三态门 ( alwaysO- I ) 的输出允许逻辑。 有时候, 不想为三态门的输出控制综合出触发器. 那么, 可 以 用 两个分开的 always 语句来建模三态门触发稽。 例 5-47 描述的主态门触发辑是在例 5-46 的基础上 , 用 两个 always 语句实现, 无需额外触发器来存储输出控制逻辑的值。 程序代码如下所示, 综合结 果如 圈 子55 所示. E例 5-47 1 无需额外触发器的三态门触发器. module TristateFlipflop2(A, B, clk, 0巳, DataOut) ; input clk, OE; input A , B; 。utput DataOut ; reg DataOut, temp; always @ ( posedge clk) temp - A ^ B ; // cemp 临时变量用以实现触发器的综合 always @ (OE or temp ) i f ( OE) DataOut - temp; else endmodule - DataOut 1'bz; 阁 5-55 无需额外触发榕的二态门触发锦综合结果 在例 5-47 建模的三态门触发器 中 , 引 入 了 临时变量 temp, 用于第一个 always ì吾I�J( 触 及器的时序逻辑 〉 和第二个 always 语句 〈 三态 门 的组合逻辑〉 之 间 的通信, 从而堪兔 了 为 二态f J的输出控制信 号综合出触发器。 迦过上面两例可以看到: 在例 5-46 中 , 输出变量 DataOut 直接由时钟 clk 触发驱动: 而在-frll 5-47 中 , 输出变盘 DataOut 不是直接依赖时钟 clk, 而是直接靠输出 允许控制变量 。E驱动。 /242/ 第 设计验证 一个完整的基于 HDL 语面的 FPGA 的设计流程为 : 设计说明与设计划分、 设计输入、 功能仿真与测试、 逻辑综合 、 门级综合、 逻辑验证与测试 、 布局布线、 后综合验证. 最后 是物理实现, 如图 6-1 所示. l!J:计说明lilt计划分 法计输入 行为级IRTI.级J!模 功能伪负勺测试 �割lt事合 门级综合 逻�I�验证aJ测试 布.lal布线 后综合钝址 $勿续实现 因 6-1 典型FPGA 设计iÁi.f'1 6.1 后综合设计验证 后综合设计验证确保综合出的网 农与综合电路所用 的 RTL 模型一致. 关 f 设计验证, f再马阳孔 鹏程摩话总?实倒刷 首先�号rtM,验证策略 , 详 细描述需验证的指定功能。 然后应该选取合适的验证语辜, 为 了 使设计和验证使用同一语言, Verilog 和 VHDL 语言被广泛使用。 当然, 系统级验证常常 采用高级语宫, 例如 Vera、 e、 C/C抖, 以及 Java 等。 最后考虑的是采用何种驰iIE方法, 目 前流行的两种方法是: 娃子仿真的 ( simulation-based ) 验证和基于形式化方法的 ( formal method-b臼ed) 验证 。 基F仿真的验证是面向输入的 ( 例 如 , 设计者输入激励 向 世 ) , 而形 式化验证则面向输出 〈例如, 设计者提供部要验证的输出属性). 6 . 1 . 1 墓于仿真的验证 基T'仿真的验证在工业使剧&多。 征验证过程中, 输入激励力n到测试平 台 对 设 计进行 测试, 将测试输出与预期值进行比较. 在仿真之前, 首先运行 linter 程序检查静态错棋、 潜在错误, 以及非法代码. 静态错误指的是: 不需要施加激励源, 就能被发现的错误。 例 如 , 没千f被驱动的总线, 或在端口不匹配等. 潜在错误通常以警告的形式出 现, 例如没有 输入信号的逻辑门. 接 F来儒要生成激励 向 监 . 如果直接针对设计 的指定功能特性生成输入激励, 被称为 瓦接�IJ试 (direct test)。 肉为在接测试的H标是设计者熟悉的, 但是程序 bug 常常扯生在 被 设 计 有忽略的地方, 肉 此 , 最好使用伪随机向量作 为测试激励源 , 称做伪随机测试 ( pseudorandom lest)0 伪随机向最常常由软付生成. 测试激励源生成以后须选择合适的仿tt器. 硬件或者软件仿真器按原理可分为 : 事件 驱动 (event-driven ) 仿真和基于周期的 (cycle-b臼ed ) 仿 真 . 每当逻辑门的 输入或者块语 句的输入变量改变时, m:件驱动仿真.器都会屯.ffr计算逻辑门或有块语句的输出 . 任 何一个 值的变化部成为事件. 毯子周期的仿真把电路划分到各个不同的时钟域, 在每个时钟街效 沿到来时计算谈时钟域的电路的值。 6.1.2 形式化验证 形式化验证不市要坐成测试向 盘, 这 是 与 基 于仿真的验证最大的区别. 形式化驹ìïE包 含下面的两个内容: 等价雄验 (equivalence ch�ckiog ) 和剧性验证 (property verification)。 哼价检验判断两个设计功能是沓相同. 主要有两种办法实现: • 用系统的方法战斗能够区别两个电路的输入向是. · 将两个电路转换成规范形式 , 然后进行 比较. 属性可以看做 是 设 计的 另一种描述, 属性验证用 于检1f设计结果是否有 设 计 说 明 指定 的属性. 剧性,如正的}丛生L1足搜索整个状态空间 ( slate space ), 理2·足沓存在剧性不匹配的点。 本; 书仅详细介绍搭于仿点的验证 , 读者如果想深入了 解形式化验证 , 可 以参阅其他书籍. 6.2 面向验证的编码风格 úû Irl]验证的编码风格 (coding for verification ) 指的 是 : 二号虑 到 设 计的可驰 征性和 可调 /244/ .8. 试性, 在用 HDL 语言建棋时, 要尽可能地遵循一定的编码风格 。 而在本节中将详细介绍 这些编码凤,格. 6.2.1 功能正确性 功能正确性 (functional corr民tness ) 原则要求设计者思式地说明其设计意图, 用以排 除一些功能上的错误. 例 如 , 有如下的程序代码: wire [ 8 : 0 ) in; wire [ 7 : 0 ) out; assign out - in; 上面的代码虽然操作数不匹配, 但在语法上是正确的. 从功能上来说, 操作数不匹配 潜在地存在截断错误。 但是, 上面的代码也有可能是设计者故,(l;使用的 . 所 以, 好的编程 风格要求在设计中明确表示其意图, 从而排除因不小心造成的功能错误. 阁此, 七面的代 码应该写 为: wire [ 8 : 0 ) in; wire [ 7 : 0 ) out; assign out [ 7 : 0 ) = in [7 : 0 ) ; 功能正确性原则包括下面的一些 内 容 . 1 . 语法性检查 要排除设计中存在的潜在错误, 需要有一套完整的编码规则, 而这些规则可以大不相 同. 因此, 仅就一些通用 原则进行介绍. ( I ) 操作数匹配原则 尽管 Veri10g HDL 语占自 动为短操作数补�以使其匹配. {11是还是该显式地加 以说明, 从而避免国疏忽造成的错误. 例 如 . 1=玉如下的程序代码: reg ( 3 1 : 0 ) X, 'f , Z; Z - X & 'f; Z [ 1 l : 3 ] - X ( 1 0 : 2 ) 晶 'f [ 8 : 0 J ; Z - X[9:1) & Y(8:1); 11 所有操作数部匹配 1 1 所有操作景!cr.JI匹配 11 锹作数不匹配 最后一条语句违背操作数匹配原则, 应该改为下面的语句: Z [ 8 : 0] - X [ 9 : 1 ] & ( 1 ' bO , Y ( 8 : 1J ) ; 1 1 ;后要补齐协作数 。〉 隐含的时序逻辑 隐含的时序逻辑主要山不完整的条件语句造成 , 如 if-else 语句和 case 语句等. 例如, 有如下的程序代码: 队245\ 应用理摩设ìt实倒摘讲 always @ (posedge clock) begin case (5) : 3 ' bOOO : Q = a; = 3 ' bO l l : Q b; = 3'blOl: Q a; 3'b1l1: Q = b; endcase assigo F = ( ( 5 靠= 3 ' blOO) I ( 5 -= 3 ' bO O l ) ) ? (a I b ) : Q ; 由于不完整的 ωse 语 句 , 上 面的程序代码需要综合 出存储端, 用 以保存未列出条件下 的变且: Q 的值。 义因为 上面的代码使用 到钟控 always 语句块'1' , 则会综合出顿外的触发 辙, 如国 6-2所示. a b MUX FF clock S 阁 6-2 -'1';王将.条件i仔句导致额外触发器的ttf干 若要避免上而不完整条件语旬导致触发器的综合 , 在前面II节中 已经详细介绍各种方 法. 例如1 , 对 七面的程序使用 full case 综合指令即可, 优化后的结果如阁 6-3 所示. always @ (posedge clock) begin case (5) : 11 synthesis full_case 3 ' b O O O : Q .. a ; 3 ' bOll: Q = b; 3 ' blOl: Q = a; 3 ' b1 1 1 : Q 罩 b; endcase assiqn F - ( (5 - 3'blOO) I ( 5 -- 3 ' b O O l ) ) ? ( a I b) : Q; 00101 0 8 )_)叫瑞ux101 ttl I Q' I F b 。 sclcxt s 国 6-3 使用 fulJ case 综合指令巡兔额外触发糠的路合 /246!A .6. 2. 结构 ( structural ) 检查 结构错误和警告来自于不同 设计者的模块之间的注接, 因此, 必须要进行结构撞查。 主要有下面一些内容。 ( 1 ) 环路结构 ( loop structure) 环路结构指的是将电路的输出反馈剑其输入, 也就是在某一时刻, 信号可以迦过整个 环路, 而没奋被触发器E或者锁存器阻隔 . 国 6-4 给 出 了 电路 中 同时含打组合逻辑环路与锁 存器环路的实例 . 环路也可能由锁存器构成 , 当在 同一时刻锁存器者1!处于透 明状态. 例如 在图 6-4 中 , clock l 处于高电平而 c」phloC-业 ck、=JM-o……仆仆斗什·叶f,凡24r- 处于低电平, 则构成了锁布,瑞透明环路. …一广 ~, ι-… J·、,『川、 '川 二肿 AM 咽町 御' )「 ←一 -气 、 巳 -­ …一 --u隔三·、f''一1 。。 -- - - ,. - - - - - - " 精.(,3环'鲁 dock2 阁 6-4 组合理辅环附与iiMH>>坏阶实例 组合逻辑环路检测 比较容易, 方法是: 如 果从织合逻辑门的输入到输出信号Inl�IJ原来 的线网, 而没有经过任何时Ff单元, 贝iJi在组合逻辑构成了环路. 锁有·揣环路检测比较网雄, 首先找到l山锁蒋樵构成的环路, 然后判断环路中的锁存器 是 否 在 间一时刻处于透明状态 . ( 2 ) 总线操作 ( Bus Operation) 驱动总线的设备必须在放弃总统操作时将驱动输出到商阻状态. 不过在大多数应用 "1 , 采用树 上拉/下拉来迦兔潜在的抖动问 题。 国此, i后要选择合适的上拉/下拉也度, 从 而避免将总统驱动剑同定的迦辑。 此外, 还应该检测总线设备的瓦斥的驱动便能信 号. 当然, 这样的检测是很烦琐的, 通常只能山形式化验证来完成. (3) 触发器与锁布器配贺 高有烛的锁存器不J也该驱动商有效的锁存器, I..JI-描有放的触发器不应眩耀�JÎ罚i合·放 锁存器. 这是lkl为, 被驱动的锁存器仅仅传遍驱动它的锁存器/触忍之惊fr.储的数据, 作用为 简单的缀忡器. 在这种机况下 , 编 译迦常会给 出 密�' rfli /f二是报惜. l司理, 低14效的锁存苦苦/下降沿触发的触发器也不能驱动低有般的锁存器. I对此, 同一 路 轮 中 的 时 J书单元相tv.庇该交替变化. (4) 时}y.单元的复位/胃忧 所有用 F控制逻辑的时仔单元应主i H-fT复位/置位功能, 从而使得在 七电挝位后 , 所有 \247 \ hí翩翩盼缸 瞿腥事酣实棚讲 控制逻辅能处于稳定的己知状态. 当然, 处于数据通道中的时序单元则没有此要求. 6.2.2 时�正确性 本节所讲的时序正确性是从 RTL 中能够发现的时序问题. 1. 竞争窗险 时序问题中最常见的问题是竞争冒险. 竞争冒险指的是: 多个操作在同一时刻施加在 同一实体 〈 例如 , 变;庭或 在·线网〉 上, 从而导致其结果的不确定性. 这些操作可以是同时 写操作或l 者同时的读写操作. 竞争胃 险有以下一些原肉. ( 1 ) 被同一时钟沿或者事件触发的多个模块对同一变量进行赋值. 例如, 下面的程序代码描述了此类型的竞争臼险. always @ ( posedge clock) x - l ' bl; always @ (posedge clock) x - 1 ' bO; ( 2 ) 对f 多个事件计数写操作造成的竞争目险则往往不易被发现。 例 如 , 在下丽的实例中, x 与 y 的变化都会引起对变是 event-number 的写操作. 如 果 x 和 y 在同一时刻发生变化, 则会出现问题. 在本例中, 变 量: event_number 加 l 压 是加 2 取决于仿真器, 所以结果是不确定的。 always @ (X or y ) event number - event number + 1; (3) 同时读写操作也会造成竞争冒险。 如l下面相序代码所示。 吗 y 值由于运算 y = y + l 后发生改变, 则会触发连续赋值语句 x = y + 2 的执行, 因而更新 了 x 的值. 但是在同一时刻变量 z 要读取 x 的值, 那么问题就 产生了: 变盘 z 读 到的是 x 更新前值, 还是 x 更 新后的值? 使得结果不确定. assign x = y + 2 ; always (posedge clock) begin y - Y +1 ; Z - Xi end 对竞争胃险作个简尊的总结: 只要在同一时刻多 个地方对间一变量进行读写操作 , 就 会存在竞争罚险。 竞争罚陆的解决办法是: ( 1 ) 对 f同时读/写操作造成的竞争忖险, 可以通过使用非阻:1&语句来排除. 肉为非阻 塞语句的写操作在当前的仿真时间结束后才执行, 而此时所有的读操作都已完成. /248 / .6. ( 2 ) 对于同时写/写操作造成的竞争时险, j.主议只在一个块语句中对变世进行赋值。 2. 门控时钟毛和j 门控时钟是经常使用的技术, 但是若使用不当则会在时钟树上产生毛JIiIJ. 从而导致锁 存器与触发器错误操作. 例 如 , 在 图 6-5 中 , 触发器输出对触发器时钟进行f J控. 假 定 门 控信号在时钟上升沿到来时, 从高到低变化. 由于触发器的时钟-输出延时, 门控时钟信 号到达要比时钟上升沿晚, 从而造成了窄毛刺信号. FP FP l旦 飞 ck:lck _j __ll!lilCh 图 6-5 门按时钟产生的毛刺 最好的解决门控时钟毛刺的办法是使用或门 . 时钟从低变化到 高, 可以先稳定或门的 输 出 , 从而有效地阻 止了毛刺. 同理, 如果门控触发器是下降沿触发 , 则 应该使用 与 门 . 3. 跨时钟域毛刺 跨时钟域很容易产吧毛事IJ. 如 果 两个时钟域没有同步, 则两个时钟域的变化问隔可能 会无限小, 从而产生毛刺. 因此, 跨时钟域伯号必须进行同 步。 典型的同步电路如国 6-6 所示. "二二二 = - " 、 、 clock domainI , , II II , 、、、 sync尬。nizer FF 、 、、 、 、 、 句 , clogkl ,,,,, FF , , I , ', ."寸.I… ;II :二 .4 . FL FζII1� -、_ 、一一-飞 -、、、、 、、 、 、、 、 - CI但k2 ---- - - ' ,, " , , , clock ‘…… doπ回in2 … - … … _ 1 因 6叫6 跨时钟域InJ !.Ii 6.3 定时验证 由 于 RTL 模型的功 能性检查井没有考虑到传输延 时 , 因 而 不能验hE模咱是否满足定 时条件和输入/输出时序的特性指标 , 所以后综什定时践证是必不可少的. 店时验证利用 器件的模型和电路的互连关系来分析电路的时序, 判断在实际设计中是 沓能达到硬件定 队249\ 时约束条件和输入/输 出 定时特性的要求。 定时验证必须考虑逻辑门的传输延 时 、 门之间 的互连、 时钟的不对称性、 输入/输出定时约束条件 〈 例 如 , 建立时间 、 保持时间及触发 器脉冲宽度等〉。 定时验证方法可以分为: 动态定时分析 CDTA) 和静态定时分析 ( STA)o DTA 使用 电路的行为模型 、 门 级模型和开关级模型来模拟分析功能通路 , 使用模拟仿真器来分析晶 体管级模型。 sτA 使用和 DTA 相同的模型, 而且系统尽可能地提取电路的逻辑门级表达 式的结构, 并 且对通路上的传输延时加以计算, 从而生成一个街向非环状图形。 DTA 相比 STA 的缺点是: 分析需要测试向量, 忽略冒险情况, 不能分析最大最小路 径, 并且由于使用仿真洼, 所以需要很长时间来模拟。 此外, DTA 还不能分析百万 门 以 上 的电路。 因此, STA 在实际中应用较广, 儿乎所有的 FPGA 综合工具都带有静态定时分析 工具。 STA 的定时通路分为下面四炎, 如 图 6-7 所示. · 从输入引脚剑寄存器单元的输入端通路: · 寄存器输 出端至tl下一个寄存器输入端通路 : · 从寄存器输出端到输 出 引 脚的通路: • 从芯片的输入引脚到输出引脚的通路。 @ dk oQ ③ ① 输入.;1脚望��m懦 ② 寄存告曹雪j省得路 ③ �' rf�击到输出11仰 @ 输入号l脚主与j输出号14即 回 6-7 问步电隙中盼态定时分析迦ili 6.4 时序分析基础 设计中常用 的时j子概念主厦 是: 陆大时钟颇率、 l时钊'建立时 间、 时钟保持时间、 时圳' 剑输出延时、 管脚到管脚延时等. 下面具体介绍 各种时序概念。 6.4.1 周期与最大时钟频率 周期的概念是时子j 概念 巾最重要的 , 是 FPGAlASIC 时j序定义的基础。 其他的时序公 /250/ .8. 式都可以 由 周期公式推导而 出 . 如 国 6-8 所示电路的最小时钟周 期计算公式为: 元LK = TCKO + Tl.l.OG C + TN盯 + 7如up - TCLK S陆W TCLK S陆W = TCD2 -元01 ( 10-1 ) 其 中 • TCLK 为时钟的最小时钟周期 : TCKo 为寄存器固有的时钟输出延时: TL∞IC 为 同 步元件之间的组合逻辑延时: 1ì阳 为 网线延时; Ts盯山 为寄行器间有的�Ù:时间: TCLK Slro-1 noro-O nando-O noro 自B 8-5 组合门的寄存揣级结构 新建波形仿真文件 ,加入输入输 出信号,设置输入信号 a与 bo 保在被形文 件 为 bombinationgate.v w f. 单由总 进行组合门电路被形仿真,仿真报告如图 8-6 所示. • " 01 b DWO Doro I> datab? l'bl : l'bO; - asslgn nbigo dataa <.. datab? l'bl : l'bO; assign smallo - dataa < datab? l'bl : l'bO; assign nsmallo - dataa >z datab? l'bl : l'bO; endmodule c公布代码为 datacompare.v . 编译工程无出后单击Tools - NetlistYiewer →RTL Viewer,何看QuartusIJ 综合 后生成的 奇再苦苦传输级结构, 如j剧8-17所示 。 /280/ . da阳b[7 dataa[7 • 第8. 姐禽 lÆS l'HIIH LessThan2 lÆST子WI nsmallo mallo lÆSTt甜刷 LessThanO lÆS Tt制N EqualO blgo . ECIJIIι 阁8-17 fii届比较糙的2旨在撼传输级结构 l'(!.击Proc臼sing→GenerateFunctionalSimulation Netlist.产生功能仿真间表. 新组波形 仿真文件, 加入输入输山信号, 设置输入信号a、wr 与双向引脚的y作为输入部分的被形。 保存波形文件为由ta∞mpare叭. AIf.单击总 进行数据 比较器波形仿真,仿真报告如阁8-18所示. 国缸,".u � '_..h� .‘. 0.... b.‘. 抽 i , . ..-Wl. ....011. 阁8-18 敛Wi比驳格泌形仿真Jatei 队281 \ . 被形仿真报告说明z z均输入信号- dataa 和 datab发生变化时, 输出信号呵。、 nsmallo 也发生相应正确的变化。 neqo、bigo、 nbigo、 smallo、 8.7 各种加法器(ì.戚法器〉设计 在所有的算术运算中,加法器〈减法器〉 是使用最多的, 特别是两操作数的加法器. 因此,整个运算电路的性能往往由加法器决定.而对于加法器来说 , 最关键的部 分 是如何 对进位进行处理。 本草将对各种不同地 位处理加法器算法进行详细介绍 , 并 给出设计的 Ver ilogHDL程序代码. 8.7.1 f于波进位加法器 一个n位的B进制行 被进位〈阳pple-Car可〉加法器结构如圄8-19所示. 其 中, FA(Full Adder ) 表示l位全加器. x(n.l)兴n-I) x(l) )(1) X(O)沃的 :(n-1 ) :(1) :(0) 图8-19 行波迸仪Jnl法苦苦结构 全加器的法代 公式为: = �1 q(i+ 1) r 1, 0, 如果x()i + y(i} + q(i) > B -1 其余 ( 8-1 ) =z(i) (x()i + y(i) + q(i)) modB 令CFA和TFA 分剧表示全加器单元所僻的硬件资源 和 计 算时间, 贝1J n位行波进位加 法器总的硬件资源 和 计 算时间为: CbaSIC-由(n) = n.CFA Tb四川伽(n) = n. TFA (8-2) 根据式 ( 8-1), 二进制全加器法代公式可以写为: = q(i+ 1) x(i).y()i v x(i).q(i) v y()i .q(i) . =z(i) x(i)EÐy()i EÐ q(i) 其'11 , V表示逻辑或运算: EÐ表示异或运算. 又例如,十进制全加器公式为: (8-3) /282� 第8章 = r--‘lk un,L' nwa ,,.‘、 -t + 、‘.,, 如果x()i +y(i) + q(i) > 9 其余 =z(i) (x(i)+ y(i)+ q(i))mod 10 一个通 用的二进制 行波进位加法器程序 代码如下, 仿真 被形如圈8-20所示。 (8-4) //二迸制行放进位加法器 module rìpple_carry_adder(且, y, cìn, sum, cout); par缸l\eter N " 8; ìnput cìn; input (N-l: 0) x, y; output (N-l:0) s山l\; output cout; reg cout; reg [N-l:0j 5um; reg q[N:O); always @(x or y or cìn)begìn:ADDER integer i; q[OJ � cin; for(ì=Oi主<=N-l; ì=ì+l)begin q[i+l) = (x[i)&y[i]) I (x[i)&q[i)) I (y(i]&q(i]); ^ ^ sum[ì) - xli) y(ì) q[ìJ; end e cout q[N); end endmodule N 回 '‘ ...‘ cout 阁8-20 二进制行坦克进位为n法吉普仿真波形 8.7.2 进位链加法器 一个n位的单独的进位链(C缸叩- Chain) 计算的加法器如阁8-21所示。 队283\ • 应用程,设计实例篇讲 刻n-I)川11-1 ) 抖n-2) )'(,,-2) .t(1) .)1(1) I .t(n-I)川俨1) 刻n-2)刘仲-2) .t(1) >(2) 缰_Jf。如,_,,, .1'(0) 兴。) ••• :(n-I) ;:('1'-2) ;:(1 ) :(0) 阁8-21 地位链力urL吉普 其中, G-P (Generate-Propagate)单元计算生成和传输函数。公式如下: g(i)= Cf 如 -�果:x-('i- 10, 其余 ') + ,y(i) >B -1 p(i) r 1, �= 10, 如果x(i) +y(i)=B-1 其余 (8-5) 进位链单元计算下一个进位输出,计算公式为: q(i + 1)= 1�r q9,((íi)),, 如果 :p(i)=1 其余 (8-6) 模B和单元则计算: z(i) =(x(i) +y(i)+q(i))mωB (8-7) 令C(;P和TGP、CCyCh和Tc.,.c协CSWD和Tswn分别代表G-P且在元、进位链单元及模8和 单元所需要的硬件资源和计算时间,则一个n位B进制进位链加法器所需总资源和计算时 间为: ( C阳归baío-ad阳(n) =n. CoP + CCyCh + Csum) =马P + Tcarry-i:baìn-adder(n) (n-1) . TcyCh +凡町' (8-8) 因为几m>CCyCh'所以进位链加法器的关键路径如国8-21的阴影部分所示。 关于进位链加法器有以下说明. (1 )进位链单元是二进制电路,而G-P单元与棋8和1(1.元则是B进制电路. (2)进位链单元功能等价于一个二边一开关 ,如阁8-22所示.因此不管8取值为多 少,根据式(8-7 ),则进位链加法器每一位的延时等于二选一开关的延时Tmω进一步的, 生成函数可以放宽为: 1, 如果x (i)+y(i)>B-l g(i对0, 如果x(i)+y(i)>(_ 1:n-.r) 42..r-1 :.r})(2_r-I:.r) 4s-I:O) ><$-1:0) (8-10) o-P tfl元与门 G-P Il'l元与(I G-P lyl元J与f1 q{n)l|崎8-26 q(n-.r) I q(2..r) 刻 t 8-26 q(.r) I阁8.26 q(0) ($比特分组〉 (.r比特分组3 (s比份分组) q(n-I:n4) .. . q(2_r-1:s) q(.r-I :0) x(n- I :n4).y(n-1:n-s) .r(2..r-1 :s).y(2..r-1 :s) *-1:0) >(s-I:0) 模B.fU单元 模B和机元 接B ..ru 1'1\冗 ::(..-1:."..). :(2..r-1 :.r) 阁8-28 眺跃ill位加法怨结构挺图 ::(.,-1 :0) 进位链的关键路径如国8-27中阴影部分所示. 气进制跳跃进位加法器程序代码如下, 仿真披形如圄8-29所示。 //二进制跳跃涟位加法器 module caZEY-skip-adder(x-i n, y-in, c-in, sum, c-out}J parameter DSIZE = 12; parameter S = 4; input c �n; input [DSIZE-l:Ol x_in, y_in; output [DSIZE-l:Ol sum; reg [DSIZE-l:O] sum; output c out; r--··rae‘Mne l gt9w e a 凹,,··vdn『hw eDS『‘e qoSETA'』••‘• CmA毡--z(nc'Ek z a o··r uzcio3-tJln 『 y ;a ­ snoqaJrJk aA -ynF _ia nd Au or ­e av c_in)begin 电A 、ι { x -l n i CJV .‘ •• hu l , y -l n [ qu ,.- -- nu I , 队287\ q[O), q[S:1}); Lor(j=O; j<=S-l; j=j+1) sum[j} = x_in[j} 《 y_in[j] ,、 q[j} ; carry_skip_add_sell(x_in[2*S-1:S], Y-inI2*S-1:S], q[S}, q[2*S:S+1]); for(j=O; j<=S-l; j=j+1) sum[S+j] = x_in[5+j] ,、 y_in[5+j] ,、 q[5+j]; cazzy-sklp-add-cell{x-in[3*S-1:2*S], y-ln[3*S-1:2*S], q[2*S], q[3*S:2*S+1]); for(j=O; j<�S-1; jzj +l} sum[2*S+j] E x_in[2*S+j] ,、 y_in[2*5+j] ,、 q[2*S+j]; end c out • q[DSIZE]; end ,, ,, FD Ltv UVM task 将 臼 分 H且 口 Va input input 进 J ,i d 位链 收 叩' r- 1 nA ' ad -0 。 l d -几 c ' e 、.在 '·品· y; 。utput [5:1] cout; reg q[S:O), p[S-1:0], 9[5-1: 0], accumulator, integer i; begin q[O) • cin; for(i-O; i<-S-1; i�i+1}begin P[i] E x[i)^y(i); g[i) - Y[i] ; q(i+1) 砸自Z (p[i])?q[i] :g[i) ; end accumulator .. p (0); for(i-1; i<-5-1; i-i+1) accumulator E accumu1ator & p[i); generalized_.p; generalized_.p .. accumulator; cout[S) - (generalized_.p) ? c io • • q[S); for(i回1; iO) pin[i+l] [j-1] = pout[i] [jJ; end pin[i+1] [M-l] = 'bO; end for(i=O; i<=M-l; i=i+1) p[i+N] - pin[N) (i) + cin[N] [i); end //进位存储乘法器基本单元 task basic_rnul_cell{input x i, y_j, cin, pin, output cout:, pout); req lnt-PJ begin irIE-p - x-i & y-j J cout 跚(cin & pin) I (cin 晶 int:_p) I (pin & int_p); pout - cin ^ int_p ^ pin; end endtask endrnodule τb. 1&1' f 1. . 0田 二éJr .,n. ... . r丁瓦晴圆 tn-tcr咽1: -521.12... 副町.. 。 ... &nd. .r巳一吨P ET 一一旦f.'" 4.80 . 0 ,. " 0.. 0 ". 回回· , 倒8-39 准位仔俯乘法�伪i工放形 8.9 伽罗华域GF(q)乘法器设计 伽罗华(Ga。l 这〉域又称有限域, 是指元素个数有限的域。 域中元素的个数称为域的 阶, 通常用GF(q)表示q阶有限域。 伽罗华域越来越广泛地应用在.倍迫编解闽、 计算机代 数以及椭圆1111 线加密等. 存限域的最大优势是其运ff.简沽、 没有精度丢失。 此外, 有限域 的特点使其易F用VLSI邻硬件实现. 下面将详细介绍伽罗华域乘法器的设计. 队297\ 帽到L应用疆原设if蜘j糟讲 8.9.1 应用背景 由于 Reed-Solomon (RS) 码具有同时纠正突发错误和随机错误的能力, 且纠正突发 错误更有效, 因而被广泛地应用于 数据通信和数据非储系统的差错控制中. 以作为提高数 据传输和数据再储可恬性的重要予段o RS码已经成为美国航天局(NASA) 和欧洲空间站 (ESA)在深空通信级联系统中采用的标准码.此外, RS码也是存储器系统中的标准用码。 RS码的编译码算法-f(是因际通信领域研究的热点问题之一. RS码是定义{r:行限域上的, 般有限域上的运算对FRS间的编译码过和来说足卡分重 要的。 其中最引人注门的有限域运算是乘法, 吓多工作占I�集中在寻找一种合远的打限域果 法器, 以使其便于VLSI实现。 在众多的有限域乘怯器中, Berlekamp和Massey-Omura比 特串行乘法器、 M筒衍ovito比特井行乘法器用于RS 码时, 更能显示它们的优点. 特别是 Berlekamp比特吊行乘法器应用于RS码的编码器时硬件最简单, 但在RSlí!斗编码器设计巾, 当数据吞吐率较高时, 由f Bedekamp比特$行乘法器涉及到两个基, 比特::þ行的运算较 难达到设计的要求. 通过引入最优对偶榕的概念. 得到了用于RS码编码器设计的最优对偶幕. 并且采用 该最优对偶蓓构成了比特)j�行有限域元素乘怯辘, 由这样的乘法器构成的RS码编码器达 到了较高的数据吞01:丰。 在本节中, 我们使用弱对偶基 (weakly dualbasis, 简骂为WDB)的概念, 给出了一 种新的比特并行有限域元素乘法器, 从而使得RS码编码器的设计达到较高的系统数据吞 吐率, 并且复杂度也较低. 8.9.2 理论算法 1. 有限域元寰的弱对偶基表示 记布限域为GF(2勺, 设α是手�-II昆域GP(2勺的本原元, 则有限域GF(2m)上的所有非军元 素均可由α的不同研吹来表示, 其分别为{ldd声,…,dFM}. 若利用有限域GF(2tn) 士1 的本原 多项式: L p(x) = xm + PIX' ,事。 (8-18 ) 则 GF(2勺t t!J=b-, b4 =b6 bs =bs bi,=b4 b7=l>J+z" 因此, 可以得到该基的变换电路, 如回 8-41所示。 bø bl b1 bl b. b, b. b:T (8-31) bó岳bi bj b; b; 0;'的 因8-41 多项式签到j弱对偶基坐标变化电路 2. 弱对偶基系数扩展 由式(8-27): b;4=TrUBdZLdhZLTrUBd+I)=ZLbL,l=0,1,2,-H,m-2 1:0 ;:0 i=。 和式(8-28): f(x)=x8+x4 +x3+x2+J 可以求得弱对 偶基下扩蜒的系数, 其计算公式为: bJ+I=bJ+44+b;叫+b;+I' (1=0,1, …,6) 式(8-32) 可以进一步写成: t也=b;+b;+b;+b; 时=bJ+bJ+b;+b; 均=b;+b;+b;+b; 品=时+b;+b;+b; (8-32) (8-33) bi-z=b;+b;+b;+t4 品=b;+b;+bj+bJ 吟=b;+td+b;+后 /3021. 一 第81挺 式(8-33) 对应的硬件电路如图 8-42所示. b; 玩 bi b) b; b; bj. b1 + + + φ 4 「可+ + + + t咱 " 问. h;1 b1.1 创, 比 因8-42 ��j对倘J在系数扩展电路 3. 乘法模块 根据式(8-26): c;=c;.0a0+c;:.J肉l 以]J{止对应的框图 , 可以得 到GF(28)有限域下弱对偶基乘法公式为: cj=bJao+da1+时的+bj03+bh4+bhs+b;06+b;07 c;=b;ao+b;a1+b;oz+bh3+bh4+bias+b;06+bJa7 C2 =bioo+b)01 + b402+仇.的+b-i,.04+b7as+句句+b9a7 4=b;ao+bhl+b;02+bJa3+b;向+bjas+bJ06+bha7 4=b;ao+bht+bjaz+抖的+404+时as+b;006+b:107 4=b;ao+bjal+b;02+bj03+砾。4+均as+b:106+向飞07 4罩b;ao+b;01+tda2+时向+鸟飞向+b;105+bho+句:07 c;=bho+bjaI+b;。2+bJ003+b:104+叫:205+td-306+b;407 ( 8-34) 所以, 可以得 到框剧 8-40中乘法模块的硬件电路 如回 8-43所示. 剧中片给出了一个 乘法器电路. b; 00 b,时0, b;.2 U� b• ,时 UJ b•• ;.4 0, b;.� 0) b;吨。• b;_, 0, 令 C, 阁8-43 嘱ik;模块1也路 \303\ 4. 弱对偶基到多项式基坐标变换 由武 ( 8-30) 可以得到从弱对偶基到多项式基的坐标变换关系为: Co =C2 CI =CI • • C2 =Co +C2 • • C) =C) +C7 C4 =C6 Cs = Cs C6 =C4 c7 =C) 因此, 可以得到该基的变换电路, 如圈 8-44所习2. .. Co .. C, .. Cl .. C) .. C. . c, .. Cð .. C, (8-35) 「 飞f二.:,、.J /\Tμ..、 - 、- Co CI C2 C) C4 Cs C6 C7 阁8-44 弱对偶基到多项式稳坐标变挟(I!.� 8.9.4 弱对偶墓青限域乘法器程廖说明 在介绍完GF(28)域的弱对偶基有限域乘法辅的理论和硬件模型后....$:节给出有限域比 特 并行乘法榕的VerilogHDL语言程序代间, 以且相应的程序说明。完整的程序代码如下。 //行限城 GE"(2 8)弱对偶基乘法 然 //"4哺i多JDi式: p(x) = x^8 + x^4 + x^3 + x^2 + 1 //多项式J.l;: (1, 旷1, 矿2, a^3, a吁, a^5, a吨, 旷7) //$j对倘�: (1+a^2, a^l, 1, 旷7, a^6, a叮, 旷4, 矿3+旷71 'define M 8 module ff mul(dinl, din2, dout, dual_base); //parameter CONST = 8'h3b; i.nput ['M-l:O] di.nl, din2; 。utput ['M-l:0] dout; 。utput (2.'M-2:0] dual_base; reg ['M-l:0] dout; //din2íi后变转换到3局对偶堪 !304!J '自8到E reg (2*'M-2:0] dual_base; reg【'M-1:0] temp: always @(din1 or din2)begin: Block1 integer i; //多项式基到对偶基坐标变换 dual base[O] dual base[1] dual base[2] - dual base[3) dual_base(4) dual base(5) dua1 base [6] dua1 base[7] = din2 [O] � din2[2]; = din2 [1]; = di.n2 [0]; = din2(7); = din2[6]; = din2[5]; = din2[4]; = din2 [3] � din2 (7); //对偶基扩展 for(i-O; i<'M-1: i=i+1) begin dual base ['M+i) - dual base [O+i) .1 base [2+i) ^ dual-base I3+11 《 dual-base[4+i]J end //多项式基与对偶基相乘 for(i皿0; i<'M; i-i+1) begin temp[i)-(((dual_base[i+O]品din1 (O])^ (dual_base (主+1]&din1 (1))) ^((dual_base [i+2)&din1(2]) ^(dual_base (i+3] &dinl [3]))) ^(((dual base [i+4]&din1 [4])^(dual base [i+S]&din1 [SJ)) ^((dual base [i+6]&dinl [6]) ^ (dual base[i+7]&dinl(7)))); end //将#民法结果从对偶基变换董Ij多项式基­ dout[O) = temp(2); dout[l] = temp [l]; dout[2] = temp [O) ^ temp [2]; dout (3) = temp [3J ^ temp [7J; dout [4] = temp (6): doutlSJ = temp (5); dout (6] - temp(4); end dout[7] = temp [3]; endmodule 图 8-45给出了GF(28)弱对偶基乘法器仿页.被形, 读者可以与表8-1给出的部分元素乘 法表核对. 队305\ Æ_叫HDLØJ照原阴阳 !IrJllI 011111'1 1"'1'01 I :--'Im川 l 凰 "'tr Tt.. l.ar't '恤. 匾' 削川 .剧 -m 二J.:JrOlme.n'--1... 22国 ["'...11 1.22田 Stu-t1 一 - JF旦 旦一喧F P国 1 . !1.. 1. '1咀 1,回2 1.9夺回 1• c • 阁8-45 基于itH尚筑的GF(2')J民法然仿真被形 S'h03 (。当) 8'b04 (al) S'ω5(0") S'h06( a:l& ) 8'h07 (0'喃} S'b02( al) S'h06 (a2• ) 表8-' GF(28)部分元'候,民法表 S'b例(a 2) 8'b创í{a2e) 8'ω8(a� } S'blO( o' ) l!'hlE (a"‘} S'b3O( a�) 跑'bOA(a刷) S'h36(az... ) 在很多有限域乘法内HjLjI, 常常会肘剑常系敛乘法器. 例如, 在RS t.liu间锦和译码器 '1"'都包含大帘:'Î;f;系数乘法措。 $.然, 在这吨们况下使用常系数乘法揣将会节约旦窑的阳件 资源, 并且能提阳系统的运行边J主. 下面的程序代阳为参数化的常系数行阳城呆泌姆, 其中参数CCONsn为树对偶基下 的常系数乘数. I大l此, 乘法端不语要再对其中一个乘数i址行多项式延到��元I倍;格的电标变 换. 例如. 吗CONST=15'hOCE7时对应的常系数为 8'h3B(α12、 //常系数有限Jå乘法滤 //本除多项式: p(x) - x^8 + x^4 + x^3 + x^2 + 1 //多l'�式码: {l, a竹, a吁, a吁, t4, 旷5, a吨, a^7} //弱对{/.且应: (l+a吨, a勺, 1, a^7, a^6, a^5, a气, a^3+a^71 'de fine M 8 module ff const mul(din, dout); parameter CONST = 15'hOCE7; input ['M-l:O) din; out:put: ['M-l:O] dout.; wire [2*'M-2:01 dual_base; assign dual_base � CONST; reg ('M-l:O] dout., t.emp; always @(din or dual base)begin: Blockl /306/ integer i; //采法运算 for(i=O; i<'M; 1=1+1) begin temp [i)�(((dual_base [i+O)&din [01) ^(dual_base(i+l) 品din(l))) ^((dual_base [i+2)&din (2)) ^ (dual_base (i+3J&din (3) ) ) ) ^(((dual_base(i+4)&d i n ( 4))^(dual_base (i+5)&din [S))) ^((dual_base [i+6)&d in [6)) ^(dual_base[i+7)&din[71))); end //弱对俑基到多项式恙交换 dout [O) - temp[2]; dout [l) - temp(11; dout(2) - temp [O) A temp(2); dout[3) - temp[3] ^ temp[7]; dout[4] - temp [6]; dout[S) - temp[5]; dout[6) - temp (4]; dout [7] - temp[3); end endmodule 国 8-46给出了基于对偶基的GF(28)常系数乘法器仿真波形, 表 8-2为对陆的GF(28) 部分元素乘法农. 读者可以自行验证. S'h3B ( a'lØ) "‘.‘ . 也!f - J,.�曾· .ι" • 00 8-46 基于对偶基([.J GF(28)常系数纳法是苦仿真汲* S'bOl(ao) S'h3B ( a'lO ) 表8-2 GF(28)部分元'晨,使法表 1'bOl( a') S'h76( a'1' ) l'M)3(a篇} S'h40( a'崎} l'b04(al) S'hEC(a'11 ) 1'11a1剧 萄} S'hD7( a'回) 8,10 常用除法器设计 下面将介绍几种常用除陆器, 并给出相附.的详细的设计实例。 8.10.1 二进制恢复除法器 给定m lt特归然数X与n比特整数y, UP: O�三X<俨和1运Y<2", 则X除以Y的整 \307\ 数除法器可以表 示为: X=QY- +R, R0→q(5) = l, r(5)=3968 -3840 =128, 2x128-3480< 0→q(6)=0, r(6)=256. 2x256-3480< 0→q(7)=0, r(7)=512, 2x512-3480< 0→q(8) =0, r(8)=1024, 运算结果是: Q=8, R = J024/256 = 40 一个二进制路数恢复除法器结构如阁8-47 所示, 其中的基本单元如阁8-48所示. /308h q(m-l) 2,�0>-X m ∞.. .0 n 2-I,y 附m-I IIttl:运" �本依元 "材,,-1 .8. Q_by_2{n..0) 例,,-1..0) q(m-2 除泌iam �.t.:1'f\元 n+m�1 . .. t{m-I) q 符号 >i); bnext = bin + 1; gnext = (bnext>>l) ^ bnext; end endmodule // Gray码到;近1M阴转缺 11 ._.iJ.tl例阴到Gray问转狼 -Mõ:Ô " "ne:r' Tla c I&r ; po lu‘ .:1:J""n:,-G' : 拥. ,.,. ltnt1"W"l1 1 吁02. zl田 $,..,. " 110. ‘9 " 一 I鼠二 。 .. 2愧 - 。. .. 一n队.。‘ " CI� r"_.n 11 ""'Y • ‘蛐飞 州)_..Qt;. .. .口t3 ‘盹。" .1. ‘ • 1. 、 剧9-5 Oray码计数量量仿具波形 9.2.3 Johnson计数器 J ohnson 计数器是把 n忧移位 寄存榕 的 串行输出取反, 反馈到串行输入端, 构成具有 2n种状态的计数器. J oh nson 计数器丁 作原理如下: ( 1 ) 如果当前计数值的 陆岗位为 1 , 如l执行地低位补 0 的 左移操 作. (2) 如果当前计数值 的 藏高位为 0, 则执行最低位 补 l 的 /r_移操 作. 以 3 位 J oh nson 计数器为例, 其计数 顺序依次为: 000→00 1→O川→ 1 1 1→ 1 1 0→100→000→… 下面给出了J oh n son 计数器姐 棋实iýlJ. 其仿�l披形如国 9-6 所示. 'de=ine WIDTH 3 module JohnsonCounter(output reg ('WIDTH-1:0) JCounter, input clk, input rst_n); always @(posedge clk or negedge r51:_n) if(!rst n) JCounter <= 0; else begin if(JCounter[WIDTH-1)) \319\ f面附比 舰部酣实伊j黯讲 JCounter[WIDTH-l:OJ <- !JCounter[WIDTH-2:0J, l'bO}; else JCounter[WIDTH-l:0J <- !JCounter(WIDTH-2:0J, l'bll; End endmodule "UIII川、时 Z 01111',tllI( l二 :J"'llIl 1. • 阁9-6 Johnson it鼓楼悠模仿兵被形 9.2.4 可预置加减计数器的设计 牛;节描述 的 计 数 是 可控的加减计数, 计散周期可以预先设坷, 并用 Verilog H DL 语言 也 棋 IJ1Jj页, 代码如下: module mycounter(clk, ud, cntp, cntout); --A ·' n nPpU UV←E- clK udJ 」 -l n噎 e npU争 。 -­ u』hu - ut L PH E rt 7· · I7 H ntP J · enE OU 争L ., ,, 系 统 时 钟 f, J, 计 做 指 川 减 控 制 f, J, 蚀 设 计 数 川 刷 /, 川 J, ,r 汁 数 结 刷刷 输 出 nu 为 、,& 川H 数 . 咱自& 为 输切hw" ‘.• ·俨· 灿 reg [7:0J cntout; reg [7:0} cnt; always @(posedge clk) begin if(l'bO = ud) 11作却I 1计放 begin if(cntp ..= cnt) 11飞ì�数极b11 "1"至与俄设川i刷一致时, 则计童u量i�(苓 begin cnt <- 8'dO; end else beg主n cnt <草 cnt + 8'dl; end end else if(l'bl == ud) /320/ 第9章 时停电蹦蹦蹦飞 begin if(8'dO == cnt) begin //当计量k器减4.1 1 " 至U O,f时, 则计数量器设为职设周期 cnt <= cntpi end else begin cnt <= cnt - 8'dli end end end always @(posedge clk) begin cntout <= cnti end endmodule 保存代码为 myco u nter.v, 编译工程无误后单击Tools → NeJt i st V Îewer →RTL Viewer. 查看 Quartus Il综合后生成的 寄存器传输级结构, 如阁 9-7 所示。 _0 幅凰 ""Øl ..., ' ""捕前 fqYlll 恤- ... EquaKJ '画"、 蛐.." 。l 阁9-7 计数器的寄存络传输级结构 队321 \ /'.问毗 回酬谢+卖帽瑞 值得注意的 是 . 作械法的语句: cnt <= c n l - 8'd 1;, Q uartus 1 1 的综合格实际七为其 综合成了一个加法, 两个 加数 都是 9 位 的 , 其巾一个 加数 由 c n作 t 为 低 8位和 地高位为 " 1 " 组合而成, 另一个加数 为 9 'b l FD. 也就是 减法足转化为 补 码 的加法来操作的 , 如 国 9-8所示。 Add1 ADDER 回9-8 作减泌的寄:fï.器传输级结构 新建波形仿真文件, 加入输入输出信号, 设 置 输入 信 号 clk 、 ud 与 c ntp. 保存披形文 件为myc ounter.v wf. 单市&进行计数器电路波f�仿真, 仿真报告如 图 9-9 所示 • • lk •• liI咽\o.t 百Tl E -a�曹 fOYI1mff YIQJ( 9 ‘ S阻" 11 因9-9 计数器电峭的法j路仿真报告 被形仿真报告说明z 输入信号时钟clk, 加减控制信号 ud, 计数周期c ntp, 输出信 号 c nto ul. 从国 9-9 可以 有rtll . 计数器在加减控制信 号的控制下进行加减计敛, 计数周期也是由信 号 c ntp 来决定的。 9.3 两种分频器设计 分频器是时JF电路的基本器件, 它的功能 )ex.t系统时钟或其他时钟进行分颇产生所 市 览的时钟信号. 分额 有两种方式: Ve副og HDL 语古建模产'-t所需要的时钟信号和利削开 ð{_丁具的PLL 进行分频. 前苦分额灵活, 分频布ì�编写代码实现, 而且有的 低端 FPGA 没 打P LL. 只能使山这 种方式来实现: 后 省相对来说效果要蜂些. 而且在进行小数分频时也 比较容易实现. 本节分 别对以 上两 种分频器进行 Verilog HDL 语言建模与仿真;."0 9.3.1 Verilog HDL分频器 �W描述 的 Verilog HD L 分频器的分颇系数可以 预设, 时钟的高 电子占世比可训。 只. 体代码如下: 13221 第9. m odu1e vclk div(clk, clkperiod, clk low, clkout); input clk; Lnput [7:0) clkperiod; i np ut [7:01 clk low; outp ut clk out ; //系统时钟 //分级系数 / /低电平占用系统时钟的周期数 reg clk out; reg (7:0) cnt ; alw a y s @(p ose dge clk ) begi n if ( cnt -- clklow) beg in clko ut <= l' b 1; cht <= cnt + 8'dl; e nd else if(cnt == clkpe ri od) begin c1k out <= 1'bO; cnt <= 8'dO; en d e nd / /当计敖楼达到clk low 时, clk out 设置为向 //当计数器达到 c lk pe riod时. clk out设货为低 endmo du le 新建波形仿真文 件. 加入输入输出信号, 设置输入信号 clk、 clklow 与 clkperiod. 保 存披形文件为v clkdvi v. wf. 单击巳|进行分频器电路被形仿真, 仿真报告如 图 9- 1 0 所示。 .u. Ii clkl.... 国 d峙ui.d ' .u...‘ 图9-10 分领榕的旅形仿真报告 被形仿真报告说明z 输入信号时斜1 c[k, 分频系数 cL均由od, 低电平系数 clk1o w , 输出信号 clkouot 从罔 9-1 0 可 以 看 出 , 输出信号 clkout确实在系统时钟的 10 分颜, 而且低电平和 高电平各占5 个系统时钟周 期 , 高电平占空 比为 50 % 。 更改低电平系数为 7, 保存文件, f(!.击'已迸行披 形仿真 , 再次得到波形仿真报告如 图9-川 所示。 �323\ 崎Dt. 应用程摩由于实f归属讲 c1k liI illI_ liI eU.p....4 c1k。川 图9-11 分领器的法形仿a报tE 被形仿真报告说明z 对国 9 门 - 道行分析得 知 , 输 出 信 号 clkout 在系统时钟的 1 0 分顿 , 低电平的系统周 j例数 为 8, 向电平的系统周期 数为 2, 问电乎占空 比 为 20 % , 分颇桦 的分频功能得到正确 捡证. 9.3.2 PLL分频器 Altera 公 司 的 中高档FPGA 一般部带有 PLL, 数目lJ� 一个城乡 个。 P LL 的 监 盟灵活 , 能有效地对系统进行分频、 借 频和 延时等 处理 。 本节将一步-tt;讲解 PLL 的 应用。 ( 1 ) 新iI! 一个工和l vpll, 选择File →New命令新il! 一个原肝.圄文件, 部l困9-12 所 示 , 并保非文件负� vpll.bdfo 。向D叩Fiea I O� F1eo I �___:旦J 阁9-12 新ti!lhiJfl!阳文n ( 2 ) 双ï1ï原理国空白 处, 在弹出的S ymbo1 对 话'1'在j 择allpl1, 岛主,I:i OKf主旬H且 出 , 如 国 9 - 13 所示. (3) 在 伸 出 的 MegaWizardPlus-In Manger 对话挝中. 11摊HDL 珉,丁 为 驰而og HDL, 设 22输出文件为 ahp110 V., 然后单击Nexl 按钮进行下一 步 设 泣, 如 回 9 - 1 4 所示. /324/ IIU�晒I,e 嗣D;U阳,矶呻 帽凰" 第9章 时刷刷唰飞 , 咀-民 - a帽"、 "'" 、, .割 .、. " �:. ".."h<"J氢."1 • hF 牛 .、 」 ra.田...嗣啕 「如…·圈..11"'"由刷刷呐_'"仲 刷刷牛 刷 l I � I 一旦J '… 圄 因9-13 缺;快法锋图 l灿lIIi 8,_ I '由蛐国阪FT陆o国.嗣. ..Þ.-.o. 刷h.ø._咽蝇田面d目峙曲,、阜.".I.。h叫o (血.l1l<串..00.帕.t喃b帽.恤.,. 回回制" ...嗣同6向阳口睛'嗣同4.c..唰tb崎刷刷 "IhoU嗣l.b_阳QO"' ... s..p ) � .. 副.iÒ_ -由 11 ... .. ... .. 护 E EE ;一3 hm"响筐 嗣 同! �_. 回国 ..。崛句剑"圃.­ (þ �, 囱9-17 PLL参敬设咒〈问〉 ( 7) 在弹出 的对话框rll进行第-t个 输IJJ n't钟分频系数的设哇 , 设 置为 2/ 1 . 即 2倍· 频: 延时为O . 即没有 延时:占空 比为25 %, 如l图 9-1 8所♂. 。 . CIrn CWJItI; OIÓ "…闸-吗h帽嗣睛...刚 'ω..ihI.,‘ QdIr..5entf: 缸..砸.-.阳_, . "….… . 伽…… 曲。"田�.,... 。.. . ..腼._ 。.�. 掷匾,确 。呻钱....事'" 1........1 …i r EL F 哩t J ... 冉腼 问.""翩翩蝇, .自 ..­ 剧目 阁9-18 PLL参徽设手!t'(1'i.) \327\ 后画向阳. 朋部部十实伊j黯诩 ( 8,)在弹出的对话框 中 进行第二个 输出时钟分频系数 的 设置 , 选 中 Enter output c10ck frequency, 这种方式为固定银率分颇, 即不需要进行分数计算, 只需直接设好.所需要的频 率就可以 了 , 如 图9-9 1 所示。 �......." .腼崎岖‘四. ,_.副始--防咱 --…_. 。瞄-..嗣恤' 。...帽内- @刷品商F蛐 阳"阑-- ‘OJ翩翩陶· 售 1虫. �由1 � I J .cc. ."�-=-:=.-:-_;币 M4· 田二{ '恤‘"�N Øë-->tl 画... � .. --叫一 俐. " 1'" 因9-19 PLL参放设�(六〕 (9)在弹出的对话握中单击Finish按钮完成PLL参数设置, 返回Symbol对话框, 单 击 O K按钮退出, 如 图 9-20 所 示. _ zs..x..响z.,z.,..a..mL.暂m."‘a1htm _�u ..� z… zt z-z回· " …-帽-向·梢帽"…"圄刷帽、 ar--川…叩阳叩阳巾… g. 旬. 啕. 嗣-眺,、 .. ‘ Egh c_" 1iI"曲崎 E鸭.... 岖 a西刷 口 .龟 .,.四 、 �-栩咽 啕吨曲-.. 百d 丐 ‘ 四副‘ 局 阳 .唱 ._. _ 1'f'I'"愉­ h啤恤.,. '"民剑 ... ...‘"'_­ - _ . _ 回险 … 帽 _ .. _ "'" 阳'也 ... .. .崛 .. …· 俑_ .'‘-吨, ‘四唱!o-四"她喇 /328� 阁9-20 PLL参政设进(七〉 第9章 时序"画丽画或入 ( 10) 在原理国的 适当位 置 放 置 altpllO 模块, 并添加输入输出模块, 更改输入输出模 块名称如 阳9-21 所 示 . aft例。 ... ...- 制PH6T 1...盹U ne脉。 _ 帽.忧".. ^。I,_.刷 .ω. - 刷町" 、 苗 ._ 。".刷., 刷... 。"帽'回蛐捕.. Norm. I IC;OUI el t'rI霄.I .... �、 ct帽, ...""。 ca. R..。 问t唰 DC (、 CO ‘自 。 ∞ 5"000 ω IDC 阳回 ... . ,"能槐,.. .' 2:、 。∞ 宏50。 .。 1 m 。 。 。 捕∞ 1M ' c, c�阳 阳9-21 PLL模�连战阁 ( 1 1 ) 保非代码为 叩门.bdf, 编译工程无误后单击Tools →Neùisl Viewer →RT LViewer, fi后 Quartus 11 综合后生成的 寄存器传输级结构, 如 国 9-22 所 示 。 altpllO:inst clkone clktwo Irc曲。 clke clklock 图9-22 PLL寄存器传输级结构 新lJ!波1�1Jj其文件, 加入输入输出信号, 设 置 输入信号 c1ko 保存放形文件为 vpll.vwfo 单击恳地行分频器电路被形仿真, 仿真报告如图 9-23 所示 . a.. I 圃.. 0,_.一.1IC . 1Ic. .:u..n. Û)r\.... d凰0<10 罔9-23 分额2量也赂的旅}在仿t4�bH斗 •• T20 0.. 800 . 被形仿真报告说明z 输入信 号时钟 c1k, c1ke 为 60MHz 频率输山, clkone 为系统|时钟 0.8分颇, clktwo 为 系统时钟 2倍额, 且占空比为 25 %0 从图 9-18可以 行 出 , 以k各个输出时钟 达 到 设 置要 求, PLL分颇器的功能得到正确验证. 9.4 两种移位寄存器设计 移位 寄梓器包括通用移位 寄存器和 桶形移位 寄:(f.器,它们各有特点, 下 面分别进行介绍. 队329\ • . /....崎阻 四四部f实附 9.4.1 通用穆位寄存器 下面 描述了一个通 用移位 寄在器, 此例可 以实现串入申 出 、 净入并 出 、 并入并出浅井 入南出。 该通剧移位 寄存器具有如下一些功能: · 储存数据: • 丘移/右移操 作 : • 加载数据. module UniversalShift(input clk, input rst, input left_in, input right_in, input [2:0) parallel_in, input [1 : 0 J mod, output reg (2:0J reg_out); a1ways @(posedge clk or posedge rst) if (rst) reg_out <= 3 ' bOOO; else case(mod) 2·bOO: Eeq-out 〈={req-out [1:0 1, EiqhE-lnl J 2 ' b01: reg_out <= ( left_in, reg_out[2: 1JI: 2'b10: reg_out <茸paralle1_in: endcase endmodule //丘移 //右侈 / / 并行输入 iìJ1用移位 寄非黯的仿真被形如图 9-24 所示. E110",., �"",..1 ...tc:r Tua kr: 川田 二l.:lro1nt=( 而.hx- EMmzz姐回,. S"r'‘: .... clk 1'1t hf‘_10 H‘tu_ln .06 ø.nllel..In nι ...' ‘ > I‘ 口� lhd: I , 阁9-24 通用移位部rn�仿真.被形 9.4.2 桶形移位寄存器 在现代高l:R阳S C 1傲 处器里 , 为 了实现在单时钟j司JIf)内各种白速的移位操 作 , 邢普遍 采 用相i}�移位 寄布,器 ( barrel sh ifter)来实现。 ba r r el shifter 已经成为R lS C 系统的一个重要 • 1330/ 第9章 时序电路酬·炜、 组 成部 分, barrel shifte r 设计 的最终面积与速度, 直接影响着较个 阳sc系统的性能。 1 . 参数化的桶形移位寄存器 下面例子描述了一个 参数化的桶形移位寄存 器, 具有循环东移功能. 仿真被形如1圈 9-25 所示。 module BarrelShlft. (din, rotate cnt, dout); parameter WIDTH = 6; pararneter CNT_SIZE = 3; input [CNT_SrZE-l:O) rotate_cnt; input [WIDTH-l:O] din; output[W工DTH-l:Oj dout; wire (WIDTH-l:O) temp; assign {dout,temp} = (din,din) << rotate cnt; 1/上面的赋值谐句与下丽的语句邻价 1/ Idout,temp} 嚣{din[ (WIDTH-1)-rotate cnt::OJ, // {rotate cnt(1'bO}}}; din[WIDT日-1:0], Endmodule 一- … 二 Tlu ß:a.r: 一 也… 川 回 到. .8r.0.01n.1c.r:1俨 一 - 1.8 一 'S N; JnU 剖"o.. O IU .,.. 1:'一 、-9 1l . %T,. 51抽 0 "" $'t u t 霉 : 0 国 ..40 . 圃 ØI lla.u 一 '一 _' -m� W: 0 ", ·'晶-P 回 ‘ , , 闯9-25 barrel shífter仿真被形 2. 寄存器输出的barrel shifter 下úñ实现的足组合逻辑的 barrel shifter. 但是在实际应用中往往前要寄存雄输出, 用 以分割细合逻辑。 其仿真波形虫11阁 9-26所示。 module BarrelShiftReg(clk, rst, din, rotate_cnt, reg_out): parameter WIDTH = 8; parameter CNT_SIZE = 3; input clk, rst; input [CNT SIZE-l:0] rotate cnt; input lWIDTH-l:0] din; output [WIDTH-l:0J reg_out; 队331 \ 2司马酬. 翻噩霹殷实唰诩 reg [WIDTH-l : O ] reg_out; wire [WIDTH- l : 0 ] barrel, temp; assign (barrel, templ e (din, din} << rotate_cnt; always @(posedge clk or posedge rst) if(rst) reg_out <= 0; else re9-。uE 〈zbazrel J endmodule !u' s "' U 1 " Th . w.雹 . …I n' 匾r'."e_.咽t 11 dln 画...、剧' 川回 •• 二1:1r. l"!r:r, l6C 儿 。 " 220 . "" l"t.,...- I , . �l' ", . 1 肘 . , -… . ‘ 舶.0 ..剧 。.0 .. • I‘ 民19-26 衍存稽输出的barrel shifter {!j '" -nt3 lnO . … , 0 "" ' 9.5本章小结 本章以代码和仿真阅结合的方式, 介绍了。触发器、计数棉、分频器和移位寄再器的 Verilog RDL 语言建校与仿真设i十. 时Jl-:fJI也路A数字电路平11 FPGA设计的基础, 华掘并 灵活运用时ri�f J电路刘复如电路设计起在f关键作川1. 带望i卖行学习时领悟各实例的特点. /332/ 第 存储器电路设计实例 存 储器在FPO A 设 计小 可分 为 两 类 : 一 类 是 FPO A 自带 的存 储 单元, 这些存 储单元可 以灵活 设 置成R OM、 S RAM 、 F IF O &. 所需 - 要 的其他形式 , 使用方便:但是 FOP A 白带 的 存 储器一般 是与FPGA 的等级相对应 的 , 等级越高, 存 储 器容量越大 , 价格也就越高。 另 一类是为 FPO A 外部设置一个 专用存 储辙 , 它们的最大优点就是存 储容量不再是问题:但 是它们一般具有专一功能, 要么是 ROM. 要么是SRAM. 或者是 F1FO 等 , 而且操 作也比 前一类更为复杂. 本章分别 介绍上述 两种存 储稽应 用方式的 Veri10g HDL 语言挫模与仿真. 10.1 片内ROM的Verilog HDL建模 本节利用 Verilog H DL 语言描述片内R OM. RO M 的存 储 容奄为8* 8. 代码如下: module chipromone(rd, addr, dataout); input rd; input [2:0) addxi 。utput [7:0) dataouti // i卖俯号·. 低1ì效 / / R OM地址信号 / / ROM敖据信号 reg [7:0] àa�aout; always @(rd or addr) begin if(l'bO=rd) begin --利用case i着句对ROM过�H赋和IJ{t( case (addr) 3'bOOO : dataout <= 8'b00000001; 3'bOOl : dataout <- 8'bO OOOOOlO; 3'b010 : dataout <= 8'b00000100; 石、崎岖应用酶酣实唰诩 3 'bOll . . dataout <= 8'bOOOOlOOO; 3'bl00 : dataout <= 8'bOOOl0000; 3'bl0l dataout <= 8'b00100000; 3 'bllO . . dataout <= 8'b01000000; 3'bll1 . . dataout <= 8'blOOOOOOO; default dataout <= 8'b00000001; endcase end else begin dataout <= 8'bzzzzzzzz; end end endmodule 保布,代{i马y.) chipromone.v, 编译工和无误后. 1Ft市Proc essing →Generate Functional SimuLation Netlist. 产生功能仿真网哀. J'(!.击Assignments - Settings. 弹出 Settings 对 话 框, 选摊 SimuLator Settings. 设 置 Simulation mode J-J Functional. 新边披}在仿真文件, 加 入输入输 出 信 号 , 设 置输入倍号 addr 和 rd。 保得 被形文件 /-J c hipromone.vwf. J1ji ll:r思!进 行片内ROM 存储器被形仿真" 仿真报告如图 10-1 所示. r x r. 阁10-1片内ROM仔储榕的法形fJj兴f银行 •• 被形仿真报告说明z 输入ROM地址信号 addr. i共控制倍号 时, 数据输出信勺. dataoulo 川剧 10-l illH分 析得知, 数据输出信号:- dataout I亏代码中 描述的数据相对应, 片内ROM ill 模得到ü正确仿真。 10.2 片内ROM的LPM应用 当;后要 描述的在储容量比较大 时 , 上节中的 Verilog HDL m1i建 模的方法就显得有点 烦琐了 , 用户可以利用Quartus白带的 LMP 模块来进行ROM ill棋 , 以解决 存储容hl: 较大 的问题. 本节描述的ROM为非 储了 256个点的 SIN函 数的被J�值。 具体做法如1f: 盯先是计 算 256 个 SIN函 数的值. ÙJr 数点比较 多 , 可以利 用 MATLAB 工具产'仨一 个个完4应用期的 SIN函 数的 256 个点的也. 由-f FP O A 处理税 数相对简 Ir�点 . 因此',I,r对 � SIN函 数值进行 鹦 数化。 在MATLAB '1'输入以下命令: >>x - 0 : 2.pi/255 : 2.pi; >>sind = (sin(x)+ 1)* 128; >>sind自 floor (sindl ; sind 数组即为 一 个完整周期的 SIN函拙值 的朝 数化。 /334/ 第10意 存储制蹦怜唰飞 ( 1 )创建 一个工程crupromlmp . 新建一个原理阁文件为chipromlmp.bdf。 为ROM 的 数据新建一个 MlF文件,单击,口按钮,在N ew对话框中选择 OtherFiles 标楼下的 Memo ry l n tialization File,如图10-2 所示。 单击OK按钮退出. (2) 在 弹出 的 容;后选择对i古怪巾 , 修改ROM 容量 的大小 , 虫n困10-3 所示。 单击OK 按钮进入下一步。 0...,.0即F旬. 011*r阳l 0._Û>n 呻蜻响n. FiIo F曲 C王::J ___:旦J …b叫 �.Ilrds I 川- "巾,叫做 圄 W'OIdsÍZ<< � � 旦旦J 附10-2新�MIF文件 问10-3 ROM容啧选摔 (3) 在 打开 的 MIF文件" '. j:�I入 MATL础产生 的数据, 虫fJ闺10-4所示。 • f7$2· 71 50 68 ‘E 能 !臼 Ef1M。B‘ ‘g 1 42 57 38 - 33 31 2且 壶' 2量 23 22 ·18 可 。 17 s 。 ‘s · 一 • 's。 '4- • '12 14 0 TKO 。。 ,1 3 1' 0 、 ,。 2 yo - J,K 3 • l呈 8 7 8 9 '2 '3 '‘ '8 17 '9 21 24 26 28 30 3章 曹$ 3 7 �1 � 4s ) ‘e 一 5' 5‘ 56 6' jB4 61 田7二0 _7, -3- 15 78 制 :67 so 宫.3 胃S 回 ' 02 →…一 '0由 ,!!' .�15 118 '21 '‘1…2a4 1 27 凶10-4填入民OM的数据 \335\ /)�问毗 应耀厚阴阳 (4) 侃得 为 chipromlmp.mif 并关闭 , 回到 chipromlmp.bdf文件. 在原理国2f.白 处观击, 在 弹出 的 S沪巾。i对话框中选择LPM-ROM 模块, 如剧 10-5 所 习2 . 俨 骂! 得 叫l 混、 i叫 过 一… 、 、 '" 4以�曰 c ü回恤翩 .翩 翩 L 电 � .脑.._" .'" ι 一…留 阳..气 、.翩 伽J. ­翩I民o_d< .、 町". . 、曲 . 吨 ,一" 、曲 」 reo帽..... r.-桐晴. ...‘ 1õ'I,N睛"咽'电"P\Ø向 "刚睛.1. '\G4O"幢幢 l C王二1 一丝旦」 阁10-5 选择LPM ROM樵块 (5) 1'(1111 O K 按钮, 在 弹 出 的 设置向导中选弹 Verilog HDL i岳,丁, )1:指定保存文件的 同求与文件名, 如闻10-6 所 示 。 单击Next按倒进行下一步设贺。 国 u国"' M鸣..租 缸 . ..., '呐 、,也 h ... .. 航-陶曲同川剧 ….. ,. rtJl民 F阴民 (? V'fIt崎盼也 喃喃捎回·曲"阳"川崎阳⑨拙..1 IE"帽"阳智、 旬'瞰刑队,审时,叫盹,.川 2坦J … ".@咽 I". *矗l'0回uT0 阳 0,.O·,:向u".嗣.ø'刷-A0.t,圃阳•田 0"Ø.''0 阳 甸.回 .筒.of.均o,帽 .. .I悦I。.... 阳.响 .(..T.,帽.禽 .....ô.-.o., 机.I吐 .o"- t'协.g.I.O脚N国I.崎.咀...咽... ….咽_宵.帽‘-."".唱时. 回 、但 , 也a回 国…圃" .回曲 帽. ... /336/ ro帽、 .‘.. -蝠� ... .. ".. …_.阳"田·帽" ‘民...俑_ .‘ ... .四 .圃 .幽 . 阜.. ... 罐"….,.,. *IIÞ.MI .回 .罐 刷归'自‘1VS_曲.。...I\b鸭.o....o..四w.�拿回E-l5.._ ..fIe帽''"'唱_ .' .. .1' .. ... ...刷 二旦J ' n _. I I 国10-6 LPM ROM 参放设'll< 第10意 存储悦翩帽偶、 (6)在弹出的对ii5桩q1.把LPM-ROM 容 址 设 置 为 256*8. !nl剧 10-7 所示。 单击N eXl 按钮l进行下一 步 设 置 . 创 唱唱,.. ‘' 屋亘 。-睛 ,Lhdd!帽,阳曲: �Mtt胁。,叫octJ响' . �西疏离 也剧由陆H翩翩CM睛,、'1>1( .咽. ..p.u.t' 由皿s 同10-7 LPM ROM 参数设n<气〉 ( 7)在弹出的对 话机tt|J. 把输出q设 Yi 为 好1 非输出 . J-t他保持默认 , 如l闯 10-8所 示 。 啦?行Nexl 按钮进行下一 步 设 F2 . W帽、 阳u sl咀"" ber叫�od? 4‘甜缸.qu‘回民 tr.匾. '‘由瞌町晴B 唱,..-" .由 . 由幽市幽啤.o,d吼by盼A四h..饵.咀'曲回曲回l归N:I剿:wu •, • E豆豆....1 I Ci.",. "" 'oó' 4S1'回W唱6曲衔 "岭、.r.嚼眩_porU 、.�.. I 1 I "."" .
  • dOnO ... 匡雪 |刽10-8 LPM_只OM参数设霄l' <.�) \337\ "。也 应商量廖设J't实倒精读 (8) 在 弹出 的对话框中 . 为 LPM R OM 指定初值艾件均chipromlmp.mif. 其 他 设 置保 持默认, 然后单击finish按钮, 完成 LPM-ROM 的设 置 , 虫u 国 10-9 所尽。 匿雪 -Doy刷刷偌忧国每嚣Iyli田M国can国1tcf tI1e ,..,.. .Vl w !叫二胞胎阳二……伽 (y阳C刷‘翩oH翩翩恤d咽(Intol-(ormot)同.(.Iw喝。, •MerI'CIrY lr由..aIln陆[.mfD E至3 同1&_. ,./fhrprGII由呻脯 一 、, 。刷刷Ir响曲酬闹闹ry C刷刷踹曹阳帽阳·刷、刷刷刷帽忧 M唱帽咀,唱ycf叶回町爱国响曲曲 甘胃'InStAnCe 10'cfct由Aα明配 问10-9 LPM_ROM参数设捋, (阴〉 (9) �到Symbol 对话艇, 把前面生成的 Ipm romO棋块i�)JlIfIH�iJ1JH到q 1. )�J-JJ.t添加 输入 输出模块, 连接各个 悦块, 如阁 10-10 所示. 斟Idr回叫7 01 clk 10m romO adrd ess[7..0J cbck q[7..01 宿lSt q17创 用10-10 LMP_ROM各报块连披|划 仇: 仔 ch ipromlmp.bdr .且在市 -按钮对整 个t科.进行编i轧编译无误后单才TProcessing → Generatc Functional S imulation Netl i s t . 产生功能仿页.网友. BR;它A s signments → S etlings, 弹 出 S eltings 对 Lft丰1st 选摔S imulator S etUngs. 设 置S imulation mode 为 Functional. 新建法f�仿点文件 , 添加 输入 输山 信 号 , 保仔为chipromlmp。 民'I\'�1I才华l'怕 号 clk A6 .4 '" 国4..h.叭 阁10-16 )11: SRAM法形仿t'�1! j号 被形仿真报告说明, 为 了 能正确驰liE对片 t:SRAM 的读、 写};k片i2t信号的操作. 片选 信 号cs 设 置前60ns 为高无效,后面 只J低有效: 系统时钟 clk 的周JUJ 设 民 为 10ns,地bl:信号address :J.J 11þ阳40ns bll" 1 ": 每隔 400s, 写信 号和读倍号台I 1005 11'敛, 其I11写信号有放光,i卖信号有放后, 这样每次读 出的数据刚好是Lr 3入的数据. 从如 |组1 0-16 所示的波J�仿真报ftl k看 , 从SRAM 渍, 出 的敬据与写入的数据一致. \341\ /伊W崎 岖4VIIJÆ附实 10.4 片上SRAM的LPM建模 片上SR AM 的 LP M ill棋步骤如下 : ( 1 ) 创建 一个工 程 chipsramLmp, 新也一 个原理田文件, 缸空白处艰JTN挝, 在 弹 山 的 Sym bo l对话框,中选摔megafu n c tion s → s torage → altdp ram双端 SR AM 棋块, 如闯 10-17所示. 一一一一一一• . 时001\略I崎I 嗣 ·响,.融, g,。oI .. t!'�..4.剑I'Q"lf- d帽唱L"响_Iooó .tJhII.t嗣 矗帽唱鹏 伽· "翩翩。 c: " "。 次怜 吹 d� 阳clI_\,l.foctII •, . . H飞 怕飞"。 �抽飞自o_d< 二飞 bI\.,­ 斗次- 叭 阳凡崎叭 蝇. 串啕 忌在Q 、、t 阳阳抽飞o飞阳 .帽. tt凡由咆·, 、, 国­ 降百" J rB帽"啊酬嗣啤 rl酣睡酬暗四"恤睛 • PLo\川、M咽晶咖.d阳耐gln H 喃ω叭酬峭...d民陶忡晴刷帆�" lllt丁 -丝旦」 AlTDPR刷 f__""乓l '‘翩翩 1'"1 刷刷 .. 晴. 刷 由叫1 w,以睛"叫 惋惜,、 ,咣蝴t1< 1>:10咀帕 ltA 阁10-17 aJtdprom锹J,k.ia;抒圈 (2) 机击OK riéfTl.i且UISymbol对话桩, 在弹tll (I'� MegaWizarð 的 LP M 设 背向导中进 行相应参 数 的 设 且o (1:输山文件类型巾店悍 Veri tog HDL. 为输入文件命名为altdpramO.v, 其他的保持默认, 虫1阁 10-18所示。 单击NelX !在钮, 进行下一步 设 进. (3) 在弹IU (J01 ^崎o M‘保 ! Mi阳mørrun翩翩htolCJ J 坦0 11 兰西 l=-�:I I�IH工fJr;It> l 圈 10-20 altdpram 参蚁设'lt; <二三〉 ( 5 ) 在弹出的对话框中进行时钟与便能设贺, 时钟操作选择 Single clock (单时钟), 边中 Cr,ωte an 'rden' read enable sign刻, 创建读使能信号, 如剧 10-21 所示. 单击 Nexl t在 饨, 进行下一步设贺。 .四嘲 '树,. 饨"。 -由d回抽'0'"阶>od曲V剧-世协U帽乎 ,- 5阳属 制兔 OùoId回缸国4J每... ..�Md'ω咀...b"_ OuoI dodo 响 _... '""' nj'.航觑i由国陆 t .011. , -j� 自窍副豆豆页司在翻 口 h一一 时"必 • EEE忧 | 匮雪 阳 1 0-21 altdpmm 参敛设投 ( I剧} (6) 在弹出的对话缸中进行寄存器、 消零设齿, 选中 read OUlpUl po叫s)‘q', 对输出进行寄存 1 344/. 第 10 蠢 存储机路设计棚、 器寄存 , 不创建时钊'便能和 异步泊苓信号 , 如图 10-22 所习2 . 1:在击 Next 按钮 , 进行下一步设置。 .制�1.0. Ai./ro 咽. 'deta'. WðI:蛐融矿'. '"咱"'en' � M叙4蛐畴;�.-d'"",' 。阳副 "南M阳>曹lIJ'"肚酬,阳帽d1e耐,.,I>Ott' · 国l!!'9.Ìi:运画面也d "。民航仲阳"阳V明恤..-1剿,队防回 bOI、刷刷 1曲伐四· 匿雪 剧 1 0-23 alldpram 参放设汗 ( ), ) \ 345\ ( 8 ) 在弹出 的对话框中进行初始化设置, 选择 No, leave it blank. 保持存储棒的值为 全 " 0"。 单击 Finisb 按钮完成 altdpram 的参数设置 , 退 出 设 置 向 导 , 如图 10-24 所示。 ..蚀. t,..‘)10 DoyOUW嗣怕 .岖 .t. ytl鸭H:l‘四叫树d刷刷刷""V1 伊困l!frlo::.u量远 .J lr曲1m .回 .由'1'<0'畴ont dola抽血.X cn阴阳南咽b __ (. Ves号....lt由..""盼..�a览啸'咱tdat& 阴阳 四川剧时曾M曲曲回价恻怕-)�悔[.h阻J...� --、Fie"[..叼 " 4Nifi 匡雪 E豆JG坠J出巴JI � I 同 10-24 ahdpram 参数设投 〈 七 ) ( 9 ) 回到 Symbol 对话框 , 单,由 OK 按钮, 在原 理国的适当位置放置 altdpramO 模块 , 添加输入偷出模块, 连接各个模块, 如图 10-25 所示。 曲目叫7.0. ) 喇喇喇1(4 01 、 ., .m 睛'怕制(4..01 e曲。 晕目h altdpramO 1n51 B阳k Ty国 AUTO 嚼7 叼 国 10-25 ahprnmO模J�应按图 保存 代 码 为 chipsramlmp.bdf. 编 J译 工 程 无 误 后 �'(!. ï行 Processing → Generate Functional Simulalion Netlist. 产生功能仿真网-.&. 0 .c在市 Assig,llrnenlS → Settings. 弹 山 Settings 对话框, 选择 Simulator Seltings. 设!自 Simulalion mode 为 FUDctionaLa 研应被 形 仿 真 文 件 , 加 入 输 入输 出 信 号 , 设百.时钊3信 营 的 问 期 为 10ns. 输入数据 data 每隔 1 00s tm " 1 ", 可地hl:信 号 wraddress 从 Ons 开始每隔 10ns 加 .. 1 飞 读地址信号 rdaddress 从 10ns 开始每隔 10ns 加 U 1 ". 以 保 证 在问 -1也.hb生 出 的数据 是 1.- 议'tj入 的数据 。 保有被 / 346/ 形 文 件 为 c hipsramlmpv. wf.单击巳 拨钮进行片上 SRAM 波)�仿真,仿真报告如阁 10-26 所示. 50 0 .., 7窜 。 .. 10 . 0 ... 110 ø ... 1 50P u 170.p .. IIO.p .. 210.,0 ... I_‘ 150 0 ... 一 .u. 日画 d.h Ii 啊‘抽皿 .na 搓搓YiTY18Yï ‘ rSY& �.jj-XI 2J ,轻手罢手吉普手再苦手吾精4 @ ‘ I Ii rh4ðr.u 圃�l2 r4.,. 因 10-26 altdpram 滋形伪·兵以 何 被形仿真报告说明 z 对国 10-26 进行分析可以看出 , 从 SR AM 读出的数据就是|司一地址:马 入的数据 . SR AM 的波形仿真得到正确验证. 10.5 片外 SRAM的LPM建模 今; 节介绍如何 利 用 FPG A 控制片外 SR AM, 本实例在j 闸 的 SRAM 为 ISSI 公 司 的 IS61LV25616. 它的非储容量 为 1 6*256K. 并只有高低逃掉信号. 10.5.1 IS61 LV25616 it1\片介绍 IS61 LV256 1 6 的 内 部根剧如 10-27所示. 剧).0\17 。在。OOER vcc • GNO 一- 3MV 由 SO阳 110 a F -t明 Oo\lA a0 向 C1RCUIT 256K 冀 1 6 MEMORVA肉同A't CO比Ut.lNI。 CONTROL CIRCUIT 罔 1 0-27 IS61 LV25616 的内部加|划 IS6L LV25616 (II.J封装:WI国 10-28所JJU \347\ 应用程靡设it;实伊脯t1f AO A1 2 A2 3 A3 4 A4 5 理s IJOO 7 1/01 ' 1/02 - V03 10 Voc 11 GND '2 V04 13 1105 ,. 1κ〉自 15 1/07 16 WE '7 A5 1 11 A6 IV A7 20 A8 21 A9 22 " A17 。 A16 42 A15 4' δE 40 UB 39 LB 38 V015 's1 ν014 38 1/0'3 35 1/012 34 GND 33 Voc 32 1/011 31 11010 l) V09 29 以)8 28 NC 'l1 AI4 由 2 A13 25 A12 24 A', Al0 阁 10-28 IS61LV25616 的封装 IS61 LV25616 的 引 脚定义如国 10-29 所 示 . þfJ.A17 VOQ.I 015 琶E � 百言 西 5百 NC Vcc GN O Aωre8S 1咱JIe 0818 'npu.elOU'PU'8 C阳pEnable In队l' 。"协u. En8b1e Inpu' Wnte Er回ble Inpu. lo..t. .b叭e C刷、恒。I (1100-1107) Uppet.byle C。价It01 (I/C)8.VO 15) No C onnec峙。" Power Ground 闯 10-29 IS61 LV25616 的号|脚主; 义 IS61 LV25616 控制信号的真值表如图 10-30 所示. 恼。曲 NOI Selec1ed 。Utpu l OlS 8b悟d Ro ad Wnta � 在 芭5E 四 lm x H x x x H L H x x x L x " H H L L L H H L L " L " L L L L L L x L H L L x H L L L x L L 110 PIN 阅。.1107 110怜1 1/0币' High-Z HígI、-Z Higl如Z High-Z H明白h-Z H叫�h-Z OOVT H咆树-z OOVT 。田 HtQt、-z 。嗣 啕h.Z 。副F 。 剧, 啕h.Z 。嗣 。嗣 阁 1 0-30 IS61LV2S6 16 控制信号的Jtû'i-U Vcc; Cur帽时 1盟 t. 1&国 Icc ICC Icc /3481. 第10意 存储制阳讲捕、 IS61 LV25616 的读时序如图10-3 1 所示. fRC ADO肉ESS 1M. 。E CE LB. UB fl.ZCll OOUT "珞协Z fL2血 IOft.o. f,iZOE f.o.CE fllLCIl … fRC OATA VAUO 11IZ8 v∞ h叫 脚 � 伽酬 1∞ Isa 咀 .C.. l ON ... 图 10-31 IS61 LV256怜 的 谈时Jy. 对剧 10-3 1 进行分析可知 . 一次读操 作, 应同时满足 ADDR ESS、 OE、 CE、 LB、 UB 有足够的保持时间, 具 体的参寿 LS61 LV25616 数据手册. IS61LV25616 的写时即如图 10-32 所示. AOORESS 。E \K/ ./1/ fWC VAlIO ADD肉ESS 、r..111.0. CE WE UB. LB 。。υT OIN LOW 丁=已民 ISA 、k 唱 OATA UNOEFINEO IAW fpW"1 y;c fpßW jν flllWIl 'LLWI: - ←…g句阳怕11叩'ωD \ / HIGH. Z 11"/ 〉支仨γDω怡,'SD → DATA、INVALI。 二-ι. ... "" 响‘ ' … 凶 10-32 IS61 LV256陆 的写时lF 对国 10-32进行分析可知, 一次'ij拙作 , 应同时满足 ADDR ESS、 OE、 CE、 LB、 UB 队349\ ‘ 有足够的保持时间 , 具体的参考 IS61LV25616 数据孚册。 10.5.2 1561 LV2561 6 控帘j模块 根据 自61LV25616 控制信号的真值表进行 LS61LV25616 控制模块的 Verilog H DL 语言 建模, 代码如下: E 代 码 1 0- 1 ) modu1e outramone (c1k, wr, rd, ce, datain, lb, ub, dataout, weo, ceo, oeo, 1bo, ubo,addressin, addressout, dq) ; input clk; input wr; input rd; input ce; input 1b, ub; input [15:0) datain; input [17:0) addressin; 。utput [17 : 0 ) dataout: output weo; output ceo: output oeo; output lb o; 。ur.put ubo; • output [17:0) addressout; inout [15 : 0 ) dq; reg [17:01 addressout; reg weo, ceo, oeo, 1bo, reg [15:01 dq: reg [15:0) dataout; ubo; reg [ 1 : 0 ) cnt; always @ (posedge c1k) begin cnt <2 cnt + 2 ' bOl: end ¢旧 m帽、 qd abTeE- ys( p o s e d e c -k } n - -o ,.• - u a de s s o u t 〈 z a d d z e s s ., /350h 一 '自 10 . ceo <= cei case (cnt) 2'bOO: 1/控制倍号量为无效 begin weo <= l ' bl; oeo <= 1 'bl; lbo <= lb; ubo <= ub; end 2 'b01: //如果写信号有效, 则进行写操作 begin i f (wr草帽 1 'bO 晶晶 rd =-1 'bl) begin weo <- 1'bO; 。eo <- 1 'bl; lbo <- lbl ubo <- Ubi dq <- datain; end end 2 ' blO: beq1n weo <- l 'bl; 。eo <- 1 ' b l ; lbo <- lb; ubo <- ub; dq <= 16' hzzzz; //在读操作之前, 赋 dq 为 高阻 end 2'bll: //如果读信号有效, 则进行读操作 beqin if (wr罩踵 l 'bl & & rd ==l'bO) begi.n weo <- 1'bl; oeo <= l'bO; lbo <- lb; ubo <- ub; dataout <- dq; end end defaul t : begin weo <- l 'bl; • 351 \ 一 oeo <- l ' bl; lbo <- lb; ubo <- ub; end endcase end endmodul e 代码分析说明, 由 于 IS 61 LV2561 6 的数据线只有一组 , 读/骂共闸 , 因此它不能像片内S RAM 一样可 以同时进行读/写操 作 , IS 61 LV2S61 6 的读/写操 作是分时进行 的 , 不能同时进行 。 在代码 10-1 中 设 计一个 0 到 3 的 计数器, 利用 case 语句分开 IS 61 LV2S616 的读/写操 作, 这样做 降低了 自61 LV2561 6 的 读/写速度 , 但提高了 代码的消晰度。 丁0.5.3 1561 LV25616 控制器的测试模块 为 了 测试代码 10- 1 的 正确性 , 需要设计一个测试棋块对outramone 模块进行测试. 为 了便于仿真观察, 片刻. IS 61LV25616 的前 1 6 个存储单元进行验证。 测试棋块产生一个 0 到 1 5 的地址信号 , 对 lS 61 LV2S61 6 先写入一组数据 . 然后再依次读出 . 检查读出 的数据 是否与写入的数据一致. 测试模块的代码如下: E代码 10-2) module testoutramone(c1k, wr, rd, ce, dataout, 1b, ub, a ddressout) ; input c1k; 。utput wr; output rd; output ce; 。utput lb, ub; output (15 :0] dataout; output [17:0) addressout; reg wr, rd, ce, lb, ub; reg [15:0) dataout; reg (17:0) addressout; re9 -L ., Ee9 •C习 [、牛 L·· 民SOz­a mJ cn J Ze9 l Ee9 ws rl7‘ zAu -- nu a d Au C n '-M ., /352h reg [15:0) datacnt; . 10 1脏 a1ways @ (posedge c1k) begin cnt <- cnt + 2'bl; clksram <- cnt [ l ) ; ce <- l ' b O ; lb <- l ' b O ; ub <- l ' b O ; end always @ (posedge clksram) begin i f ( l B ' d15 -- addcnt) begin wr rd <- -wr rd; addcnt <- 1 B ' d O ; //写完成之后 , 就改为读操作 end else begin addcnt <- addcnt + l B ' d l ; end end a1ways @ (posedge clksram) begin i f ( l 'bO =� wr rd) begin addressout <= addcnt ; dataout <- datacnt ; wr <- l ' bO; rd <= 1 'bl; datacnt <- datacnt + 1 6 ' d l ; end else begin addres$out <= addcnt; wr <= l 'b1; rd <= l ' bO; end end endmodu1e • 353\ 一 /去蝙咆椒应用鹏话抗惯例黯谓 10:5.4 IS61 LV2561 6 控制器的仿真 下面对 testoutramone.V 和 outramone.V 分 别生成棋块符号。 新建原则剧文件 , 添加 testoutramone、 ou阳mone 和输入输出模块, 在原理阁 的 适吨位 置放 置以上棋块, 连接各个 模块, 如 图 10-33 所示. a--』1 ; : ; .... . … .... .... .. . ... .… .. ..… ... ..…… .... … ..... ..�... ......... . ........ .. ....... . .. . .. .. . . ,..1.惧61 'i11T略" ." 帽 。. 锢_(1& 01 • r. UI> ad.drHs ..(17 DI , •• … .… . ... ...一 … … W田.. 一 '.. .… ..-...….. .… ...… ..... '•.… .._.… . "..'.… ....... .... . ..... .... .. .. ..咱-. .. • .. • 。.‘ '" 阉 •• 帽.(. 15 DI b 曲 _(17.0) 帽醉UI[峰 。l ω<10 000 Ibo 咀呻 篇蛐咽1IðI.C[17 0) 制[1$ .0) _ ..、. ....... ... . '. '- " .… , , ….• . .. .. … .. . . . .. .. .. . . .. . … … t. . l2i.'.!..uy 惧.. t..-'---i • •• .• , …. . .. .. .. . ... . . : ,. d刷 刷ìlð.O .....<:<.-r;;.�nJ. ) i: •• • 阳 10.33 IS61 LV256 16 r?M�排悦块在 j 核阁 保存原理薛|文件为 testoutram.bdf, 井 设 为 顶Jri文件, 分配 testoutram 的引脚, 编 i辛 E 程文件. 为 了 更页真.实地验i证正 !归S6刷1 LV2S6 1 6 控控蛐司审帘制i引司lj措 的 if.立 h惜的 逻辑分析仪. 新 边 S TP文{件牛 . 如国 10-34 所 示. N..w 08Wll0叩Fiea OlhelFiea I --X-E F融f'tIe O咱国.F由mðlJAo and Probe. Editcr F曲 Ir阳loee FiIe T酬Fie Fie 01{ CanCeI 阁 1 0.34 新5.J! STP 文件 {f弹出 的 窗 口 巾 , 地h采样时钟选择, 以J业所� A.è蝶伯号的 设 贺 , 911 1到 10-35 所 不. / 3 54 / '自 10 章 晴 "*'w .. 剧M.幽 .,. . .唱...0 、 ψ . 1:1 再高.喇喇 @ t 坦. 嗣W响 t 出 '四Im .I.t 单盟军军盟i m回恤, 且溢血-,1 。"眠, ‘ 蝇'组翩翩", ' 44 :': 二盟 " - GI.曲 . - 唱..J"IIA l守, .血 .. a t.J 1) UI..JIIAM 。"民翩 UI _SIW< - 11ifAl1.. .u �吨' 二j - P ," 咽 , JOOt 嗣 饵 .,‘ P ' 霄 , ,:注:院 : 回 霄 画 ' ' p 田 þ 里 掌 刷阳、闷响‘ 阳叫 Z 阳 酬 气 … 阿瓦两 &阳 一 -一 @ '‘ 3 -空!__] 3 二旦坐旦j 口 -一一 sq唱巳--由匾 恤l血 。 ... S呻帽" 前3 刷刷 I r ,_叩 广一-一 一 '‘ 斗 ' 何 .. 1 问'-嗣.胁.- .阳 1l,M."刷"币_… d二j l' ,- -啪.. .:J f 飞饲圄... ‘·畸崽 _j 二j 民I 10-35 STP 文件目H't if(新编译整个t程 , 编译无误后, 准备好开发饭, 接通电源, 连接 JTAG F载线缆。 打 开 stpI .stp 文 件 . i(!击 & 拙钮对 FPGA 芯片进行 F载配哩。 下我成功后, 单市 、 按钮 通过 JTAG 把所要观察信号的值上传到 计算机 I:ill 行观察, 虫11闯 10-36 所示. 」az -- l 呻 1 . .1..3X. .I … ‘直' 一 … 7R … … … 0 …• . .. .. . . ..• .. .. h- • . .2I 喃 喃 " 一刷 12 主λ旦采且又丘Ãl!Ã丘.xu ,X' . . ... t .... . .. . … . . . 1 . . . . . . , . . . . _.. 1 . .. . .. . 1 . . . . . . . 1. . . .. -@ 1 措.53 1 :l6 -a -A--aWe 国 10-36 Logic Analyer 维ÙE Logic Analyer 敬据说 明 如 下 : 烛火 stp I .stp文件 , 可以 农现 在中1:11dJ 的地址 匕 读数据与可 数据一敛 , 所 以 IS61 LV2561 6 的读/马控制器的i在/写操 作l巨确. Logic Analyer 是进行 FPGA 开发非常有用的工具, 有时;后要剧察多 个 信 号 , 而示波又 没有那么 多 的血i且 . 但 Logic Analyer 可 以 很方便地 为 设 计者提供一个剧棋 FPGA ,m阳或者 内 部 信号的平台, 以利于设计茜查看伯号的功能与n,t序是11有问题. 10.6 同步 FIFO的Verilog HDL建模 FIFO 是First In Firsl OUl 的缩写 . ).J.:在ii告器 的一种 , J王 亚用 F 数据级仔 、 边率匹配等 应 用 。 FIFO 一般有时钊1倍 JL 、 数据输 入 、 马 使能 、 敬据输UI 、 读 使能 、 说;空告警和写 满 告警等 常 用 信号。 |叫步FIFO的建模代间如下: \ 355\ modu1e chipfifoone (c1k, reset, wr, datain, rd, dataout, fu11, empty) ; input c1k; input reset; input wr; input rd; input [ 7 : 0 J output [ 7 : 0] 。utput full; 。utput empty; datain; dataout; reg [ 7 :0] dataout; reg [ 3 : 0] cnt rd; reg [3:0J cnt wr; reg reg [3:0] [7: Q] cnt data; fiforam reg empty, fu1l; [15:0] ; //读数据指示精 //写数据指示银 //数据个数指示糠 //FlFO存储数组 a1ways@ (posedge c1k) if (reset) begin cnt rd <- 4 ' hO; cnt wr <国 4 ' hO; cnt data <- 4 ' hO ; fu11 <� l ' b O ; empty <= l ' b1; end e1se begin case ( ( rd, wr) ) // 义写操作的情况 2 'bOl: begin i f ( l 'bO -= ful1) begin / 1 如 果 FIF。没有写满. 则执行写操作 i f ( 4 'he == cnt_data) //当 盯FoH 14 个数据时, 再写就满了 begin fiforam[cnt wrl <= dataio; cnt data <罩 cnt data + 4 ' h 1 ; fu11 <.. l'b1; /356 • '阳 10 I脏 i f ( 4 'hf -- cnt_wr) 11如果写指示摆到最后 了 , 则转到开始 beqin cnt wr <- 4 ' h O ; end else begin cnt wr <- cnt wr + 4 ' hl; end end else begin fifOEarn[ cnt-wz] 〈' datairIJ cnt data <- cnt data + 4 ' hl; full <'" l 'bO; i f ( 4 'hf -- cnt wr) begin cnt wr <- 4 ' hO ; end else begin cnt wr <- cnt wr + 4 ' hl; end end empty <= l ' b O ; end end 11只读操作的情况 2'blO: begin i f ( l 'bO ... 创贸pty) 11如操没有i在空. 则执行读操作 begin i f ( 4 ' h O -- cnt data) begin //如果 FlFO 具有一个数据, 再读航空了 dataout <- fiforam[cnt rd] ; empty <- 1 'bl; i f ( 4 ' h f -- cnt_rd} / / 如果读指示楼到是后了, 则转到开始 begin cnt rd <- 4 ' hO; end else begin 357\ . cnt rd <- cnt rd + 4 ' hl; end en d el se b e n ­-n 争 v da t ou t 〈 E fifo r a m I c n z d l ., 凰" em p t y 〈=1 boz - cnt - da ta 〈z cnt - d a t a4 , h 咱2· -- ,也{4'h f = z C nt - z d } b eq·l n cn t z d 〈 z 4 · -O z n end else begin cnt rd <- cnt rd + 4 ' hl; end end end end / /读/写操作同时逃行的情况 2 ' bll : begin case ( { full, empty} ) //既没有写满, 也没有读空的情况 2 'bOO: begin dataout <冒 fiforam[cnt rd) ; i f ( 4 'hf -= cnt rd) begin cnt rd <.. 4 ' hO; end else begin cnt rd <= cnt rd + 4 ' hl ; end / 358 fiforam[cnt_wr) <= datain; i f ( 4 ' hf � ∞t wr) begin cnt wr <= 4 ' hO; end • 第 10 j民 else begin cnt wr <= cnt wr + 4 ' hl; end end //没有写漓, 但读空的情况 2'bOl : begin dataout <- dataini end //写满的情况 2'blO: begin dataout <= fifor缸n(cnt rd]; if(4 ' hf -- cnt_rd) begin cnt-rd <= 4 ' hO; end else begin cnt rd <= cnt rd + 4 ' hl ; end . fiforam[cnt wr] <= datain; i f ( 4 ' hf -- cnt wr) begin cnt wr <- 4 ' hO ; end else begin cnt wr <= cnt wr + 4 ' hl ; end end endcase end endcase end endmodule 保存代码为 chipfif∞ne.v. 编译整个工程, 编译无误后单击Proce s sing → Generate Functional Simulation Nedist. 产生功能仿真网表. 新建波形仿真文件, 加入输入输出信号. 359\ 后面阻 四鹏说宁跚跚讲 设贵时钟信号clk 的 周 期 为 1005: 设 置 复位信号 r eset 前 20ns 为高有效 , 后面一 直为低无 效 : 设 置 输入数据 datain 1尊隔 1005 加 " 1 ". 对读/写信号分别作三次仿真设 置 , 分别为写 信号, wr 一 应有效、 先写再读和读/写同时进行 , 分别如图 10-37、 阁 10-38和国 10-39 所 示 . 圈þo I clk r...‘ 回 cl.t..... .n ... f..l 国 d.t.oul ..p. ‘y rd 画Tin-x主I豆-xsrSYl面丽ITi23'.(画百弱ï菊4 。 闯 1 0-37 盯FO 放形仿真报告 { 一 〉 . 0 1 cllt rt '.‘ tïI ..t..ß ..r full tïI d.t..叭 "‘' r. 倒 10-38 FIFO旅}�伪炎,报告 〈二) .u ,...‘ 画面 "'.'.1þ r.u a �.‘..,. …‘' •• 阳 10-39 FIFO 放 形仿真报告 〈二〉 被形仿真报告说明z 国 10-37、 图 1 0-38和 国 10-39 分别仿点了耳操 作、 读操 作 和卖i /写同时进行的操 作, FTFO的读宅告警 、 写满告警均能正常反毡l , 所以 FrFO的建校得到正确验证. 10.7 同步 FIFO 的LPM建模 IJJ.i W FIFO 的 LPM �辛棋步骤如下: ( 1 ) 创建一 个工 程 c hipfifolmp. 新建一 个b�理图文件, 在原理制空白处攻击丘饱, 在 弹 出 的 Symbo l 对话框lþ遮挣� m egafunclíons - storage → 1pm_fifo_dc . 如 国 10-40 所示. 单击OK按钮, 进 行 下 -t(,设盟. (2) {E弹出的对话框中进行输出文件 设 'l!. . 逃掉输出文件为 Verilog HDL文件 , 文件 名 为 Ipm_fifo_dcO.v . 如刨 10-41 所示. 单而 N ext 按钮, 进行下一步 设 置。 13601 第 1 0 j撞 存储黯 E �. . . ... ... • . •• . . …..,.. .... ' . . . .. . • 回 ..�. . n..cIIt b"吨"I'."1�甸 \,.-, EEL- .. ..画面 F喇 I11- �._d< 」 「 旬..帽叫嗣血 • 「 抽回咿‘回.恤呻 S; �..的响 . 唰阳聊 酷略事晶嗣同刷01(皿崎L C王二3 一但已」 图 10-40 LPMJlFO-DC 锁块池弹 |川吁lM1bJ川 抽回剖I:!:.O'血l!'ldiar冒 11p.! 'fJfO .\ W协Jlopeof响惜自.00阳峭‘loa酬的 产 必4口L r II.HDL r- ve.tr:捕HDL w、IJI '1ðfTM' ðg阳,唰盹blheguIpA伽? IE;\IXCIOIO I\vo<曲抽出lk\1刷刷曲1>\1田yt_1i且也创 HoIe: ToCOII抽 ·阳愣d即回帽�in阳白国阳11 ooftwar缸jJOUI O�阳咽 daIOg阳皿σ叫$ m酬 也衔,阳回 阳1I bern阳阳锵ct cl曲eolol.y rn Iho依lbðI国割勘审阳 莓>edi!国 in thé in lho U 帽 l.brarlM p唱jeCI ht eSeII1QS ..L. 国 aU1回lDðf)ItI>国flOld ci呻啕 』蜘 队ntgr喃自由 m自'IU}. Y刷CYI1制闹剧 lbraIY"剧由自 . .. , ! 「 且时础嗣,.. . " 0IÂp.A fle闹闹翻lhe刷刷Iie 101'"且崎帆 111h血跑 帽回 0IÂp.AIies 晦 ðYtom �翩翩the-cur酬OIÂOI flefOnnIJ. 侧目e.Yω阳、turnlheBlock.EÓI的a刷帽回啕翩翩。10ItIIJ 倒四刷 刷刷 。11withtt胃口μIont commandIri Ihe Tooh帽叫 CanOeI J[ 何t H""'> l刽10-41 LPMJIFO-DC 参数设留: ( 一 〉 队361 \ 应再马"也 回酶设计实例黯诩 (3) 在 弹出 的对话框 中进行 FIFO 宽度与深度的 设 置, 本实例设 置数据宽度 为 8bilS, 数据保度为 16wor出, 读/写时钟设置为读/写时争j'独立 , 其 他保捋默认设置, 如阁10-42 所 示. 单击 Next 按钮, 进行下一步设置e "也 翻昭叫 3 01 岖7 .0) 雷帽明酌 ,你 剧.(..3 0) 01<.曲 . �ted聋... 1.响 . : "‘ "1 !!!l 阳的嗣同doId "脚"啕.1圃.Id问f1FObo1 M惨 , l' ‘s How曲"" ahO.Ad ihoF1FD bo' [汇一-.唰曲 DoYOU-X�_do晴"" .莓 ., . 、 ;-喇喇键问阳 FlrOI 一- 0咽�.•... JYOCfwOt嗣boUl'odIo..t _晴、,抽出,ι 。.血"鸭of'"," 刷刷田制"田队 " 闸'..,..,_幅teadn;剧"闹剧禽t( tnd-w,ct:I 帽哥晒h曲.c,.. .础。1"峭帽嘀帽时句睛.....。咱血 - 2r叫..mt 叫 ..捡. 回·萨誓。__._霄od! tM'晴叫 叫… 田叫 '恤_ ,,",Ú、.. ò民 萨趾 抽41..0.呻� S 融JS白 t蜡 be.Sy世 r曲.柿。.蕾 t e帽 . dd dat>od .隅 血..Jbyolnr<相柿阳 ,也a圃 ..a..也of.o6、 "阳,.) 阁 1 0-42 LPM_F1FO_DC 参数没宵 (二 〉 ( 4 ) 在 弹 山 的5Hi茜f医 ' -j 'ill行 FIFO 状态信号输山 设置, 在R ead-sid e 下面�i)-' empty 和 u s edw[], 在 Write-side 下面选 中 full 和 u s edw口, 如|剧 10-43 所示。 单市 Next t主钮, 进行 下一 步设宵。 /362 / W树叭A w,_ 叫, 咽 ,像 翩 。 叫 , • :1:「[古 回 ‘嗣胁。 、4 幅呻响口 蝇似j,.O 晴 1'" 州... N … n回.呻、�, ... 咽'骂阳售商.. 10 .咱 dk' N _ n- 四 F 由 …帽'-"'… " ... cr <1_曲,、11>0问fO "01.、Vou_响· Ifro '呈 "S ω "咽 "... •helll ulík略 的归田曾帆ouo 曲" ,. _ _ l到 1043 LMP FIPO DC 1:$段路t1ft' ( 三 〉 第1 0 意 存储制翩制"、\ ( 5 ) 在弹出的对话框中进行输出数据设置, 选择数据在 e rdreq' 有效前可用 , 其他设 置保持默认 , 单击 Finish 按钮完成LPM 的设贵, 如 图 10-44 所示. \fM:h 抽 咽"r四 o< 翩翩曲" 田- ‘ "协阳陆 甜甜 睛 。 阳 �同 阳 �四d�!It‘S.)B呻 bI'幅o VO由 .四 t唰 r" H.d..悖 .翩 .-.。q" 时 t翩Ø恤 } .��IS幽帽国咱 �;-, St\O,I.. : .甜 "咽'""唱1 m。刷国恤 T、he蝇od。It草� Oboc...o.m幅o画 t .面阳 .晒 曲啕 . b曲 ef.c.n.'rct耐地帽..,回J 陆阳i节喝ìmi>da""阳'f."" f>l) ^ rbnext; / / 二进制到 Gray码转换 a1ways e {posedqe zclk 。z negedqe aempty-n} if ( ! aempty..n. ) ( rempty, rempty2 ) <= 2 ' b l l ; else { rempty, rempty2 } <= { rempty2, 句aempty-n } ; Endmodule 状态 " rempty " 被信号 " aempty_n " 异步盟位, 并且 当读指针递加后撒除 . 5. 写指针与 " 满 " 逻辅模块 写指针是一个 n 位 Gray 间计数器. FrFÛ " 满 " 状态信 号 "w如11" 在异步比较输出信 号 " ahilJ" 变低时有效, 一旦 " aful1 n " 变而后, 则在下一个可时钟的上升沿撤除 。 除了输入信号 " afull n" 之外, 整个模块郁闷步在: "wck" !峰时钟域, 从而简化了模 块的静态定时分析. 程序代码如下: module wptr...full (wfull, wptr, afull..n. , wreq, wclk, wrst_n ) ; parameter ADDR..W. IDTH - 4 ; output wfull; output [ADDR_WI DTH-l : 0 1 wptr; input afull_n; input wreq, wclk, wrst_n ; reg [ADDR_WI DTH-l : O l wptr, wbin; reg wfull, wful12; wire [ADDR WIDTH-l :Ol wgnext, wbnext; / / 寄存器输出 Gray 码该地组J:指针 always @ (posedge wclk or negedge wrst_n ) • if ( ! wrst..n. ) begin wbin <- 0 ; wptr <= 0; end else begin wbin <= wbnext:; wptr <= wgnext; 队371\ 帽到L 蓝踵疆摩酷镇倒躏讲 end //Gray 码计数迦秘 assign wbnext - ! w f u l l ? wbin + wreq : wbin; assign wgnext - (wbnext>>l) ^ wbnext ; always g {p。sedge wcl k or neqedqe wrst-n oz ne9edqe afull-n } i f ( !wrst n ) (wfull,wful12) <= 2 ' bOO; else if ( ! afull n) I w f u l l , wful12) <= 2 ' bll; else {wfull, wful12} <= (wful12, 句afull n ) ; endmodule 当 FIFO 复位时, 状态 " wfull " 也 同时被扭位 , 此外, 信号 "ahllJ" 对其进行异步 咒位, 并 且当读指针增加后撤除. 1 0.8.4 异步 FIFO 的相关问题 1. FIFO 的复位 在异步 FIFO 的 设 计 巾 , 牢房.个模块的复位相;与 南要. 因此, 下面简要总结合: FLFO 复位 时, 需要复位的棋块或占信号· . 主要是: · 复位信号 会丘接消除 " 飞� " 标忐 . il t是 "mmpty " 信 号无荷复位. · 复位信 号消除读/写地址指针 , 使得两个指针相 同 , 即 FIFO 处于 " 宅 " 状态。 · 复位还帘的除 11direction " 标志 〈 见图 1 0-汩 的异步比较器电路). 2. FIFO 关键时序路径 本例设计的外W FIFO 的关键时ff路径.(E r "三户 / "梢" 状态信号, 如l阳 10-53 所示。 " 空 " 状态信号' "mmpty " 出 下 面的路径组成。 · 读指针 (rptr) 边响的时钟到输出迦可H : · 读指针 〈 叩lr ) 与可指针 ( wptr) 比较理机: • 比较器输 山 与 " direction " 锁存器输出的组合逻辅 , 生成 "aemply_n " 状 态 信 号 : · 异步辑位信 号 " aempty_n" 圭IJ状态信 号 " remply" 的输山路径: • " rempty" 主IJ且驯&41J132驯的路径: • 同在 " rclk" ß.t钟域的 F游触发器所必'I/,Ì(I� ill立IHrl呵。 |司坷. FIFO " 淌 " 状 态 信 号 分析 与 " 气 户 信 号 类 似。 / 372� 第10 意 存储削踹憾� 呻trfn] 二〉 dirsel n 自1k rcmpLy xlJ F个 触发苦苦的姥立 时rnJ (rdkl!t钟域〉 惰,时0-1] -一、 rptr[n) -J wτSl 0 CMP = dclkk-->>qq((咱 币的的 wfu1l �J F个ll!:I..1:lI� 的应立时间 (wclk时钟峨〉 wcJk wrsl n 囱 10-53 FIFO 关键时序路径 10.9 本章小结 本 J�'t详细| 介 绍 了 片 内 ROM、 片 |工 SRAM、 同步 FIFO &封� W FIFO 的 建模 与 设 计 过'科。 压介 绍 了 对 于片内 RAM 不够用 时, 如 何 设 � l'制jlJ片外 SRAM 的民/写控制措, 并讲解 r 如何使用 Quar阳s n 向 仰的 LPM 板块来进行问效 设 计 . 本12介绍的实例非常典型, LA: 者 可以根据实际开发需要, 对实例进行简单修改就口I以应用到IJ I'- lL 斗的项 目 中 . \ 373\ 第 数字通信与控制设计实例 Verli og HDL语言在数字迦信与数字控制领域有行深入广泛的应j日, 本:?ti血过几个典 咆实例, 来!提示Veri10g HDL数字应用程序瓦t计的特点平11方讼。 11.1 时序状态机的设计 计算机及H有内有必按照所存储的息执行-系列操作的JC宫数字系统统称为u n-tli�状 态机", 其电路可以迦j立时序迦�i:�进行应膜。 MJ子状态机的性能与细合逻辑不|叶, 肉只j时 序状态机的输出不仅取决于叮闹的输入值, 而且取决。j二历史的输入。 时j子状态机被广泛I也 用于J.f�指定顺序操作的应用'11 , 例如l用时!f.状态机的输出控制计算机的同步数据油路&. 寄存描跺作 。 所甸 的时序状态机都具有如 阁 1 1-1 所乐的i1Ji用问锁约 构 , 任这种结构中时序 状态机的下一状态是 由 当前状态和当前输入一起形成的 。 乒|下叫H俨比i 内({ n一 当 前状念 阁11-1 f付印状念相LJift!闺 n.t J手状态机可以极是否受-个公共的时钟控制〈钟控〉分为同步状态机和1异w状态 机, 如果共打电斗'控则为问w状态机, 反之为外步状态机: 根扭1;状态数u足二手Hi限可以将 I付j卡状态。L分为旬限状态机和无限状态机. 本书只讨论!uJ!J;有限状态机(FinílC Stale Machine, FSM) , 它在数字系统中RHHtl广泛, 例如, '1ι『可以作为 wrr.恨元与处用,巾的 数据油路控制础。!tiJ步行限状态机的特点)t';H有有限个状态, 刀井二门.状态的1转专换是H山111.忖中 驱动的 〈 钟控 〉λ@ 第11 章 戴字通铺 11.1.1 青限状态机(FSM)的分类 有限状态机有两种基本炎型: 米和Ij ( Mealy)机和摩尔 ( Moore ) 机, 米利机的下 一状 态和输出取决于当前状态和当前输入: 摩尔机的下一状态取决于当前状态和 当前输入, 但其 输出 仅取决于当前状态。 这两类有限状态机的下一状态和输出都是 由组合逻辑电路形成的. 1 . 米和J CMealy)机 米和IJ ( M臼Iy)机的结构如图 1 1-2 所示. 输入 下一状态 组合逻辑i 状态 唱暗衍营事 田' 输111 组合边草1 ← IH申 倒门-2 米和IJ (Mω1y)机方板阁 山国川-2可见, 米和J ( Mea1y)机的 F一状态和输出部以快 f当前状态和:与前输入。 2. 摩尔(Moore)机 严捷尔 ( M∞re ) 机的纣i性!如国 1 1-3 所"J二. 输入 f-J!J:,部 组合适销 状� ¥¥;{(l部 愉111 组合i草制1 M!中 回11-3 ��H, (M∞re) �lH根阁 由阳 门-3 可见, 席尔 ( Moore)机的 下一状态取决于:与前状态和当前输 入, fll.其输出 仅JfX决于、41前状态. 11. 1 .2 育限状态机常用的描述、 开发15法 有|唱状态机可以借助时J1阁、 状态哀、 状态圄以此 ASM 闯进行系统的描注与设计。 时印刷可用于说明系 统1112边系统与周阎王平峭的接n巾信可的行放输入与收态转移之间的 关系. 例如, 西态随机iJj fuJ内蒂的'号刷刷可以用一个时j手圄加以说明, 该时Jf剧点II)J抒储 i(l元的地址必须在写使能信号有效之前就己纶被确定• {E1Mló]结合的 设计方让巾, 设计的 时附指标 构 成 了 对 必 须 由 设 计 t 具 实 现 的 屯 路 的 限 制 . 状态表或状态转移1<.以表格的形式点示在飞前状态和1输入的 各种组合下状态机的下 一状态和输出 。 \375\ 矿石函毗 应隔感谢f跚跚浏 状态转移囱 (State Transition Graph. STG ) 是一种有向圈, 闺中 带有标记的节点或顶 点与时序状态机的状态一一对应. 当系统处于弧线起点的状态时 , 用有向边或弧线表示在 输入信号的作用下可能发生的状态转移. 米利机 STG 的顶点用 状态进行标记, 状态转移 国 的有向边有下面 两种标记方法: ( 1 ) 用能够导致状态 向 指定 的下一状态转移的输入信号来标记。 ( 2 ) 在当前状态下, 用由输入信号确定的输出 来进行标记。 摩尔机的状态转移图 与米利机相类似, 但它的输出是由各状态的顶点来表示的 , 而不 是在弧线上表示. 费:法状态机 ( ASM ) 国是时序状态机功能的 一种抽象 , 是模拟其行为特性的关键工具0' 它类似T软件流程阁 , 111显示的是计算动作〈如寄:有-ff§操作〉的时间顺序, 以及在状态机 输入影响下发生的时序步 骤 。 ASM 阁描述的是状态机的行为动作, 而不是存储组件所有: 储的内容。 在时候用 机器工作期间的行为动作来描述状态机的状态 , 比起用状态机产生的 数掘进行摘边更为方便也更重要. 例如 , 我们可以用 1 6 位的计数器内容来描述计数器本 身, 我们也可 以将它视为一个数据信道单元来描述它的动作〈如计数、 等待等 〉 。 在描述 时)�状态机的行为方面, 以及设 计状态机来控制数据信道方面, ASM 国是 非常有帮助的。 ASMD 阁 是 ASM 圆的扩展。 状态机的一个重要应用就是控制时序状态机数据信道上 的寄存器操作, 而该时序状态机已被划分为控制器和数据信道. 控制措可 以 用 ASM 图 来 描述, 我们修改 ASM 固 的 门的是把它连接到状态机所控制的数据信边上. 当控制榕的状 态 沿�迎道发生转移时, 通过标注每个数据信道来指出 那些在相关数据信道单元中所发生 的常非器操作. 以这种方式连接到数据信边的 ASM 阁 被 称 为 算法状态机和数据信道 (ASM O ) 阁 . 在把时序状态 机数据信边的 设计从控制 器 的 设 计 中 分 离 出 来 , 并在两个单 元之间保拇泊晰联系的的况下. ASMD 阁 行助f阎明这样的时序状态 机设计方法。 与状态 转移并行发生的寄存器操作是在阁的迦道上标注的, 而不是在通过上的条件框或状态握中 标注的, 肉为这些寄存器不是控制器的一部分. 由控制措产生的输出是 那些控制数据信道 寄存器的信 号 , 以及引发 ASM 图上标佳的寄有器操作的信号. 1 1.1.3 基于状态转移国(STG) 的设计 1设计要点 对于一个同步时序状态机的给定 STG . 设 计的任务就是确定下一状态和输出逻辑。 如 果用一个 气进制代码来表示时序状态机的状态, 那么其值可以 非储在触发器巾。 在时钟的各 个有效沿处, 状态保持触发器的输入变成下一个时钊'周期的状态。 同步时序状态机的设计就 是要根据机器的状态和外部输入来确定能形成触发器输入的逻辑, 该逻辑为组合逻辑, 并且 应该是最简逻辑。 对于有效 的 STG 而言, 其每个顶点必须表示一个唯一的状态: 每个弧线 则农示在指定输入信 号的作用下, 从给定状态主IJ下--个状态的转移, 并且从一个节点山泣的 / 376/, 第 1 1 章 戴字通惜与 各弧线必须对应一个唯一的输入。 通常, 与从一个节点出 发的一组弧线有关的布�J'条件必须 满足和为 1 ( 即 状态转移困必须考虑到从一个节点出发的所有可能的状态转移), 并且在给 定 状 态 下 与 输 入变盘判 应 有关 的每个分文条件必须对应 F一 条 唯一的 弧 线 〈实时序状态 机仅 可以山一个节点经过 一条弧线转穆到下 一个状态λ根据时钟剑来之前的状态值和 当 前输入 值, 由 |司步时序状态机的 STG 所表示的状态转移将在时钟倍号的帘效沿处发生。 基于状态转移回 ( STG) 的有限状态机的系统设 计方法迦常包括以下几个步骤. ( 1 ) 构建状态机的 STG. (2) 捎去等价状态. (3 ) 选取状态剧 〈 如二进制代码) . (4) 编写状态表. ( 5 ) 推 出 描述保持状态位的 D 触发榕的输入 布尔方桂. (6) 利 用卡诺剧优化布尔方程。 2. 建模实例 z {O. O } 1/ • Data PI <问。" • 阁 11-12 二级流水线2: I抽i仅榕的ASMD阁 基于 ASMD 困的二级流水线 2: 1抽取措理序代码如下所示, 仿真波形如回 1 1 -1 3 所示. E�, module decimator (clk, rst, Load, Data, Dout ) : parameter S_IDLE - 2 ' bOO, S 1 - 2 ' bOl, S FULL 皿 2 ' bl0, sωAIT - 2 ' bll; rst, En, input clk, Load; input [ 7 : 0 ] Data; ou�put [ 7 : 01 Dout; reg [ 7 : 0 J PO, Pl, Dout; reg ( 1 : 0 ) state; a1ways @ (posedqe c1k)beqin /386/. .11意 r s }b 9 ··4 n 过 争伽·』 e p TD sateJ飞E · 山nb-o A p 、nA. AUUo ,.,. p 〈= 〈= 《ARV· ·hh 6 ed n u 争 } e se c a Se{sta e 目 - l '1" n} Mq - T4DLE· · ·-E s 伽 t s a 』 e p A电UA 〈〈-E p beq in 〈 Da zt as­- A、 , . PlJ end S_l: begin state <- S FULL; P1 <= Data; PO <- Pl; en iDF F L } L- n ad beq ) qin d U --·l·6 ((-Mb bSta ePl Po te 〈· 〈· 88〈 ''Bhh n《内aUυ-oo ‘z­i., end else begin state <- S IDLE; Pl <- 8'hOO; PO <- 8'hOO; end Dout <= PO; end else begin WAIT; state <= S end S WAIT:if(Load) begin if (En) begin <- S s�tate 1; P1 <- Data; OP <- Pl; end else beqin State 〈 D L ., ,匾uh 向nbu-o,.T目, Me Pl 〈­8 ‘ 387\ 一 <= PO 8'hOO; end Dout <= PO; en -e f a u­ e n -d EG hu- p-state <= 5 IDLE; Pl <帽 8 ' hOO; PO <- 8 ' hOO; end endcase end endmodule E 1. fLj,'", .'.'" 8ar, ""er TLu 1.。回 l'.I.' '.In,...,�11.66.,. Intt:T四1: -t'盹剖... s‘町t: 0", (1回: 1.。回 B 世mh叫M.... 1.1ao.o... '101.0 .,. E鼠。" 一 ‘"、。回 ‘曲。. 0 ... 一801.0 阳 '且 闸门-13 流水线2:1抽取器仿巢放形 11.2 伪随机序列应用设计 伪随机序列在扩频迦伯、 霄达、 1m卡汪/遥漂IJ、 加密/解密和无线电测fl(系统领域rll有着 广泛的应用 。 在很多实际应用q1, 直撞利j刊FPGA产生伪随机序 列的}ir去可 以为系统设计 或测试带来极大的便利. 11.2.1 应用商景 伪随机序夕IJ (Pseud o- Noise, PN) 也称做伪屿, 它是JI.{j近似随机Jf纠(噪声)的性质, 而又能战一定规律 〈 周期〉产牛.和复制的序 列。 因为随机序 列 是只能产'l:1而不能组制的, 所以称其足"伪" 的随机fy.判。 在数字电视和数字通信巾, 一般使剧伪随机序判作为训练l乎纠, 用伪随相Uf. 列口f以实 现能 f让随机化. PN 序 列的特点是: 尽管其序列产'Þ.器有确定的构造方法, �叫PN J乎到本 身具有很 多类似随机序 列的性质。 例如1. 剧 11-14足数字电呗 DV B-C 前捕编码和|调 制框 国 . 口f以看到, 在进行信迫编码时部.ìlJ:H了扰码处JIli.0 /388;' 第11章 ..1 复Jjj 运倪与 加扰 JMS.C 型血 常 形成 店主 QAM 制制勺 去*W -1 … 时川 tt痴接 εJ u VB-C 倒 11-14 D 前瑞编码和调制拯囱 进行基带信号传输的快点是: 额i曾会因数据出现连"1" 和连11" 0 而包含大量的低频 成分, 不适应通道的传输特性, 也不利于从中提取山时钟信息. 解 决办法之一是采用扰码 技术, 使信号受到随机化处理, 变 为 伪随机序 列 , 又称为"数据随机化"和"能量扩敞处 理飞扰码不但能改善位定时的恢复质量 , 足可以使馆 号额i拉平滑, 使帧同w、 自远l业同 步和自适应时域均 衡 等 系 统的性能得剑改善. 扰码虽然"扰乱" 了原有数据的本来划伸, 但是因为是人为 的"扰乱", 在接收端很 容易解扰, 从而恢复出原来数据. 利用伪随机序列*行扰码也是实现数字伯号高保密传输的重要手段之一. 一般将信源 产生的二进制数字信息和一个周期很氏的伪随机序 列进行模 2 相加, 就可以将原信息变成 加哥特后的另一序 列. 这种信号在信道巾传输肉然有很内的保密性. 在接收端将接收到的信 号再加上〈榄2 和〉同样的伪随机序 列 , 就nJ以恢复为原来发送的信息. 在 DVB-C系统 中的 CA系统原理就濒于 此, 只不过 为了 加强系统的保密性 , 其此随机序 列是不断变化的 〈 每10s变一次). 这个伪随机序 列义叫控制宇( CW). 此外, 在扩颜.ìlf1信中也而要用到伪随机序 列。 找们知迫, 扩频的主要特点就是发射机 和接收#山、须预先知远一个硕茸的扩频码或密钥, 扩频间必须足够辰, 尽最接近或类似于 随机数字序 列. 但是, 在任何情况下 , 它们必须保持可恢复性。 否则, 接收机将不能提取 发射信息. [用此, 这种序列是近似随机的. 在软{'t11'一般部采 用 含行大数呆法的i是推公式所计算 出 的一组数值来产生伪随机数 列. 二!斗数列足够长时, 这组数值就是近似满A均匀分布的伪随机数列. 虫n在 C语占下: 程序初始化时调用一次 sran d()函数设置好随机数"种子", 然后就可以通过调用 ran dO函数 来产尘随机敛 了 。 随着可编程逻辑器件(FPG A) 在电子领域越来越广泛地应用 , 在很 多 高远 设计和商 边测试的场合下, 我们希咱能够在FPG A中rI接实现伪随机Jf 列反'1:器. 本市的实例是基 于线性回馈移位寄符器电路, 针对 DVB-C标准, )t-结合FPG A的特旬结构, 设计了一种 简捷而又高效的伪随机序 列产生方法. 队389\ • 11.2.2 理论知识 1. 伪随机懵号特性 最常见的二进制 PN 序 列是最大长度线性移位寄存器序 列 , 也称m序 列 , 它是由一 个线性回馈的n级移位寄存器生成的。 所谓线性回馈.是指回馈函数中仅包含棋 2 加运算 而不含非线性运算. 图 11 - 15 是一个简单的n=3 级PN序 列产生器, 其生成多项式 〈 即 连接关系〉为x3+x2+ 1. 当移位寄存器组0 1 、 0 2 , 0 3 被 设置为一个非金"" 0 的初始状态 后, 它将循环通过所 有 2 叫个可能的非金101 "状态, 同时输出的PN序 列也以快 2 川为 用期反复循环. 不同的初始状态决定了PN序列的起始点, 也称为PN序 列的相位. 于置宣韧IJ{血 阁 11- 1S PN防守11便成黯(1l�3) &1t状态转移阁 其它长度的PN序 列的生成多项式在许多教科书中可 以查到。PN序 列的生成多项式必 须是n狄本原多项式, 其周nJJ为 N = 2 n _ 1. 这样生成的PN序 列 是一个以 2 '二l为周期的 俑环序 列。 PN序 列具有一些典型的伪随机特性: (1)PN序列的一个周期(氏度 为 2 " - 1) 中 , t< 1"、"0"的个她豆豆多相差一个, 称做 伪随机序 列的平衡特性. ( 2 )序 列巾取值相同的相连的元素介称为一个游程 , 游程中元素的个数称为游程长度. 伪 随机序 列i丘似满足如下特性: 一个用朋 内 氏度为l 的游程 数目占lJfl程总数的 1/2, 氏度 为 2 的游程占总数的1/4, 氏度为 3 的游科iJf总数的 1/8……依此类推 , 氏度为k的游程占 总数的f. 这称做伪随机序 列的游程分布特性. (3 )将伪随机J1- 列一个周期与其任意汰的循环移位的序 列逐位比较 , 相 同的位数与 不 闷的忱数最多足l。 这称做伪盹机序 列的相关特性. (4) 将一个PN序 列a循环丘 移 tt( 求。)位 , 得剑的PN序 列LÁ_a)与。棋 2 加以 后 , fÐ 仍足。的循环左移若下位后 的PN序 列 . 即 a LÁ_a百) Lr(a). 可见. PN序 列满足线性 法加。 ( 5 )PNJ?- 列的向相关的她Ra(t)和宇均.r})卓谱密度 S a(f) , 如回11-16 所示.山于Ra(l) 具有周期性, 所以其傅里1叶'变换〈 即平均功率谱密度 ) S a/( )为离散线讲, 谱统问阳为 l / N T. 伍实际巾, 通常将PN 序 列的问期 N 取得很大, 而脉冲宽度几取值较小, 此时PN 序 列 的白相关凶敢将近{以为δ函数. Jt功率谓近似为于坦的宽1rf连续谓. 也就是说, 随;(f N 值 /390/ 的增大, PN 序列 更加接近随机噪声的性质。 Ra(τ) 2_�.- 1 N- '自11章 f 2t 0 t2 T‘ T. T. T. 图 1 1- 16 PN 1'(-列的白相关的数和平均功率诩密度 2. 线性回馈移位寄存器 如制门-17所示为m级线性回馈移位寄籽器(LFSR)的电路结构。;lt巾系数|大l了�Ji= 1 衣示有连接. /,=0 :&.示无连接. e表示异或(XOR)运算。 f..吉l 10 = 1 nI-2 1 nI-t OUlpUI Clk 剧 1 1-17 m自战线'性凹帧侈优待存榕 (LFSR) 显然. LFSR 的输出序列是有周期性的. 同为一旦m个寄再端上出现了 以前经历过的 状态, 贝IJ以后的状态将周而且始。 m 级的LFSR :陆多川有2m个状态, 所以 重复朵不可迦 兔的. 若m个寄存器的初始状态全为.. 贝IJ LFSR 将一自保持全苓状态 . Lkl此, 在初始状 态非全军的前提下, LFSR 的周期r 运2'"_1. 如果选取远当的 国馈方式, m 级 LFSR 所 产'E的序列周期可以 达到敲大值 2'"-1 , 这时 LFSR 所产生的伪随机序列 也称沟址K序列 〈 或者m Jÿ.列)0 LFSR 的刷JØ]只与其国馈方式打关, 而不依赖r-其初始状态. 棍据其国馈 }j式的不II1J . 可以 定 义 LFSR 的特征多项式: p(x) = 汇川xt=xm + fm斗xm-l +… + Jix + 1 ( 1 1-1) 可 以 证明, 山 特征多项式p(x))开对应的 m 级 LFSR 输出战氏序列的充�条件是: ( 1 ) p(x) = xnl + 儿,-IXM +…+ Jix + 1 , 是不可约 的 ( irreducible) : ( 2 ) 不存在k<俨-1, 使 得 (xk + 1 ) 能 被 p(x)整除· ( 1 1-2 ) \391\ 1 1.2.3 PN廖列应用实例 本章节将以 D VBC- 标准中的同步字节翻转与扰码为例, 介绍其 LFSR 具体实现。 如 阁1 1- 14 所示 , D VB-C标准中为了实现基带信号频谱成形, 首先应进行扰码, 从而得到平 均功阜谐。 在经过MPEG-2 传输 复阳器后, T S 码流以 固定的包长传输: 总共是188 个字节, 包 括一个字节的向步字 ( s ync- word, 其 值为4 7HEX )。 在发送端, 丁 S 码流的处理顺序从母、 高有究生位 (M S B)开始。 为了与卫且系统一 致和保证正确的时钊:恢复. MPEG-2 传输 复用拇输 出的数据'必须进 行扰码, 如1图 11-18 所示. i主伪随机二迸制序列(Pseudo Ra n d o m Bina ry S equne c e. PR BS ) 的 生 成 多 项式为: = + p(x) xlS Xl4 + 1 ( 1 13-) 在 图 11 -18 中, PN 码发生稽的部布楷书j始值为: 1 0 01 01 01 0 0 0 0 0 0 0. MPEG2- 撤 据 流 中 , 每8 个数据帧组成一个数据组. PN 码发生器的部存器在传输 每一个数据组的开始 时初始化一次, 为了提供该初始化信号, 每一组数据中 的第一个MPEG-2 数据帧的同步 字节按比特反转, 即 4 7H EX 反转为B8H EX. 而MPEG-2 数据流中所有同步字节不参与 扰码。 1 00 10 切盼化Ir列 o 0 0 0 000 000创沁1 1. ..• AND 4此向/解忧量H<<输出 {直II� m除Itt1i'llk!l<输入 致1<输< 入(MSB) PRBS 序列 41先,101111创沁 ,1 x x x Ix x x x x 000 1000 1 1 .._ 国11-18 DVB.C忧码/解扰实现低因 对于圄川- 18 的 D VB-C扰码/解扰实现框 剧, 需要说明的是: • PN 码发生器的寄非据初始 值置为1 0 01 01 0100.0 • PN 向发生器在传输 每 一个数据组 ( 8 个数据帧〉时初始化一次. · 每一组数据 中 的第一个MPEG-2 数据帧的同步字节技比特反转. • MPEG-2 数据流中所有同步字节不参与扰码. • 译码部分和译码原理完全相同. / 392� • '自11. 1 1 .2.4 程廖说明 完整的 D VB-C标准的扰码与向 步字节翻转程序代码如下: IIFile name : randomizatio n . v IIFunction:sync 1 inversion and randomization module randomization (clk, start, rst, valid_in, Dataln, sync_in, DataOut, sync_out) ; parameter PacketLength - B ' dlBB; //输入/输出埠定义 input clk, start, rst, valid .ln, sync_io: input [7 : 0 J Dataln; output (7: 0 ] DataOut; 。utput sync out; 11变量定义 reg [ 7 : 0 ) DataOut; reg sync_out; reg [ 7 : 0 ] ByteCouot; reg [3:01 PackCouot; reg [ 1 5 : 1 ) m-sequence; reg [ 7 : 01 m_seq_reg; always @ (posedge clk or posedge rst)begin: Randomizat:ion integer i; reg [ 1 5 : 1 ] temp_seq; reg [ 7 : 0 ] temp reg; if (rst)begln ByteCount <= 1 ; PackCount < = 1 ; DataOut: <= 0 ; m-sequence 〈 = 1 5·bOO O-0000-0000-000OJ m_seq_reg <= 8 ' bOOOO_0000; end else i f (valid_in) begin if(start)begin DataOut <…Dataln; 11同步字节反转 ByteCount <- 2; PackCount <- 1 ; m-s equence 〈 - 15·b0 10-1001-0 000-00111 m_seq_reg <皿B 'bOOOO 0 0 1 1 ; end else begin 队393\ 11m序列生成器 temp_seq = m_sequence; i>=O: for(ì�7; i-ì-l)begln temp-zeq{i]= temp-seqI15] 《temp-seq[1411 en dtemp-seq ={temp-seq l14: 11, temp-Eeq[il}; m- se ence 〈 mv飞 M-一 z争-h、 e mp 地阔 m­ se izeq 〈 - q ., e m p ­ j q ., case(ByteCount) S'hOl: begin II每一包的第一个字节 if(PackCount -- l)begin //每一帧的第一包 DataOut <- -Dataln; II同步字节反转 ByteCount <- 2; end e1se begin DataOut <- Dataln; //每一帧的随后7个包 II同步字节保持不变 ByteCount <- 2; e!'ld end PacketLength: begin if(PackCount--S) PackCount <= 1; e1se PackCount <- PackCount + 1 ; ByteCount <- 1 ; DataOut <- Dataln ^ m_seq_reg; end defau1t: begin ByteCount - ByteCount +1; DataOut <- Dataln ^ m_seq_reg; end endcase end <= sync_out sync_l.n; end e1se begin {sync-out, Dataout}〈={sync-in, 8·hOO}J end end endmodu1e 对上面的程序说明知 l下. • /394!A 第11 j撞 ( 1 ) 为 了满足 DV B-C标准规定, 担ff中用到"stan叫抖, 作为一个数据组(8 个 数 据帧长〉的起始标志. 用 以 实现 每一组数据中的第一个数据帧的同步字节按比特反转, 以 及PRBS 序 列加载初始值. ( 2 ) 程序 中使用"sync "数据帧闷w标忐, 用 以 控制不对 一个数据组的后ÚlÎ7个数据 帧的同步字节进行扰码. ( 3 ) 为了便于后续信道处理, 该模块同时输 出同步标志和扰码后的数据. 如困 1 1-1 9所示 为扰码与同步字节翻轩的iJí页,波形, 该被形只显示出前面几个字节的扰 码输 出. 辛,.",...., - "" ftI lntcT咽1 .:.l:JPOllU睛: ..ncr Tbc aar:. 1.09回 4ft. t I -615.6 .. SU.r\: 。 po 160.0 .,. 吨1_" JU- E‘0. 0 肉, ,扭.。因 ‘ m 。。. … A ‘嗣. 。帽 ‘'‘'‘ b咽: ,副队0 .. . 口� '也。回 11 ..0.0.. "‘ dll I飞J"1..-J' LIl__f飞J'LJ'飞J1J飞J飞J飞J飞J1J ...Uu'I' 0) h 扭 曲" 。皿·阳回 'qmeenor d"'..). 1 01 - 翩翩1(7 01 呻-0 Ollt_.饵" 的,咱酬or 因 1 1-44 UART 接收模圳在接阁 保布原理国为 uartrxtx.bdf. 编译工R文件, 编i辛无误后吓tiÏì Processing - Generate Fuoctional SimulaliOD Nellist, 产生功能仿点同哀。 新il!波形仿真文件, 加入输入输出 信 号 , artrx以 设置系统时钟信号 clk 的 周 期 为 20ns, {呆在被%文件为 u .vwf, !)i击 巳 按旬l迸行 UART 数据搜收的波l�仿真 , 被J�仿真报竹如 图 川 -45 所示。 r.. ‘。 11& as &1 <14. 咽 8 1 缸 u I Ot ‘ " ... 1ω clk c.4l1k.ou‘ ‘a 固 tlu...‘ ..…B 回 i.hn.\. ,l.,4..i...‘.rTW 4.tawror 困 1 1-45 UART �收模块的被形仿真报tti 波形仿真报告说明z 对 剧 1 1 -45 分析看 出 . UART 接收棋块接收到的数据 与 UART 发送棋块发送的数 据 相一致, 每接收 到一 个数据r.1i {J一个 读取数 据指I(J rdisg, UART 接收税块得到 l巨确 验证. 1 1 .5.6 UART 的硬件测试 儿) r 测试 UART 与 PC迦们的正确性, 今;例如l试方法是, PC 将她据发遮盖IJ FPGA. PPGA 接收到数据再发送给 PC. FPGA 与 PC 届信棋块连接原理国如回 1 1 斗6 所f12. / 432 /� 毡 .. [P'V2I .. 、 ,. c. cJ‘a咀 翩、\ 第11 章 抑通倩与擅制翩 .似 .a . ‘h .. 圃>'11 ,羽 幽 幽血叫'饵 ,忘 何lI.q 01‘-咱, ,__鸣" 。例,时17 01 晴町 -饵" t,.,..霄" 阁 1 1-46 FPGA ,] PC 涵信校旗连接回想|刽 根据 PC 的 串 口 调试工抖的设置, 快l坦代码是否l1J�奇偶校驹仪, 以及分掘系数. 分 配 FPGA 引 脚 , 编译t稽, 连接好开/J:.板.& F载线缆, 接 k 电源, 下载配咒 FPGA, 打 开 JI 11 PC 的 吊 口 调试工具, 发送数据, 观察接收到的数据 , 如1阎 川-47 所示。 g L al b HUl L树').:i}U :1'.(I�� I ....11.' lCDL ....11., lCDL ...rilo‘ lCDL e 口 布: 阿t 被 将 事 1"s2öò • . 筐: 严 二j 停 止 � : 陋虱星回 二j 精蛐位 : lrm. 二j 刻幽鑫 : Ivoril., lCDL 精空蜜收区 . 些主」 旦旦」 退出 阁 11-47 PC I扫门调试工具 \433\ 噩噩噩摩设ìt:实倒翩 PC 串 口 调 试工具中发送" ve副og HDL", 同时接收窗口显示" verilog HDL". 说明 FPGA 的接收和发送模块与 PC 的通信正确. 至此, UART 收发器的验证全部完成. 1 1 .6 12C Master 控制器设计实例 12C ( lntel-lntegrated Circuit bus) 为 内 部 lC控制的双向串行总线, 用于连接微控制器 及其外围设备的互连. 本章以 FPGA 模拟 J2C 协议作为主端对 AT24C02 进行读/写操作, 来介绍 eC Master 控制器的 Verilog HDL 吾i 古建模与硬件测试. 1 1 .6.1 12C总线协议介绍 J2C 总线只简要两条线, 其巾一条为时钟线, 另一条为数据信号线. 总统t的终端挂 在总线 匕 终端有主端与从端之分。 在同一总线上同一时刻只能有一个主端, 主制设备负 责初始化总线, 产生总钱数据传输所需的时钟。 在同一总统上可以有多个从端 , 每个从端 都有一个唯一的地址来标识自 己. 12C 总 线上传送数据时J'f剧如困 1 1-48 所示. 起始俯号 应唱'俯号 川山… SDA 71」 叫 t一7 一咄 什 SCL 地址 啊;Uj9!!川二" 了 LF!, 四 1 1-48 11C 总约 七传数�时IY.回 • 起!lfj信号: SCL 为 高 电 平 时 , SDA 由高电平 向低电平跳变, 开始传送数据• 4古地址fð 号: 传 7 位地址信号, 山高位到低位, 再加 1 位卖i /写标志。 • 传数据信 号: 数据技高位剑低位的顺序进行传送. • 停 I r.{占· 号: SCL 为自ru平时, SDA 由低电� 向 南 电 主y;眺变, 结 束传:送数据. • 陪伴俯号: 从端在强收完 8 位数据后. 在时钟信 号 SCL 为高电平时 , 设 吨1 数据信 号 SDA J.; 低电平, 即为应答信 号 , 衣示一个字节数据接收完毕 • 1 1 .6.2 AT24C02 介绍 AT24C但 是 ATMEL 生产的 � 行 电 叮楝可可编剧只读非储苦苦 , 宫的存储容址 为 2S6X 8bit, 封装小, 足广泛使用的 EEPROM 布fìtt�苦. 内部结构如闸 门-49 所示. /434/ VCC • GNO • WP 5CL 50A A A ,。A '自 11 :1脆 戴字通铺 5TA宵T 5TOP LOGIC LOAO OEVICE AOORESS COMPARATOR SEAIAL CONTROL LOGIC 4 COMP , EN H.V. PUUPITIMING OATA RECOVEAY LOAO INC AIW OATA WORO AOOR/COUNTER ω凶。 EEPROM 到 Y OEC SERIAL MUX 。恻 .r 。ωT 。剧,.JACK LOGIC 因 1 1-49 AT24C02 内部结构阁 封装与 引脚如圄 1 1-50 �¥l表 1 1-9 所示. ph UV AO Eμ S们C A1 口口21 h SDCmw GNAO2 口 口 34 a 口 cL ' ' 'A ' o e a 因 11-50 1\口4C02钊脚囱 A().A. 2 SOA SCL WP GNO VCC 弓l " 褒 11-9 引脚说明 号l.iIt明 , Address Inpul.S (地址设置口 Señal Data (11I1T敏�) Scrilll Clock Power Supply ( Il!.源) \435\ 反画同帽比 血牺摩酣跚蜻说 AT24C02 的器件地址设制如| 表 ) )- )0 所示。 褒 11-10 A;T24C02 的部件地址设置 。 AI AO R/W MSB LSB 其 中 , RIW 仿,为 "0" 表示主端向从端写资料, 为 " ) " 表示j:端l句 从端读数据. • AT24C02 读/写时序 FPGA -t端向 AT24C02 写资料时序: ① FPGA 向总线发出开始信号: ② FPGA 向总线发出需要写数据器件的器件地址和写信号并等待 AT24C02 产生应答 信号: ③ FPGA 向总线发送要写的存储地址 并等待 Aη4C02 产生应答信号·: @ FPGA 向总钱发送所要写的数据1 ⑤ 等 待 AT24C02 产生应答信 号. FPOA 向 总线纠;送结 束 信 号 , 完成一个字节的写 过程. AT24C02 可数据时序圄如 剧 ) ) -5 1 所示. E』 C TATSR DEVICE ADDRESS WRITE W 。 n川 o A nu D R DATA STOP UV MSCBLU mUNE UUMSB 1 τ寸 | |·: : L S RI BW CA K MSB : : :一: : | AC K | : : : : : : : i ACURH 附 川 -51 þi.η4C02 可数据时!节问 FPGA 从 AT24C02 读数据时序: ①FPOA 协商向总线发送开始信号: ②FPOA T:踹 向总统发送;JJE?读数据拇件的辅件地Jlt和写信 号并将待 AT24C02 严'1:.应 答信号: ③FPOA 1:端向总线发送所需读数据的地址并等待 FPOA 主端产'EJ_业答信号: @接着 FPOA 1=.端向总统发送开始的 号和需要读数据器件的器件地址及写信号)j:等待 AT24C02 产生附件信 号 : ⑤FPGA 主揣战从高剑低位按收总线七的数据: @产生停止信号结 束数据的读取. /436/. 第 11 . 戴字通铺 Aη4C02 读数据时序国如阁 1 1-52 所 示 。 SDA UNE W R s R S l T E WOAD : OEV肌 肉 AOOAESS E A O T 。 P ADOAESS n T ITUl广?1||·:::::::| 门1Ilζ=nl:::::::IU M L A AM s S I CS B eW K B OUMMY WAITE LA M sC s 8 LA sc 8K OATA n N 。 A c K 图 1 1-52 Aτ'24C02 谈数据时序图 1 1 .6.3 J2C Master 控制§代码设计 时钟操作是总线的关键部分, 为 了 豆加清晰地分析 J2C 的时序关系, 本例把一个时钟 周期分为 4 个部分: a、 b、 c、 d, 如 剧 1 1-53 所示. a ibici d 图 1 1-53 12C 总线时钟周期分割 Verilog HDL 代码如 下 : case (st.art;cnt) 2'bOO: begin scl <= l ' bQ ; //ß.t争" a 段 startcnt <= 2 ' bOl; end ' bO l : begin scl <= l ' b l ; //时钟 b 段 st.art.cnt <= 2 ' blO; end 2'blO: begin scl <= l ' bl; //n忡l' c 段 startcnt <- 2 ' bll; end �437\ 2 'b11 : begin scl <- l ' bO; /1时钟 d 段 startcnt <- 2 ' bOO; end default: beg�n scl <- l ' b O ; startcnt <= 2 ' bOO; end endcase 12C 总线起始信号的特征: 在时钟信号 scl 为 高电平时, 数据信号 sda 由高到低跳变­ Verilog HDL代码如下: assign sda- (link)? sda_b u f : l ' b z ; 1/敛据倍号 sda 双向瑞口操作 start: begin case (startcnt) 2' bOO: 11时钟情号与敛据信号郁为高 begin scl <- l ' bl; sda buf <- l ' bl ; link <- l ' bl; startcnt <- 2'bOl; end 2 ' bO l : l/时钟俏号保持为 高. 数据信号设为低 begin scl <- l ' bl: sda bUÍ <= l ' bO ; link <= l ' bl: startcnt <= 2'blO; end 2 ' blO: I/时钟信号设为低. 数据信号保持为低 begin scl <- l ' bO; sda buf <= l'bO; link <= l ' b l ; startcnt <= 2 ' bll: end 2 ' bl l : 11时钟俯 号与数据信号都保持为低 begin scl <� l'bO; 1438h 一 . 11 1民 sda buf <� l'bOi 1ink <- l ' bli startcnt <= 2'bOOi inner state<�firsti end defau1t : begin scl <= l ' bli sda buf <- l'bli link <- l ' bl; startcnt <- 2'bOOi inner state<=starti end endcase end FPGA 主端发送 AT24C02 的地址信号和读/写标志z 先发送 AT24C02 的地址信号, 从 高位到低位, 然后发送读/写标志。 Verilog HDL 代码如下: assign sda- (1inkl ? sda_buf : l 'bzi //敛据信号 sda双向端口操作 • case ( startcnt) 2 'bOO: begin sc1 <= l'bO; sda_buf <= chipaddr [7] ; 1ink <= l ' bli startcnt <= 2 'bOli end 2 'bOl: begin scl <= l ' bl; sda buf <- chipaddr [ 7 ] ; link <= l ' bli startcnt <- 2 ' blOi end 2'blO: • begin scl <= l ' bli sda buf <- chipaddr [ 7 ] i link <= l 'bli startcnt <- 2 ' blli end 队439\ 一 2 'bll: begin sc1 <= l ' bO; sda_buf <= chipaddr [7] ; li盯k <= l ' bl; startcnt <= 2 'bOOi inner state<=se'cond; end defau1t : begin sc1 <= l 'bl; sda二buf <= chipaddr [ 7 ) ; 1ink <- l ' b1; startcnt <= 2 ' bOOi inner state<=firsti end endcase 代码分析z 上面代码用于发送 Aη4C02 地址和读/写标志, 重复 7 坎上面 的代码就可把 AT24C02 的地址信号和读/写标志发送完成。 发送完 AT24C02 的地址信号和读/写标志后 , 接着就是 FPGA 主端检测 AT24C02 发迭 的应答信号。 Verilog HDL 代码下。 assign sda= (linkl? sda_buf : l 'bz; //敏据倍号:. sda 双向端 口操作 ack: begin • case (startcntl 2 ' bOO: begin sc1 <= l ' bO; 1ink <= l ' bOi //更改数据信号sda 模块的输入 startcnt <= 2 'bOl; end 2'bOl : begin . sc1 <= l ' bli link <= l 'b O ; startcnt <= 2 ' blOi end 2 'blO: begin 1440iA 第 11 '1撞 scl <- l ' bl; link <- l ' bO; sda buf <- sda; //在 : 时钟俏 号为 街 也平时, 来样敬据信 号 sda 的值 startcnt <- 2'bll; end 2'bl1: begin sc1 <- l ' bO; link <= l ' bO; startont <= 2 ' b OO; if (sda buf 草草 l 'bO) 1/虫防融胁;俏电'sda 的健;!kJfß:. 贝'n苟部版剧AT24C02 的目晦信号 begin inner state<=first; i2c state<=sendaddr; link <= l ' bl; end else beqin main state<=3 'bOOO; inner state<=start; end end defaul t : begin scl <- 1 ' b1; sda buf <- 1 ' bO; link <- l ' bl; startont <- 2 ' bOO; inner state<-ack; end .endcase end 代码分析z 检测 AT24C02 的应答信号需要更改撒据信号,. sda 的输入模式, 这样 FPGA 主端才可以 正确接收 12C 总线上的数据. T2C 总线停止信号的特征= 在时钟信号. scl 为高电平时, 数据信号 sda 由低jlJj商跳变. Verilog HDL 代码如下: assign sda� (link)? sda_bu f : l ' bz ; //数据信号. sda 双向编1-1操作 stop: begin 0.441 \ case (startcnt) 2 ' bOO://时饼与戴揭倍号都为低 begin scl <- l ' bO; sda buf <- l 'bO; link <'" l ' bl; star�cnt <罩 2'bOl; end 2 ' bO l : / /时钟偏号变为高, 数据信号保持为低 begin scl <- l ' bl; sda buf <- l'bO; link <- l ' bl; startcnt <- 2 ' bl0; end 2 ' b l : / / 时钟俏号保持为高. 数据信号保持为低 begin scl <- l ' bl; sda buf <- l ' bO ; link <- l'bll startcnt <- 2 ' bll; end 2 ' bll: //时钟倍号保持为高, 敛据信号设为商, 产生低到高的跳变 begin scl <- l 'bl; sda buf <- l'bli link <- l ' bli startcnt <- 2 ' bOO; inner state<国start; i2c state<-ini; main state<-2 ' bOO; end default: begin scl <草 l ' bl: sda buf <= l ' bO; link <- l ' bl; startcnt <- 2 ' bOO: inner state<=ack; end endcase end 1442 /.. • 翩惰� 第 11 意 醉通偏与翩 将以上的代码段组合起来 , 就可以对 AT24C02 进行读/写操作 了 . 首先进行写操作, 根据图 1 1-51 所示. FPOA 对 应24C02 的写时序由 以下代码段组成: · 产生起始信号 : • 友送 AT24C02 的地址信号和写标志: · 等待并检测 AT24C02 的应答信号: • 发送所要写数据的地址信号: · 等待并检测 A口4C02 的应答信号 : · 发送所要写的资料: · 等待并检测 AT24C02 的应答信号 : · 产生停止信号 . FPGA 对 AT24C02 的读时序由以 下代码段组成: · 产生趋始信号 : · 发送 AT24C02 的地址信号和写标志 : · 等待井检测 Aη4C02 的应答信 号: • '),之i恙所要写数据的地址信号: · 等待井检测 AT24C02 的应答倍号 : · 再次产生起始信号 : · 发送 AT24C02 的地址信号和读标志 : · 接收所要读的数据 : · 产生停止信号 . 由于篇幅有限且完整 代码有工 千多行, 这里没有食部列出 , 元朝代码请读有参苟先在 内容. 编写完整代码, 保存为 i2c.V. 编译'民个℃程. 编译无i提后1艳rIr Processing → Generate Functional Simulation Netlisl. 产生功能仿真同表. 新建波)�仿真文件, 加入输入输山信号·. 设 置 系统时击中信号 c1k 的 周 期 为 1 Ons. 保存披J�文件为 ücwr.vwf, 单击 t. I!主 制进行 A丁'24C02 写数据的波形仿真. 波形 仿贞.报行如l图 门-54 所示. 啊 .. ._. .. 0 I " 、 d‘ v'_a..,.‘ ,ι.呻M ..1 h血 d气..r ••• Gi .�叩..... 但 4.、"抽 Ii cl.hl'" , . ... 斗"咀‘ 也1' " ‘翌23 ‘� 主旦.. ·可怕 ‘!l.恤 旦旦旦 闯 1 1-54 '"口4C02 写数据的波}�仿ti.m�与 \443\ 忍耐町、脱脱郎郎十唰刷 波形仿真报告说明t 在 波 形输 入 文 件 中 , 设 置 AT24C02 的 地 址 为 " 1010000 " , 所 写 数 据 的 地 址 为 "0川00100飞 所写数据 为 " 00001 101 气 被形仿真报告 中 的 sda-buf 信号与以 k数据相对应, FPGA 对 AT24C02 写数据仿真正确。 更改披形仿真文件的输入信号为读数据 , 单击 思 i按钮进行 AT24C02 读数据的披形仿 真, 波形仿真报告 如 阁 1 1-55 所示。 11 ... 也田 " ‘ ._..: 4町M ‘四" .. 军田" S田" 一霄‘ 、 一 u.. _• I ".. U'Pu.也 rd, i戳put 雀.1 H晴 'ù_buf .d. � 4"..u\ 国 11-55 AT24C02读数据的法形仿真报告 波形仿真报告说明z 在被形输入文件 中 , 设置对应时刻的 sda 信号的值, 披形仿真报告中接收到的值与 sda 的值相对应, FPGA 对 AT24C02 读数据仿真正确. 1 1 .6.4 12C Master 控制器硬件测试 为了测试 (2C Master 控制器的硬件, 需要添加一个测试模块, 产生读信号、 时钟信号、 地址信号和数据. 驰而og HDL 代码如下: modu1e testi2c(c1k, dataQut, chipaddr, dataaddr , W�, rd , clk�) ; input clk; output [ 7 : 0 ] dataout; output [ 7 : 1 ] chipaddr; output [ 7 : 0 ) dataaddr; 。utput wr, rd; output clkt; reg [ 7 : 0 ] dataout; reg [ 7 : 1 ) chipaddr; reg [ 7 : 0 J dataaddr; reg wr, rd, c1kt: reg [ 1 9 : 0 ] cnt:.; ! 444 ;' 第11 J撞 always @ (posedge clk) //1.'l系统时钟进行分掘, 产生所捕的时钟伯号 begin <= cnt cnt + 2 0 ' d l ; clkt <= cnt [ 8 ] i end always @ {posedge clk} begin <= wr l 'bl; rd <= l ' b O i <= l dataout 8 ' d OO i chipaddr <= 7'blOlOOOO; <� dataaddr 8 ' d12; //写信号 //该信号 1/数据 IIAT24C02地JJI: / / 数据地址 end encimodule 保存文件为 恼li2c.v, 单击 Files → Cr四te/Update → Create Symbol Files for Current File 命 令 , 为 tes归c.v 生成原理固模块. 新建一个原理阁文件, 在原野.圄空白处双击, 在 弹出的 Symbol 对话框巾选择 Project → t臼ti2c 模块和 应c恢块, 11.1.击 OK 按钮退出 Symbo1 对话框. 在原理囚的适当位置放置 泣c 模块和 testi2c 模块, 并海}JU输入输出模块。 各个模 块的连接如 图 1 1-56 所示. •••• •••• • • •• . . •• • •••• • ••.. EJL;1 :王飞J rl嗣,. 『 响 。恤恨皿-."1'.句1' 翩翩柿。明 ., ... •• ,,, • 11 01 ••... 自主. 量国 响叫睛" ‘ .. .. ••• -0··(. •. . . . . .. . . .. ... .• . . • … "•. .• �... … '• .".• .•. … . . . , •. ".• .,,一 ..… .….….. ..… . .........•. .…. ••. .•.,. •". .…. •. • ., • • • •... …. ….. . • . •. . •' • .. ….. . . •. .…. . . .. . .... . ' … .. .. . ... .. .. ... .. .. .. .... … .... .. .. . ... . ... •. .. .. .τ.. • 剧 1 1-56 ec 使件测试锐块连拔倒 . . . . . …. i . . .. . • • • • • .• •. …. ..-…• . ·一 • ...一~ 保存原理国为 iicwr.bdf. 新建一个 Logic Analyer 文件, 观察时钟倍 号与数据信号是沓 传输正确. 来样时钟设为 Clkl, 采样探度为 缺, 编译℃程文件, 编译无误后连接下载线缆. 接通电源, 下 载 iicwr.sof 文件对 FPGA 进行配置, 单市 Processing → Run Ana1ysis 进行 观察, 如阁 1 1 -57 所示. \445\ /石丽毗应耀廖酣实唰浏 军民J 1.:嘿… • 量虫 • @ 甜'翻" • g dII-* ' @ 幅庸、 一 I Ot OOOl 0001 I饵 )b 帆'∞10Clb 图 1 1-57 应24C02 穹过程测试 Logic Analysis 分析z FPGA 的写时j乎完全与前面仿真的一致, 数据信 号 sda ' J 朋 友萃j 的 资 本1.一敛 , AT24C02 的应答信号也正确严生 , 因 此 FPGA 的写时序得到正确驼,hE. � 改 testí2c.V 为 读测试, 再进行上面的 Logic Analysís 分析 , 结 果 古JI 阳 1 1 -58 所 示 . 些• 哩lI些白jI r啕阳ne L…3一…一旦……..JE…卢…:变--……":旦……J立一…_. ø I I íÐ CHtøà 011001伽 一 一 �制缸' !Ð ô翩翩蛐 18 æ 幅画、 101000b OOtO lQOb 011001创:1) 阁 1 1-58 AT24C02 读过科 Logic Analysis 分析z FPGA 对 Aη4C02 的证: 操作时 , 读取先前写 的数据 , 结 J提出 :1 1 的 优 , -)可 入 的 故据 一致 . 1);1此 FPGA 的 出 时fif.得到正确验证 11.7 SPI Master 控制器设计实例 SPI ( Seríal Perípheral Interface. 串 行外用 设 备接 仁1 ) 是 · 利' 个 /.'. i_ n可 �y通怡总均 水 节 盯 先介绍 SPI 的 协 议 、 传输时j子 , 然后使用 Verílog HDL 讯 ,'j'illH也 模 号 仿 点. . 1 1 .7.1 SPI 界面介绍 SPI 就 是111 行外罔 设备接n . 是 Motorola 芮先在其 MC68HCXX 系判处理器 i : ;主 义的 . SPI W1(li l:巫山川在 EEPROM、 FLASH、 实时时钟、 A D 转 缺 栋 」止敌?千二i 号处理器和数.r: u 信号· 时间拇之例. SPI 是一种迫旦在较高、 全观工、 lJ岁的通弘总rt. )1. n在芯片的引脚 1'. 只 占 J.1] 4 根线 , 节约f芯片的才|脚, 同时为 PCB 的布}..j 怕有呼吁'11J , 提供方便, 正 U; : l 1 r­ 这种简1在劫剧的特 性 . 现在越来越多 的芯片集成 了这种副 i 主协议 SPI (�J且l f�原理很简 吧 , 古 以 1:从方式工 作 , 这种方式迦:币:-(i . 个 主 设 备 和一个!oc多 /446/ 第1U 挺 个从没备, 至少需要 4 根线 , 其实 3 根 也 可 以 (单向传输时〉。 也是所有基于 S凹 的设备 共有的, 它们是 SOl (数据输入〉、 SOO (数据输 出 〉 、 SCK (时钟信号〉、 CS ( 片 选信号). ( 1 ) SOOf-主- 设备数据输出, 从设备数据输入. 在片选信号有效时, 数据由自位到 低值, 在时钟的上升沿依次发送给从陡备. ( 2 ) SO←一主设备数据输入, 从设备数据输出. 在片选信号有效时, 数据由两位到 低值, 在IH钟的 t升沿依议发送给主设得. ( 3 ) SCK一一时钟信号, 由主设-%-产生. 在片选信号有效时, 产 生 SPl 时钟信号低, t: 从 设 备 数 据 同 步 使 用 。 (4) CS-从设 备 使能倍号 , 低有效 , 由 t:设备控制. 其 中 , CS 用于控制芯片是否被选巾, 也就是说, 只有片选信号为预先规定的使能信 号时 〈高电位或低电位), 对此芯片的操作才有放. 这就使在同一总线上连接多个 SPI 设 将成为可能. 通信是通过数据传输来完成的, SPI 是 串 行通信协议, 也就是说, 数据是一位一位 传 输 的 。 这就是 SCK 时钟线存祀的眼|坷, 由 SCK 提供时钟脉 冲 , SOI、 SDO 贝IJ 慕 于 此 脉冲完成敏据传输. 数据血过 SOO 线 输 出 , 敏据在fl1钟上升沿1&下降沿时改变, 在紧 接着的下降沿或上升沿被读取, 完成一位数据传输 , 输入原理与输出一样。 这样, 温 过至少 8 次时钟信号的改变 〈 七升沿和下降陆为一次), 就可以完成 8 位做据的传输, 如 图 1 1-59 所示. c na SCK SDO 口 因 1 1 -59 SPI 时J�j图 1 1 .7.2 SPI 分频模块 由于系统时钟 与 SPI 设备的可能不一致, 肉些南要进行分颇, 分频器的 Verilog HDL 代码如下: module clkdiv (clk, cl kout ) ; input clk; output clkout; / / 系统时钟 / /在� fl'. 时钟输出 \447\ 应用雹摩设it实倒醺瑞 reg c1kout; reg [ 1 5 : 0 ] cnt; a1ways @ (posedge c1k) / / 分频迸程 begin if (cnt == 1 6 ' d l ) //占空比系数 begin clkout <罩 l ' bl; cnt <= cnt + 16'dl; end else i f ( cnt -- 1 6 ' d3 ) //分频系数 begin <- clkout l'bO; <= cnt 1 6 ' dO ; end else begìn cnt <= cnt + 16'dl; end end endmodule 保存文件为 clkdiv从 Jf!.击 Files - Create/Update → Create Symbol Files for Current File 命令, 为 clkdiv.v 生成原理图模块. 新建一个原理国文件, 在原理剧空白处双击, 在 弹出的 Symbol 对话框中选择 Project - clkdiv 模块. J)1击OK 按钮退出 Symbol 对话框. 在原理图的适当位置放置 cLkdiv 模块, 并添加输入输出棋块. 保存原理国为 spi.bdf. 编译 t租文件, 编译无误后单击 Processing → Generate Functional Simulation Netlist. 产生功能 仿真网表. 新也被形仿真文件, 加入输入输出信号 , 设 置系统时钟信 号 clk 的周期为 10r邸, 保符波形文件为 spi.vwf, .1'(1击 巳 按钮进行分频器的波形仿真: t 波 形仿真报告如 国 1 1-60 所示。 E… " 11细. 5.9MQI 崎 .9 DS !o 9 QI 80,9 "" 1翻,). 0 "" 120.!l '" 140.!l 1ll 1阔.,0 III 180). 1 IIS 21 旦旦 " clb.\. 阁 1 1-60 分频糠的旅形仿真恨帘 被形仿真报告说明= 分频时钟输出实现了所帘的 4 分额, 分频摸,块得纠正确验证. /4481A • 第11 章 1 1 .7.3 SPI 主蹦发送数据部分 SPl 主端发送模块的功能: 接收到发送数据指令后 , 产生从端的片选信 号 , 接着产 生数据同步所需的时钟信号, 同 时把所要发迭的数据在时钟的上升沿发送到 SPI 总线 上 。 最 后 , 数据发送完成后恢 复片选信 号 为 无 效 , 停止时钟信号的产生o Verilog HDL 代码如下: module spimaster (rst, clk, rd, wr, datain, spics, spiclk, spido, spidi, dataout ) i r input st i input clki input rdi input wri input spidii input ( 7 : 0 ] dataini II置位信号, 低有效 I I 时钟信号 / /接收数据命令 / / 发送数据命令 IISPI 数据输入信号 II发送数据输入 。utput SpiCSi output spiclki output spidoi output ( 7 : 0 ] dataouti IISPI 片遮信号' IISPl 时钟信号· IISPI 数据输出信号 II接收数据输出 zeq s eS d P1-ze9 s c1 PPL-l· '·'·民Lre9s d · o h reg ( 7 : 0 ] cnt, dstate, dsend, dreceive, dataou'ti . reg ( 1 : 0 ] spistatei , parameter idle � 2 ' bOOi = parameter send data 2 ' bOli parameter receive_data = 2 'b lO i @ • alw,ays (posedge clk) begin if ( ! rst) begin <= spistate 2 'bOOi <= 8 i cnt ' dO <= spics l 'bli <= spiclk l 'b1i spido <= l ' bl i • � 44 9 \ • dstate <... 8 ' dO; end else begin case (spistate) 2 'bOO: begin spics <= l'bl; spiclk <= l ' bl; spido <= l ' bl; if(cnt ... 8 ' dO ) begin cnt <- 8'dOi -� && 1f( (wr l ' bO) (rd -= l ' bl ) ) begin 、 spistate <- send datai //发送数据转换 dstate <- 8 ' dOi . dsend <= dataioi end && else if ( (wr -= 1 'bl) (rd -- 1 'bO)} / /接收数据转换 begin spistate <= receive_datai dstate <- 8 'dO; end ‘ end else , begin + cnt <- cnt 8 ' dl; end end 2 'bOl: //发送数据状态 begin • case (dstate) 8 ' dO: //产生片选信号有效 begin spics <- 1 'bO; <.. spiclk l ' bl; spido <'" l ' bl; dstate <= 8 ' dl; end . 8' dl: /450 . 11 . begin <- spics l 'bOi <- 1 spiclk 'bli <- spido l 'bli <- dstate 8 ' d2i end 8 ' d2: begin <- spics l'bOi <'" spiclk 1 'bOi <- spido l 'bl; <= dstate 8 ' d3i end 8 'd3: begin <= spics l 'bOi <- ' l spicllt l b ; <- spido dsend (7) ; <- dstate 8 ' d4; end //发送数据是高位 8 'd4 : begin <- spics 1 'bOi spiclk <= l ' bOi <= spido dsend(7) ; <= 电 dstate 8 'd5i end , 8 ' d5 : begin <- spics l ' bO; <- spicllt l'bl; <- sp�do dsend ( 6 ) i • <= dstate 8 ' d6; end 8 'd6 : begin <= O spics l'b ; <= spicllt l'bO; <- spido dsend (6) ; <- dstate 8'd7; end • " 451 \ • 8 'd7: begin spics <- l ' bO ; spiclk <- l ' bl; spido <- dsend [ 5 ) ; dstate <- 8 ' d8; end 8 ' d8 : begin spics <- l'bO; spiclk <.. l ' bO; spido <.. dsend (5 ) ; dstate <- 8 ' d9; end 8 'd9: begin spics <- l ' bO; spiclk <- l ' bl ; spido <- dsend (4 ) ; dstate <- 8 ' dlO; end 8 'dlO: begin spies 〈- 1·bOJ spiclk <- l ' bO; • spido <- dsend (4 ) ; dstate <- 8 ' d l l ; , end 8 'dll: begin spics <- l ' bO; spiclk <- l ' bl; • spido <= dsend (3) ; dstate <= 8 ' d12; end 8'd12: begin spics <- l 'bO; spiclk <- l ' bO; spido <- dsend ( 3 ) ; •. dstate <- 8 ' d13; /452 . 11 • end • S 'd13: begin spics <- l 'bO; spicllc <= l ' bl; spido <= dsend ( 2 ) ; dstate <- S ' d1 4 ; end S ' dl 4 : begin spics <= l 'bO; spicllc <事 l ' bO; spido <- dsend [2) ; dstate 01 C相位为军); • )=>10 (相位为 180). 波形图如图 1 1-64 所示. 基辛告信号码 曼彻斯特码 剧 1 1-64 生tlVJ斯特码滋形凶 生主彻斯特编码是一种 自动间 步的编码方式 , 即时钟同步信 号就隐藏在数据波形巾 . 在 曼彻斯特编码中, 每一位的中间有一次跳变, 中 间 的跳变既作时钟信 号 , 又作数据信 息 从高到低跳变表示 " ) ". 从低到高跳变表示 "0". 曼彻斯特编间娃将时钟和数据包含在数 据流中, 在传输代码信息的 同时, 也将时钟同步信 号一起传输到对方, 每位编码中有一次 跳变, 不将在且流分盘, I玛此儿有自同步能力和良好的抗 F忧性能. 但每一个问元部被调 制成两个电平, 所 以 数据传输速率只有调制速率的 1/2. 1 1 .8.2 曼彻斯特码编码器 恨据处彻斯特码的问咆特点, 设 计曼彻斯特编码器的方让Þ.II 下 : 如果输入数据为 " ) ", 则转换为 " )0"; 如祟输入数据为 " 0 飞 则转换为 .. 10飞 然后 把官们串行化输出. Ve州og HDL代码如下: module mcode (clk, databin, datamout) ; pln ut clki input dat.abini I/Ii't钟{占号 11披据输入 /460h . 11 . output datamout; / /�曼彻斯特编码输出 reg datamout; reg flag; reg [ 1 : 0 } com; //标志信号 always @ (posedge clk) begin i f (f1ag = l 'bO) begin if (datab1n � 1 'bO) begin com <- 2 'b01; end else begin com <- 2 ' blO; end end end //当数据为 " 0 " 时. 转换为 "01" //当数据为 " 1 " 时, 转换为 "10" always @ ( posedge clk) / / �曼 彻斯特编码输 出逃租 beqin if (flag -- l ' b1) beqin datamout <- com[l ] ; flag <- �flag; end else beqin datamout <- com [ O } ; flag <…flag; end end encimodule 代码分析s 由于曼彻斯特码在码型上实际是把原来的一个码元转换成两个码元, 因此每输出两个 码元才进行一次数据码元的来样, 用标志信号 f1ag 来指示. 461 \ 矿面马帽λ JVIIJß酣翩 保在文件为 mcode.v, 单击 Files → Creale/Update → Creale Symbol Files for Current File 命令 , 为 mcode.v 产吧原理国模块. 新m一个原理图 文件 , 布原理图�向 处双击, 在 弹 出 的 Symbol 对话框巾.QI.;佯 Project →mcode 帧块, 单击 OK 怯创1ll! 出 Symbol )(,t 讯框. 在原理剧的道当位置放咒 mcode 模块, 并添)Jn输入输出模块。似乎fJ点. 坦因为 mancheSler.bdf, 模块连接 阳 如 图 门-65所示. 何、COde clk clk datamout dalamoul databfn databln InSI 剧 1 1-65 舍是彻斯特编伺候块连接回 编译工程文件, 编i杀无误后单击 Processing → Generate Functional Simulalion Netlist, 产生功能仿真网衰。 新边被形仿真文件, 加入输入输出信号, 设叫系统时钟 信号 clk 的周 期为 10ns, [(1市选 中输入数据信弓. databin, 可ll, ï >@ 按钮设置输入数据信号 databin J.J 随机 11lmI川肌 iiiI 数, 儿J, WJ为 2005, 即为 ut. i:1中川剧的 2 倍, 如回 1 1-66 所示. G制制ðle帽回omv蚀m r E四"y ørill riervðl r Ev酬y恻orldriervðl r A11笛"町、tnterv,'ðIl r. 自lfQ回跑盟副 l叫阳时 陌τ� 1m丁 � Cancel I |锦 1 1 -66 设n随机信号 CMt-披形文件J-J manchesler.vwf, 啦,1'( 巳 怯·钊l进li坠构UWí特编码器的被形i}J点, 被J� 仿 真报价如闯 川-67 所示. E蛐. P' 40 Q I\S 伺. Q l\S 120 P 1\, 1ω-P M m O M 240. O M m O M mi 时一 i划 1 1-67 纶彻JI1í轮梢的'糕的旅 形仿tt.�IH', / 462/ 第 11 J民 被形仿真报告说 明 s 编码输出倍号 datamout 符合曼彻w耐编码规则, 当输入信号 databin 是 " 1 " 时, 编码 输 出 信 号 datamout 为" 10": 均输入信号 databin 是"0"时, 编码输出信号 datamout 为 " 0 1 ", 曼彻斯特编码器得到正确证形仿真. • 1 1 .8.3 曼彻斯特译码器 曼彻斯特译码的功能: 把接收到的业彻斯特编码译码还原为 曼彻斯特编码前的基带信 号 , 如1国 1 1-68 所示. 曼彻斯特编码输入 曼彻斯特 译码器 sl 基带f自号输出 回 1 1--68 �彻斯丰�' i挚问m阁 曼彻斯特译自吗器的关键是从曼彻斯特编码的数据流中准确提取 " 0 1 " 和 " 10 飞 并把 它转换为 " 0 " 与 " 1 "。 假设业彻斯特纳闷的数据流为 "01010101 ", 如柴从第一位卅始i学 码, 则结果为 11 0000": 如果从1在二位开始译剧, 则结果为 " 门 1 " 和头尼两个曼彻斯特码. 因此, 如果 曼彻斯特编码数据流中 只千f " 1 " !&H有 "0" 的编码, 那么足不能准确 得到IJì李 码结果的; 如 果 曼彻斯特编码敏据流'I 1 :1I现 " 00", 贝IJ "00" I�Íf后的问yb必定是 " 1 ": 如 果曼彻斯特编码数据流中出现 " 1 1 ", 贝IJ .. 00" 前后的问元必也是 '.0 110 根据前面的分析, 可以把 "00 " 与 " 1 1 " 作 为 经 彻斯特编码i学码的标志位. [11]如果检测到 " 00 " 或 " 川 ", 则从肝一个 " ) " WG " 0 " 开始以每两个问元为一到1.iJ.1:行曼彻斯特译剧, £j 照 出基4if{,T F7 0 Verilog HDL 代间如tF : module mdecode (clk, dacamin, dacabouC ) ; inpuc clk; inpuc datamin; //时钟输入 / / 处彻斯科蝙问输入 output databout; 1 / Ii! :fIJJ斯科i宇间领导出 reg dat:abouc; reg [ 1 : 01 com; reg Elag; • reg syn; always @ (posedge clk) 队463\ begin com <� (com [ O I , datamin); end always @ (posedge clk) begin i f ( (com -- 2 'b11) 1 1 (com 菌- 2 ' bOO) ) begin flag <- 2 'bll; syn <- 1 ' bl; end else begin syn <- 1 ' bO; end end //检测 "' 1 1 " 和 "' 00 " always @ (posedge clk) //:曼彻斯特李i 伺输出i1!程 begin i f ( (syn -- l ' bl) 1 1 (flag = 2 ' bl l ) ) begin case(com) 2 'bOl: databout <� l 'bO; 2 'blO: databout <- l ' bl; default: databout <- databout; endcase end end endmodule 保存文件为 mdecode.v,单击 Fill臼 → Crea忧旧pdate → Create Symbol Files for Current File 命令, 为 mdecode.v 产生原理圄模块. 打开原理图文件 manch臼ter.bdf, 在原理圈空白 处双击,在弹出的 Symbol 对话框中选择 Project -mdecode 模块,单击OK按钮退山 Symbol 对话框. 在原理固的适当位置放置 mdecode 模块, 并添加输入输出模块. 各个模块的连接 如阁 1 1-69所示。 川64h 第 11 章 戴字通铺与 datamout mdecode mcode clk databln 、〉 It呢 N同F π dalam由Jt | datamln clk d副abc且JI inst3 inst 。atøbout 阁 1 1-69 曼彻斯特译间锁块涟按倒 保存原盟国 为 mdecode.bdf。 编译工程文件, 编译无误后单rlí- Processing → Generate Fuoctional Simulation NetJist. 产生功能仿真网表. 打开披形仿真文件 manchester.vwf, 加 入输入输出倍号, 保存波形文件, 单击 思 扳钮进行曼彻斯特译间僻的波形仿真, 被形仿真 报告如国 川-70所示. .01 •- CUO ù.…‘ 4.ult.a ..,....‘ S ... 400 0 .. 1'1,. 40 9 .. 回. 0 .. 120.9 ... UIO9 ... ZIJO.9 .. 2 咽 ø .. UC) J) u 320 .0 .. J剧 由 .. 阔 11-10 曼彻斯特译码器的法形仿真拟省 被形仿真报告说明, 对国 1 1-70 分析看出, 曼彻斯特译码输出与曼彻斯特编码输入的数据基本一致, 曼彻 斯特译吗辘得到正确的波形仿真。 11.9 RS 编码器、 译码器设计实例 RS 编码端是 Reed Solomon 编码器的简称, 它 是 日 前最有敛、 Jlv.阳最广泛的差错控制 编码方法之一. 它是 1960 年 由 lring R臼d 和 Gus Solomon η-先构造出来的一种 BCH 码, 既能纠错随机误码又能纠错突友性误码, 在敬据通信 、 电视传输、 数据再储将领域得到广 泛应剧 . 1 1 .9.1 RS 编码器的设计 下面简要介绍 RS 编码的基本原理, 并以 RS(63,45)为例, 介绍 RS 编码的 Verilog HDL 语言设计过租. 队465\ 应用程摩设计实确属讲 1 . RS 编码的代搬知识 数据的多项式表示, 可以把二进制数表示为一个 多项式. 例如 , 二进制撤 11 1 10010", 可以表示为以下多项式: g(x) = asx5 + 向X4 = Ixs + Jx4 + O+x033+X3O+x2a+zxIzx+l +OlOXx1o+ G命军。 = X5 + X4 +XI ( 1 1-48) 式 ( 1 1-48) ι11 x'代点t挂 j 制的码权, 前面的系敬 。t 代表码值。 多项式中系数不为霉 的战高次项的码权扣数称为多项式的次数. 多项式运算的域自 在 RS 编码中 , 所有的运rl �'li�在伽罗华域r l 1ill行的, 有关伽罗华 的详细介绍请读者参与相关文献资料 , 这里只f乍简单介细. 伽罗华榻的符号z 假设有伽 罗华域 CF(2勺 , 则此伽 罗华域有 n ( n = 2m ) 个称号分 别 为 : 0,ao,。1.azy--。"-2 , 并 且伽罗华域中的每个符号部可以用 。。,。1,a2,…,a'"→ 的和来表 示 , 其中 。n-I = 1 . 伽罗华域的问 则运算规则以 GF( 24 )为例进行讲解. 加法, 作榄 2 }Jr�法, 简单地说就是不进位, 不{:H恒, 只对当前位做异或运算。 例如] : a3 + a5 = 0 1 1 0 + 1 0 1 0 = 1 100 = a6 减法E 减法 与 加法规则相 同 . 乘法z 指数相加的和] 1王 1 5 取模. 例如: all a6 * = a (6+II)n时15_ α2 除法z 指数相减的是与 1 5 取模 . 例如: a9 a� / = a(4-9)回回15 = alO 表 1 1-1 L 纠出 f 部 分 RS 编码的本原多项式 P(均· m 2 3 4 5 6 7 8 褒 11-11 部分本原多项式 I + X + X2 l + X + X3 l+X+X. I + X2 + X5 *Jl多项式P(X) I + X + X‘ I + X ‘ + X7 1 + X 2 + X3 + x. + X 8 以 m=6 为 例, CF(26 ) 的 全部符号的求法如表 1 1-12 所示。 1466/. 第 11 意 戴字通铺 符号 。 a。 。1 02 0' 0' 。s 蛊‘ 。1 o� o' 。" 。" 。归 。" 0'‘ r。" 0'6 表 11-12 伽罗华域符号的求法 币f"t..示 。 -二姐.... 侃)()()()() "沁ωl ' o 阴阳10 ' 0 侃)()I∞ 。1 ∞1以)() ' 0 。, 。 . .. 1 +0 . 0 1以lOO l创沟∞ 以沁011 0(1 +0)草0+02 03 =O(o+ol)=a' +0) 0 0' =0(0' +0))= 0' + ' 。10 =0(0' +0') = 0' +0' 0(0' 。11 = +0')事。'+0令l 0" = 0(0' +0+1)=0' + 1 。1) = 0(0' +1)=σ'字。 。.. =O(OJ +0)=0' +0' 01J"o(Q'+01)事。r'+,i F � :Uy�L l �� , 。ω = α(æ +0')=0' +lI+1 • 侃)()IIO ωII∞ 0 1 1 似¥0 110以刘 1侃)() I I 以)()IOI ω1010 0101∞ 1 0 1创泊 、 01ω11 」 十边倒'监 。 2 4 B 16 32 3 6 12 24 48 35 5 10 20 40 19 山 F篇幅有限, 点 1 1-12 只列山 了 部分的符 号, 其余求法类似. GF(26)的生成多项式为式 ( 1 1 -49 ): g(x) = ( x - a )( x - a2)(x - a3 )...(x - aI8 ) ( 1 1-49) j展开式 ( 1 1 -49), 合并间类项, 并运用伽罗华四则运算化简得到式 ( 1 1 -50): = g(x) x'1o8 +, o_2�'2.."("1.7 +, o_Sn9.."J( ".6 +, O_UOx..I' JS +, 0_3'"x..1'4� +, O_U6'1x..'1 '3'' +. 0_3'>08x.1".2 +, o_"21x.".1 1 + + o�6x.. '1.0 +. o_3"1x..'9 +, o_2-Sx.J.I +, o_5--9 :c..7" +, _O3'2-x..'6 +. _oI"I x..S' +, _0 -35-x_4' +. O_"5 1 x..3' o-3x-2 +, o•"48x'1 +, O_45 ( 1 1 -50) 棍据式 ( 1 1-50) 幽 出 RS 编码的电路凶 , 如国 1 1 -7 1 所 ,h l \467\ 应商疆摩设计实倒躏诩 18 � 63 45 图 11-71 RS编码的电路图 2. RS 编码的乘法器 根据伽罗华域运算规则设计乘法器. 当系数为 0 时, 乘法器的 Verilog HDL 代码如下: module mu�a O (a , c ) ; input [ 5 : 0 J a; output [ 5 : 0 ) c ; reg [ 5 : 0 J c ; always @ ( a) begin c [ 5 J <=a [ 5 ) ; c [ 4 J <=a [ 4 ) ; c [ 3 J <=a [3J ; c [ 2 1 <-a [ 2 J ; c [ l l <"a [ l J ; c [ O ] <=a ( O ) ; end endmodule 代码分析z 由于伽罗华域的加法是作异或运算, 与: 系做为 0 时 , 乘辜!Ell为; 本 身 。 当系数为 1 时, 乘法榕的 Verilog HDL 代同如下: module mula l (a , c ) ; input [ 5 : 0 ] a; 。utput ( 5 : 0) c; reg [ 5 : 0 ) c; /468h always @ (a) begin c [5 ] <-a [ 4 ] ; c [ 4 ] <=a [ 3 } ; c [ 3 ] <-a ( 2 ) ; c [ 2 ] <=a ( 1 ) ; c [ 1 1 <=a[5} ^ a [ O ] ; c [ 0 ) <=a [ 5 ) ; end endmodule 代码分析, 假设乘数为 c = c[巧x' +c[4Jx4 +c[3]x3 +c[2]x2 +c[I]x' +C[O] , 它乘以 x, 得到式 ( 1 1-51 ): c = c(月x6 + c[4]x$ + c[3]x4 + c[2]x3 + c[I]x‘ + c[O]x ( 1 1-51 ) + 化简得到式 ( 1 1c-5==2cc)[[:45]]x(1s++xc)[+3]cx[44J+xcs(2+]cx[33]+川c[+lJcx[22]x(3c[+Oc][+IJcx[25]+)xC[+Oc]X[5] ( ) 1-52) 上面代码中的 c[1]<-a[5] ^ a[O], 当系数为其他值时, 按此方法类似求得. 由于篇幅有 限. 这里不一一列出所有代码, 具体的讷参考光盘内容。 3. RS 编码的 Verilog HDL 实现 根据图 1 1-7 1 , 组合 RS 编码的乘法器, 设 计 Verilog HDL代码如下: module rscode (clk, clr, start, datava lid, x, y ) : input clk; input clr; input start; input datavalid; input l 5 : 0 } x; output [ 5 : 0 J y; reg [ 5 : 0 } y: wire [ 5 : 0 ] mu�O, mull, mu12, mu13, mu14, mu15; wire [ 5 : 0 ] mu16, mu17, mu18, mu19, mullO, mulll; wire [5 : 0 } mul12, mul13, mul14, mul 15, mul16, mul17; reg [ 5 : 0 ] rO, rl, r2, r3, r'l, r5; reg [ 5 : 9 ) r6, r7, r8, r9, rlO, rl1; �469\ reg [ 5 : 0 J r12, r13, r14, r15, r16, r17; reg [ 5 : 0 } databack; /1调用乘法器 mula_4 5 gO ( . a (databack) , .c (mulO ) ) ; mula_48 gl ( . a (databack) , . c (mull) ) ; mUla_3 g2 ( . a (databack) , . c (mu1 2 ) ) ; mula_51 g3 ( . a (databack) , . c (mu1 3 ) ) ; mula_35 g4 ( . a (databack) , . c (mu14) ) ; mula_ll g5 ( . a (databack) , . c (mu15) ) ; mula_32 g 6 ( . a (databack ) , . c (mu16) ) ; mula 59 g7 ( . a (databack ) , . c (mu17) ) ; mula_25 g 8 ( . a (databack) , . c (mu18) ) ; mula 31 g9 ( . a (databack) , . c (mu19) ) ; mula 6 glO ( . a (databack) , . c (mullO) ) i mula_21 gl1 ( . a (databack) , . c (mulll) ) ; mula_38 g12 ( . a (databack) , .c (mul12 ) ) i mula_61 g13 ( . a (databack) , . c (mul13) ) ; mula_3 g14 ( . a (databack) , .c (mul14) ) ; mu�a_O g15 ( . a (databack) , .c (mul15 ) ) i mula 59 g1 6 ( . a (databack) , .c (mul1 6 ) ) ; mula_22 g17 ( . a (databack) , .c (mu1l7) ) i always @ (posedge clk) begin lf (clr -=[ l ' bO) begin rO <= 6 ' dOi rl <= 6 ' dO i r2 <= 6 'dOi r3 <- 6 ' dO; r4 <= 6 ' dOi r5 <- 6 ' dOi r6 <= 6 ' dOi r7 <- 6 'dOi r8 <- 6 ' dO; r9 <- 6 ' dO i rlO <- 6 ' dOi rl1 <- 6 ' dO; r12 <- 6'dOi r13 <- 6 ' dOi r14 <- 6 ' dO i /470� 第 11 J脏 r15 <- 6 ' dO i r16 <= 6 ' dO i r17 <- 6 ' dO ; end else if (start -- l 'bl) begin rO <= mulOi rl <- rO ^ mulli r2 <= rl ^ mu12i r3 <- r2 ^ mull; r4 <= r3 ^ mull; r5 <- r4 ^ mull; r6 <- r5 ^ mull; r7 <.. r6 ^ mulll r8 <- r7 ^ mull; • r9 <- r8 ^ mulli rlO <- r9 ^ mull; rll <- rlO ^ mull; r12 <- rll ^ mull; r13 <- r12 ^ mull; r14 <- r13 ^ mull; r15 <- r14 ^ mull; r16 <- r15 ^ mull; r17 <- r16 ^ mull; end end /1作异成运算 always @ (datavalid or X or r17) begi.n if (datavalid -- l ' bl) begin databack <= X ^ r17; end else begin databack <- 6 ' dO; end end always @ ( datavalid or X or r17) begin 471 \ 产i画画毗 翩翩酣实棚讲 i f ( datavalid == l ' bl) begin 11输出数据 y <= x; end else 1/输l机检验码 begin y <= r17; end end endmodule 保存代间只,) rscode.v, 并 设 为 顶属文件, 编译工艇, 编译无误后单击 Pr,∞essing → Generate Functiooal Simulation Netlist, 产牛.功能仿真网表. 新建波形仿真文件, 加入输入 输出信号, 设置系统时钟信号 cLk 的周期为 1 0ns, 单T旨输入信号 clr, 设置为前 20ns 为低 有效, 后面的为自无效; 1'ß击输入信号 start, 设置为前 2005 低无效 , 后 面 的 为商干于效 : 单 出·输入信号 datavalid, 设究为 20�470ns 为 高奋效 , 其他时间 为 低无数 : 单击输入倍号 且, 设置从 2005 开始, 每隔 10ns 加 " 1 ". f呆仔被形文件为 rscode.vwf, 单击 息 技钮进行 RS 编 码器的 波形仿真, 被形 仿真报告如 困 1 1 -72 所示。 1.. I " 0 cu dr .t,U'‘ 4-.\._..1叫 园, 因, 阳 1 1-72 RS 揣间糠的波形仿冉银行 被形仿真报告说明z 在信号 datava1id 为高时, 输出信号 y 就 是输入数据 X: 当信号 datavalid 为低时, 输出 衍'号 y 是 18 个校验码。 1 1 .9.2 RS(204, 1 88)译码器的设计 RS 码在通信系统、 数字也视和 计算机存储系统中内周报广泛。 例 如 , DVB ( 数字电 视 〉 标准中{亩地编/解码来阳 RS(204, 1 88); ATM 网络中使用 RS( 128, 124)作为前lhj纠惜编 妈 ( Forward Error Correcting, FEC). 4:节将以 DVB标准中也义的 RS(204, 188)译码器为例, 详细介绍棋子改进 的 BM 选代 算法、 pipeline 纣 构 的 i辛码的所有技术细 节。 考虑到译fi马错的可扩展性、 可维护性, 实例 '11)革可能地使川参数化 、 棋块化的设计. i卖 行可在实例代间基础上作很小的改动 , 就能实 现不I.;J 需 要 的 RS 译码器. /472/ 第 11:1 撞 戴字通铺 1. 应用背景 在数字通信、 数字电视中, 信道编码的使用提高了 数据传输的质量. 且然增加了传输 1if 宽 , 但 信 道 编 码减 小 了 数 据 传 输 山 现 误 间 的 概 率 , 同 时 也 减 小 了 所 日1 茧 的 信 噪 比 Csigoal-to-noise rate)。 在太 多数应用中 , 将 RS 码与卷积间级联使用进行纠错. 在 自 信源至接收的过程中, 数字电视信号 的编码包括倍源编码 、 信道编码及加密. 信 道编码又称做前向纠惜编码, 其 目 的是提高信息传送或传输的可程性, 当传输左铺在一定 范围内, 接收机都能将误码纠正过来. 必须指出, 信道编码并非指信号给 1:变频发送 出去 后 , 在传输信道中 〈 甸线、 J!.星或 地 刷 〉 进行编码, 而是指给过编码后便匹配信道传输和减少是错. �I此, 自 信濒编码后的 所有编码包括能盘随机化扰码、 卷F、、 交织、 Reed-Solomon 编间等都可划为信坦编码. 典 型的敢于电棍信道编码如剧 1 1-73 所示. �,也慢 ff�1数 MPEG-2 SlJll匹配唁 外,,� .u.; 怕 H 币流 自Ui扩i: lIt 8画Eq !lJlJ 因 1 1-73 数字电视品且 i 偏间的一般结构棉田 在回 1 1-73 中 , 外编码 多 为 具有很强突发纠错能力的 RS(n, k, 1)编码• n 为 〈 缩 短 〉 码 长• k 为信息位• I 为 能纠正误码的最大的码位. 且 RS 外码编码的特点是纠正与本组有关 的民码, 尤其对纠正哭泣性的 民码最仨效. 迦常, n、 k、 I 分另IJ;I,; 204、 1 88 和 8。 如 阁 1 1-74 所示为 "EN 300 429" 于1·钱数字电视 CDVB-C) 标准规定的1>2:送端 (Cab1e H臼岳阳d) 在 阁 , 其中包括了数据帧结构 ( Framing struc阳re ) 、 信道编码及调制. 可以看 到, 使 用 了 RS(204, 188)编码. 间 可4 J 广门 翩 钟 m jl . 8 RS �fiT! s -& :ø� 8 和钊l 忧 (204. )188 交 �! 1=12 的 节、 flJ r-r �� 理提 M 4者' m m J-L QA.\.i U,�n,IJ 分 细画 4 I&. Q IF 物理 的 形 t主u t L '…2 ---------…· II.J例,11H).如促成 倒 1 1-74 DVB.C tìtr端推回 其 巾 , RS(204, 188)码定义如下. • 码'EJix多项式: g(x) =(x+λOXx+λt)(x + A.2)…(x + λl勺 , 加 02HEX • JJJIG尘成多项式: p(x) =x8 +x4 +x3 + x2 + 1 \473\ 应用霍摩设计实倒搞调 2. 理论算法 RS 译码主要有时域译码和额域译码, 时域译码通常采用 BM 选代算法或者欧式算法 ( Euclid's Algorithm). 本文主要介绍 BM 迭代算法原理及以此n法为基础的 RS 译码辘的 FPGA 实现. RS 译码可分为 4 步 : 第一步L由接收到的码纽计算伴随式: 第二步求解关键方 程: 第三步计算出错误图样: 最 后 由 错误圈样和接收码组计算出可能发迭的码字 . 国 川 -75 给 出 了 RS 埠码辘的一般步骤框图. R(x沪C(x)+E(x) 伴随式 s(x) 计算 A (.r) 串串关怕也 方程 A(X) S(x) Chein 4峰说位'H. 搜黛 qx) 俯i� Fomey tlt讼n但 1!l汇 JW. FIFO级行 困 1 1-7S RS 译罔缆的一股步 骤恬i到 RS译码的关键在丁·求解错误位置多项式 A (x). 1966 年伯利钦哲� ( Berlekamp) 提 出 了 可以山伴随式计 算错误位置多项式的应代译码算法, 这极大地加快f求解错误位白:多项式 的 速 度 , 该方怯简单且劫于实现,· 从而从工程上解 决 r RS 译 峭 的 问 题 : 1969 年梅同 ( M囚sey) 指 出 了 该n法与序列的最短线性移位寄存器综合之 间 的 关 系 , 并进行了简化, 肉此, 此详码算法就称为 BM 迭代译码算法. ( 1 ) Reed-Solomon 码基本概念 RS 循环倒是广泛阳 子数字电视传输系统中的前向纠错阔的重�组成, 是一个符 号取 白有限域 GF(q), 氏度为 n . 信息 位 长 为 k 的(n, k)线性分ffi.码 . Jt中 的任何{崎矢 C= (C,川,…, CI, Co). 可用阴字多项式表示为: C(x) = Cn-1X俨I + C俨2Xn-z + … +CIX I + Co ( 1 1-53 ) 如果 F 是包含阶数 为 n 的元素α的有限域. ,. 是 1 flJ n 之间的|叫应的蜡数, F 域 中 的 所 行 矢'应 C = (Co. C1, " , CII_I)满足下式: 川+ -- n u ,. = J n υ ( 1 L -54) TJ同臼 C α 仇 那么, 这样的矢-r;t集就称做在街限域 F 1:的长度为 n 川余为 r á'.; Reed-Solomon 向­ l�tll . bo 为任意鞍数, 通常取 t . 但在 DVB 标准巾 bo=O.矢ftt c称做该码的问字( codeword )0 RS 码是特殊的 BCH 码, 其码字 C 和生成多项式g(x)均在 1..;1 . 个有限域内 . 对 r 本源 BCH 屿, 分m 氏l主 n = q'"- 1 . 其'EJ且多项式g(x)的棍在扩 j提域 GF(qm)内. BCH 码的 原:X) nT表示为: = g(x) LCM[m缸�O(功, 111(1忡I (x), … , ma�'" , (x)] ( 1 1 -55 ) /474/ 第 11 :1筐 '自 其 中 . LCM 表示多项式的最小公倍敬 。 mal表示 GF(q"')域中 的本原元d在 GF(q)中的 最小多项式 ( minimal polynomial ) . 8 称做码设计间距 (design distance), 且 3三二8�三n. 如 果取 m = 1 . 则 n = q - l , 此时就得到 了 标准的 RS 码 . 因 为最小 多项式和1本原元均在 GF(q) 中 , 贝IJ 最 小 多项式的次数 ( degr臼s ) 为 1 , 形式为(x- a'), 所 以 RS 码的生成多项式简化 为: g(x) = (x-α岛 Xx - α句刊) … (x -α部+ö-2) ( 1 1 -56) 对r RS 码, n - k = δ-1 . 因 为 是特殊的 BCH 码, 所以其最小码间距 dmin"?;8. 又因为 · 所有的线性码的码间距只能小于等于 n - k + I , 所以 dmln = n - k + 1 ( J1-57) 为 f 便于理解 RS 码的i学码原理, 由式 ( 1 1 -54) 的定义可得出下面重要性质. 设 RS 码的码矢为 C = (Cn-I," -. C1• Co), 其对l恒的码字多项武 c(x)如式 ( 门-53) 所示, 贝IJ c(x)有 由本原元α为底连接的从 bo jlJ(bo +8- 2) 为辜的8- 1 个根。 ap: l C(x> x_"''= C(αðt.,.l ) = 0 . i = O. 1川归 ( 1 1 -58) 此外, 还可以从报域的角度进行分析. 有|喂域的 N 点 OFT ( 离 散傅也11t-变换 〉 定 义 为 : 1'1-1 Xt = Z xJK , i z 0, l,…, 州 ( 1 1-59) k‘。 j.t lj ' . x = (x仇XI," ', XN_I)趋来 自 GF(q)、 民!变为 N 的序列。 α是来 自 OF(q勺, 阶 数 ( order) 为 N. 即α‘ = 1 . 如 果 令 m = 1 ( 如 RS 码 ), 则 OFT变换对f恒的序列 x 和 X均属于向一个 域 GF(q). |叫理. OIT的边变换 10FT 定义J..; : -I: 1'1-1 Xk = L X.a飞 k = OJJ·- , N - l " 1...0 ( 1 1-60) 设 RS码的码宇为 C = (C,ιn-扣山. 对应的 OF凹τ 变换附jF 列 为 tt?=刊(Cιn-I 、J,Jf. ….….•U. .N-I ,之Ct 'IC0ω) . 则由式 ( 1 1-53) 和式 ( 1 1-59) 千1·: êl = L Cka'k = C(α斗 , i = 0, 1,…. 协1 ( 1 1-61 ) 山式 ( 1 1-61 ) 的定义可知. RS 州的码字的 OFT ff列从 比 如+ 1,… , bo+δ-2 忧民连续 的在l 个系数均为O. ( 2 ) RS 详间 与关槌JïÆ?: 在介绍 RS 详码的关键Ji程之 前, 先给 山 下剧的 定 义且应用。 对 r-给定-个矢 耳t v, 其支持集 (support set) 1 定 义 为 : J = {i:O� i运17- 1 1 1. V, *O} ( J 1-62) \475\ 应用雹摩谢慎倒篇讲 定义矢盘 V 的位置多项式 ( locator polynomial) 为 : σv(x) = IT(I -a'x) ieJ 定义矢蓝 V 的 第 i 个点的位置多项式 ( punctured locator polynomial) 为: σ沪(x) =σv(x)/( l - aÎx) = IT (1 - aJx) ( 1 1-63) ( 1 1 -64) 最后, 定义矢最 Y 的计算多项式 (evaluator polynomial) 为: 价(x)= L阿σ俨(x) ( 1 1-65) lel 定理 11.1 (关键方根〉 对于给定矢盘 V, V 对应的 DFT 变换多项式,(x) = '。 + #IX 创 I +…+ 此,IXPl , 收)及 ωI{x), 贝J下式成立: σv(x)萨(x) = ωy(xXI -x") ( 1 1 -66) 证明: 由 DFT 的定义有: ,(x) = 汇 (汇 κaý )xJ = 汇 阿 三x,αH j={) εi I jeJ J={) σ 又肉为对于所有的 i e 1 • 有 σv(x) = 伊(xXI - α坷 , 所以 ( 1 1-67) 仰 σ,, (x)后(x) = 立的σ沪(x)(I -a'x)LxJa!l = Lκσ沪(xXI -x") = (xXl - x" ) ,eJ ):0 1E1 肉此, 定理 1 1 . 1 得证. 下面的定到 1 1 . 1 的推 论 l 给 出 了 如 何由 o y(x)和 ωI{x). 恢抖出原来的 Y值, 其巾 σj, (x) 为 多项式 。叫:x)的导数. 推论 1 对每个 i巳1. 下式成立: VJ == -a'l -ω-y---'(α1'---1一) σHα叫) ( 1 1-68) 证明: 对关键方程式 ( 1 1-66) 两边取微分, 则有: σv(x)"(x)+ σj, (x)V(x) =ω,, (x)(-nx"-l) +ωv (xXI -x") 如 果令 x α I 并且 iε1, 则式 ( 1 1-69) 可写成: σHα-/)V(α-/) = -nαIω,, (α -/ ) 又例为 萨(α-' ) = n 只 · 笔此, 推论得证. ( 1 1-69) ( 1 1-70) 也理 川 . 1 的推论 i 表 明 , 使用式 ( 1 1-68), 矢 Q: V 的 时城电标可以山 σI{x)和 ωv(x)恢 复出来. 下面开始时论 RS 译码的具体问题.假设 c = (Co, CI...., C".I)为纠钳能力为 t 的 RS巾, 均 码的码字. 码字 C 发送后经过有噪声信埠 , 接收端收到的!码字 为 R = (岛, RI..... Rn-I)。 设传输过程'1' 加入的错误国样 ( error pattem) 矢量为 E = (Eo, EI,…• E,,_I) = R - C.. 忠义f� /476� . 第 1 1 意 数字通馆与 随武 ( syndrome) 句 为 : L SJ n-I = Rlal(如J-1), j = l ,2,…,2t '-0 因 为 R = C +E. 并且 C 是码字, 所以 "…l Sj = ZEdM'", j = l, 2, …, 2t ( 1 1 -7 1 ) ( 1 1-72) 由此可知, 伴随式 岛 的值仅取决于毕英国样 E, 而与传输的码字无关 。 由前面的 D阿 定 义 , 可 以看到 岛 其 实是错误图样 E 的 DFT 变换的第 (bo- I ) 个分量. 下面定义 " twisted eηor pa阳m" V 为 : V = (Eo.EIα饨,E2α2衍 ,…, En-Iα(11-1)岛 ) ( 1 1 -73 ) 设 V 的 DFT 变换为 , ' 则由前面的相关知识有 (品,品, … .S2, ) = (儿, 民 … , 比川 ) . 将 矢盘 V代入式 ( ) 1 -66), 因为仅知道归功 的 2t 个系 数 , 即 儿 , 民. … ,,2川 , 所 以关键方程 可写 为 : σ(x)萨(x) =ω(x) ( m创 沪') ( 1 1-74) t 式 ( 1 1-74)就是熟知的 BCH/RS 关键方程。其中, o(x)称做错 误位置多项式(eaor-1oca or po1ynomia1 ), ω(x)称做错误计算多项式 (eao问valuator polynomja1)。 设伴随式多项式 S(x) 为: S(x) = SI + S2X + SjX2 + … +S2,X2H 且由前面可知• S(x) = 萨(x) mod x2, . 贝IJ式 ( 1 1-74) 的关键方程可写作: σ(x)S(x) =ω(x) (mod x2, ) ( 1 1-75) ( 1 l-76) 如 果 通过接收到的 R 求出伴随式 S, 能够解出关键方程 , 然后又解山σ (x)和J�x). 就 可以很容易地恢复错误圈样 E. 后面会介绍高效的 Chien 搜索及 Fomey 算法用于恢 复 E. 最后, 通过计算 C = R - E . 就得到了发送码字C. 下面将介绍关键方稽 的求解. • ( 3 ) BM 及其改进算法求解关键方程 1966 年伯 利 坎 普 ( Ber1ekamp ) 提 出 了 可 以 由 伴 随式计算错误位置多项式的法代详 码 算 法 , 这 极 大 地 加 快 了 求解错误位置多项式的速 度 , 该方 法 简 单 且 易 于 实 现. 从 而 从工程 t 解 决 了 RS 译 码 的 问 题 : 1969 年梅西 ( Massey) 指 山 了 该算活 与序列的最短 线性移位寄存 器综合之 间 的 关 系 , 并进行 了 简 化 , 因 此 , 此译码算法就称为 BM 选代 悖码算法。 在 VLSI 设 计 中 , RS 解 同 时 的 关 键方程求 解 比 较 复 杂 , 主 要 有 以 下三 种 方 法 : Ber1ekamp-Massey CBM) }立法、 EuclJdean rr.法、 PGZ 算法。 当错误个数 (ρ3) 值较大时, 一般认为 BM 算法 占用最少的面积和时间及相对小的 结构复如皮. 但是 , BM 挥出涉及到 有限域元隶求逆 (ÍDverse) . 这是个报复杂、 很耗时的运算。 而本文t'(.J RS(204, 188)详陶器 关键方程求解采用 了 改进的 BM 算法, 算法基i 代时无需求解奋寝| 域元素草j ( inversionJess ) 。 � 477\ 下面首先详细介绍 BM 算法. 设纠错能力为 r 的 RS(n, k)码的错误位置多项工飞为 σ(x) = 1 +σIX + … σdXd • d!Æ三t 由 式 ( 1 1 -66) 可知: σ(x)S(x) !!! 0 (mod I - x") ( 1 1-77) 闲此, 对于任意的j (O�三jζn-l ), 下式成立: d Sj = -L:σ岛-I ' j = 叫 价 1 , 2/- 1 ( 1 1-78) 其 巾 . d 为误间的个数。 式 ( 1 1-78 ) 可 以 用 四 川-76的移位寄存措描述。 --- 如|如 ---- SÞ-J S归<1-,…So 国 1 -76 移位宿在精描述的关键Jjft BM 贷:法可以得到最 小 次 数 多 项式 ( 即 最短的移位于守 得 端 ) , 用 于 确 定 错 误 位 置 多 项式. 在i rr.法逐渐增 加 移位寄再器 的 氏度 , 从 0 开 始 l'I到节� T-实际错误的个 数 . 若式 ( 门 -78 ) 不 成 立 , 则 要 么 改 变 a; 系 数 , 要 么 增 加 移 位 布 将 器 辰1直 . 例 如 , 有 差 值 (discrepancy) d" 为 : d" = S" + 艺 σIS,,-I ( 1 1-79) 如 果 4" 不 为 :莓, 则新的移位寄非器系数在上次改变阻的基础匕)JfI上当前值. 上忱的系 数战n民移位寄存榕的方向移动, 宦圭IJ与伴随式相对应. 随后 . 利1间的是值d"使得移位寄存 都 氏度改变. 新的错误位贯多项式由下式给tl\ : σ伽n肿叫+ .. "" ,, ( 1 1-80) Jtql, n - m 为移位队;数 ( l(:JJ[), dn 为新的注ffi, d",为J:一次 l<:应啤变时的Jff值. 只 有当 d,,-:#=O 1f� ft. 2L,,!Æ二n 时 , 才会引起长度的改变. 在介绍改进的 BM 算法前, 先给出完整 的 B M 11陆的流和. ( 1 ) 初始化: σ(O)(x) = 1 B(O)(x) = 1 /(0) = 0 k = 0 ( 2 ) 下面的步骤从式 〈 川-81 ) 到式 ( 1 1 -85) 循环l1i代, 1'1到 k=δ-1 .. J ùl1-) l:i(k牛1) = 亏 L、 厅U�1t)S._1 );0 ( 1 1 -8 1 ) /478/ 第 11 意 戴字通ft σ(k刊I(X) = σ{的(x) _ 6(hl)8(ItI(X)X { = � 8({k哟} {x)= [ixσ8m(的(x(x)1),6(k+I), 6("'1) 0 或者 2/(的 > k 6(k+1) :;J; 0 或者 2/(k) k = 11叭 l(k+1) A川 = 0 或者 2/(k) > k !k + 1 -/(的, 6(hl) 笋 0 或者 2/(k) 延 k ( 1 1-82) ( 1 1 83〉 ( 门-84) k =k + 1 ( 1 1-85) 其 中 , σ(d-I)(X)为错误位置多项式. 即式 ( 1 1 -76) 中的 σ(x) 0 在上面的 BM 算法中, 式 ( 1 1 -83) 求 8(x)中用 到有限棋元素求逆运算, 即[6 (It)rl 0 因为 何限域求逆 〈 除法 〉 运算 很复杂, 下面给出改进 的 BM 算法, 无需求逆. 改进的 BM 算法如下. ( 1 ) 初始化: = I1(O)(x) 1 T(O)(x) = 1 L(O) = 0 r(O) = 1 k=0 ( 2 ) 下面的步骤从式 ( 1 1-86) 歪IJ式 ( 1 1-91 ) 循环法代, 直到 k=δ-1 . A仙1) = L(" L I1�lSIt-) 1;0 = ;t(k叫1(x) y(ltll1(k) (x) - 6(k+l)r(k) (x)x {t Tt\ k� lI (" X) = f xT( A(* 气功, )(x), 6(...1) = 0 或者 2L(It) > k 6(hl与0 成者 2L(Ic) 运k ( 1 1 -86) ( 1 1-87) ( 1 1-88) - 1 �川 .1c+1 ) _ J L(x), k +1 - L(It), γ' LER 「-4lJSY Aιz、n,+ = 6(1c+1) = 0 或者 2L(It) > k � 6(1<+1) :;J; 0 或者 2Ltlt) k = 6(*+1) 0 或者 2L(k) > k :;J; 6(k+l) 0 必者 2Ltk) 运k t X' k=k+1 ( 1 1-89) ( 1 1-90) ( 1 1 -9 1 ) 其 中 . ;t(d-I)(x)为错误位贵多项式. 在: r.面改茸i 的 BM 算法巾, 整个过程没有剧到有 限域元索求边运算. 通过比较两种算法 . 可以有下面的结论: = ;t(k)(X) TIr仙σ叫x) ( 1 1-92) T(k)(X) = r(k)B(It)(x) = L(Ic) 1(") ( 1 1-93) ( 1 1-94) 特别地, ;t(d-I,(X) = 1(,σ(d-ll(X) ( 门 -95) 其 中 • k 为常故, k = 行 y忡 。 所以, 烈的(x) 和 川(均有相间的根, 并 且那能作为错 \ 479\ 应丽吨,也 AfIIJæß设it;实帽制 误位置多项式. 二者最大的区别是: cr(x) 多项式的地小次数项系数为 1 ; 而 A (x)的最小伙 数项系数可为非 0 的任意数. ( 4 ) Cbien 搜索和 Fomey 算法 在算出错误位理多项式 11 (x)后, 就可以结合关键方程求出错误图样. 结合式 ( 1 1 -95 ) 及o(x)的定义: σ,、x、EJ HM '飞 α x 则有: A(x) = KD(l -a-fx) ( 1 1-96) 其 中 , 1 {i:E1手的· 所 以 , 通过将有限域元索的倒 数 〈 即 o(x)的根〉 代入错误位置多 项式, 就可以找到错误所在的位 置 , 这就是 Chien 搜索的原理. 具体做法是: 将有限域元 素 α-tMLα'"'2} , … 1·l,1 逐次代入 A(x) . 若 A(α-1 ) 军 0 , 则接收到的第 i 个码出现误码. 在: o(x)来I S(x)均 已知的情况下, 通过式 〈 川-76) 的 BCWRS 关键方程可求出错误计算 多项式a(x)。 即 : ω(x) = σ(x)S(x) (mod x21 ) 用 A (x)瞥换叫吟, )书n (x)替换a(x), 贝IJ有下式: n(x) = A(x)S(x) (mod X21) = kω(x) ( 1 1 -97) ( 1 1 -98) 在 确 定 了 误码的位置后, 可以使用 Fomey rI-法求出该位置的错误样值o Jft交织的错误 矢 盘 V = ( Eo . EIα仇, E2α2饨 , … ,Enetα仲Ilb. ) 替换走到� 1 1 . 1 的推论 1 中 的 矢 盘 Y. 即 用 E,αb.I 代替 的 , 可 得 : V U I I I E,; ←α-(bo-I)I (t)(a-'. ) σ'(α-' ) • ( 1 1 -99) 其 中 , IE三1. 在 武 ( 1' 1 -99) 巾 , 附 为 n(.:r) = kω(x) 并 且 A'(x) = ka'(x) , 所 以 Fomey 算法也可改写 为: n(ζi E, = -a-(bu-I)f A'(α-' ) ( l l·lOO〉 最后 , 利用 C=R-E 就可得到纠正后的正确的码字 . 3. RS(204, 188)译码器建模 这 里 以具体的 DVB标准中定义的 RS(204, 188)间 为 例 , 详细讨诠其实现的 FPGANLS1 硬件模型. 在 DVB 标准1 1 ' , RS(204, 188)1冯主i二义如下: • 1i马坐成多项式: g(x) = (x+αOXx+αI ))(x + α2 ) … (x + α勺, α = 02HEX ( 1 1-101 ) /480 1.. 第 11 1在 · 域生成多项式 : p(X) =X8 +X4 + X3 + X2 + J ( 1 1- 102) 由定义可知: n=204, 严8, 8=21+1=17, b俨o. ( 1 ) 伴随式计算模块 + 2 回顾前面 sj 的 定义, 8(x) = 81 + S2:xi + S)X2 … +Sz,x 叫 。 其中 : n-I Sj = L: Rla'伽J-气 j = I,2, …, 21 /.。 对于 昂 的 计算 , 下面给出一个高效的算法一-Homer 准则, 采用嵌套的乘累加运算: 8j = (( … (Rn-Iα{加)-1) + Rn-2 )a(bo+)-I) + Rn-3)α(如今j-I) + … +RI }α(110'1-)-1) + � ( 1 1 -103) 将 n=204. bo-O代入, 则有: SI = (( … Uh03 + R202 ) + R201) + … +RI } + Ro 82 = (( ". (R203α1 + R202)α1 + 0R2 I )α1 + ..• +RI)α1 + Ro •••••• 816 = (( … (R203α15 + R202 )α15 + R201 )aIS + … +RI )aI5 + � 式 ( 1 1 -100) 的运算可以用 流水线结构硬件实现, 如图 门-77 所示为通用伴随式计算 框圈。 圈中 "0" 代表寄存器I "+" 代表有限域加法, " × " 代表有限域乘法。 初始化时, 所有寄存器置 O. 经过 204 个时钟周期, 接收完所有的 204 个符 号 后 , 就可以得到全部 16 个伴随式. d'- a'树叶 庐巾�I SI S1 Sl1 Ro.….R,萨' 因 1 1-77 涵用伴随式计算框闺 ( 2 ) 改进的 BM 算法模块 当 2t 个伴随式都求 出 以 后 , 就可以通过改进 的 BM 算法求错误位置多项式 σ〈功, 即 BM 算法中的 A (x)。 在此回顾武 〈 门-86): A叫 = L. A�)Sk-j 很显然, !l 是 l1(x) 与 8(x) 的卷积求和运算 。 为 了实现流水线处理, 可以采用 FIR 滤 披器技术来实现. 如 图 川-78 所乐为 FIR 滤波器计算 A 。 初始化时, 所有部非址是直 0, 然 后每个时钟周期, 依次将 51, Sa---,岛,移入移位寄有器。 滤波 器系数 11 1 也在每个时钟声j期 更新一次。 �481 \ 应用疆摩由愤偶制 缸ζ主主l J与 111 Ib A A 回 1 1-78 F1R滤法器计算A 此外, 简要提一下, 在改进的 BM 算法中 , 式 ( 1 1-87) 求A(功。 A(k+l)(X) = r(k)A(k)(X) - !l(k刊)T(k)(X)X 因 为A(x)是多项式, 自1]求A(x)的多项式系数. 所 以 , 式 0 1 -87) 分解成 仲 l 个运算。 HUF "V �k+l) =r(k)�k) 4叫 = r<勺ikl + A{川TJK} ( 1 1 -104) •••••• A�k+I) = r(klA�k) + !l(轩"mJ 从式 ( 1 1-104) 可 以 珩 出 , 在循环地代过程中A(x)的系数除Ao ( 仅 1 个果法器) 外, 各荷要 2 个乘法器和] 1 个加法器 〈除Ao外〉 实现. ( 3 ) Chieo 搜索模块 由 式 ( 1 1-96 ) 可 知 • A(x)可用来搜索错误忧贺, 方法是: 依次将α-tn·I},α巾,2}, … ,α-1, l 代入A(x). 若A(d/) = O. 则在该位理出现误码. 每效的实现框阁如固 1 1-79 所习2. 1。 f告说 指lf' 111 ql 1\, 1 '" 剧 1 1-79 Chien烛'必拟块很闯 /482� 第111 院 (4) Fomey 算挫模块 在求出等价的错误位置多项式A(x)后, 可以利用式 ( 1 1 -98) 等价的错误计算多项式 O(X), 即 : = O(X) A(x)S(x) (mod x2,) 因为O(x)的结果为 mod:i', 所以O(x)的最高次数为 2(- 1 . 因此, O(x)可表示为: 。(x) =Oo +0,X+02X2 + … + 02t-1X2叫 ( 1 )-105) 式 ( 1 1-10日 中 , O(x)的 系数可分别表示为: 。o = AoS, • 0, = AoS2 + A,S, 02 = AoS) + I1,S2 + 112S, ( 1 1-106) …. . . O2,-. = AoS2, + I1,S2川 +… + 11,3, 从式 ( 1 1-106) 可以看出, 两个多项式的相乘其实质是两个多项式对应的系数卷积求 和. 因此, 式 ( 1 1- 106) 运算也可采用 FlR 滤波器技术来实现, 对l恒的原理框国 如图 川-80 所示. 初始化时, 所有寄存器宜 0。 然后在每个时钟周期, 伴随式从 品,…品,依次移入移 位寄存端, 生成的。依次经过移位寄存器。 最终, 21 个0, 移位寄非器的内容从1r.到右依次 为: Q2川,…,0.. 00. Sb.... .s. 因 1 1-80 FlR 实现的n (x)计算很自 下面介绍错误位置多项式l1(x)的 导数A'(x)计算. 设A(x)表示如下: + l1(x) = Ao + 111x 112X2 +… + I1,x' 则按照导数的定义有: 11'(x) = 11, + 2112X + 3113X2 + … + tl1/x,-1 ( 1 1-107) 在通常情况下, 用到的 RS 码都是基r. GF(2m)域的. 根据有限域的知识, 域 GF(pm) 的特征 (cbaracteristic) 为 p, I1P域·tl的任一元素祟加 p l!Ã的和为 00 故对于式 ( 1 1- 107 ) 钉, 2;1r0, 311)=11), 依此类推, 式 ( 11-107) 可 以简化为: 11'(x) = 11. + I1)X2 + … +rnAmXFl 其 巾 , m 为主主t 的届大奇数。 若 以 RS(204, 188)码为例, 其 t=8, 则奋: = 11'(x) 11. + A)x2 +I1sx4 + 117x6 ( L 1 -108) \ 483\ . ...鹰;也宁实倒搞调 硬件结构框因如阁 11-81 所示。 、 。 。 。 。 回 1 1-81 /'=8时的A'(x)硬件结构框阁 n旷) . 再次回顾武 ( 1 1-100) 的 Fomey 算法如下: E,- = 一α响 -1); /1'(α-一' ) . · 大多数的 RS 码 b俨 1 , 所以α的事项为 1 . 但足, 在 DVB 标准中• bo=O. 所以式。 1-100) 可以写成: EI1 = --αai n(卢) /1'(α-')' . · ( 1 1-109) 式 ( 1 1-109) 的硬件实现框图 如 图 1 1-82 所示. • • / 484 � 11. 11) A. 。 』直收 Wi' 忧fi'l'。ih' |刽 1 1-82 Fomey 算法及误码枝在锁件实现枢回 '再 11 章 戴字通铺 在图 1 1 -82 中 , "Pow" 棋块表示生成根d 的罪次i, "Exp" 表示查表求d 的幕, " Inv" 用查找表求A'(a可的逆. 4. 程序说明 本部分将给出 RS(204, 1 88)译码器的 Verilog HDL 程序代码, 其巾 RS码的生成多项式 g(x)为: g(x)= (x+αO)(x+αI ))(X +α2 )…(x+αIS ), α = 02HEX 该程序代码已经仿真 、 验证, 能够纠正不大于 8 个的误码, 完全实现流水线结构, 伴 随式计算、 关键方程求解、 Fomey 算法、 Chien 搜索等模块并行工作. 在经过 243 个字节 的固有延时后, 每个时钟用期都能连续输出经校正的码字. 同时, 与前端反后续电路的接 口简单, 无需额外的握手控制信号. 考虑到文章篇幅, 此处仅给出几个关键模块的代码, 在随书光盘中有完整的程j引巳码, 请读者参阅. 下面首先给出伴随式计算模块程序, 如下所示. module SCalculate (clk, lnlt, 5C done , r, S out) ; parameter t - 8, Ilt-纠错能力 1nput N .. 2 0 4 , 8 ; m .. clk, init; IIN-RS 码快I.!t. IIm-GF (2m) 扩展域 input (m-l : 0 ] r; outpu t ( m - l : 0 ] output s_out; sc done; /1伴就缸til"第:iêl�倍 号 reg (m-圣 : 0 ] s(t*2 : 1 ] , s_latched[t*2 : 1 ] ; wire [m-l : 0 ] r_a l t*2-1 : 0 ] ; integer counter; always @ (posedge clk)begin: SC_BLOCK integer j ; if ( ( init) 1 1 (counter=嚣N) ) begin for (j=l; j<=t*2; j-j+l) //锁乎f t ..帧数据的ft础武 . 开始新的计算 5 latched [ j ] <- 5 [ j ] ; for ( j - l ; j<=t*2; j-j+l) s [ j ] <= r; counter <.. 1; end else if (counter< N-l) begin for(j由1; j<-t*2; j-j+l) 5 ( j ) <- r ^ r_a (j -l ) ; 队485\ • counter <- counter + 1 ; end end μ 下面是有限域的常数乘法器的例化 * / f f const mul r x aO ( .din ( s [ 1 J ) , .dout (r a [ O J ) ) ; //a^O ff const mu1 r x a1 ( .din (s [2J ) , .dout ( r a [ 1 ] ) ) ; //a^1 f f const mul z x-a2 { . din {s i 3 1 } , .dout ( r a [2 J ) ) ; //a^2 ff const mu1 r x a 3 ( .di.n ( s [ 4 J ) , .dout ( r a [3J ) ) ; // a^3 ff_const_mu1 r_x_a4 ( . din (s ( 5 J ) , .dout (r_a ( 4 J ) ) ; // a^4 fE const mul E X a5 { .din { S [ 6 ] ) , .dout{r-a [ 5 1 ) } J // a^5 ff_const_mu1 r_x_a6 ( . din ( s [ 7 J ) , .dout(r_a [ 6 J ) ) ; // a^6 ff_const_mu1 r_x_a7 ( . din(s [ B ) ) , . dout(r_a [7 J ) ) ; // a"7 ff_const_mu1 r_x_aB ( . din ( s ( 9 ) ) , . dout (r_a [ 8 ] ) ) ; // a^8 ff_const_mu1 r_x_a9 ( . din (s [ 1 0 ) ) , .dout (r_a [9 ] ) ) ; / / a^9 ff const mul r x a10 ( .din ( s [ 1 1 ) ) , .dout (r a [ 10] ) ) ; / / a"10 ff const mu1 r x a11 ( .din(s [ 1 2 ) ) , .dout (r a [ 11 ] ) ) ; // a^ll ff const tnul z x-a 1 2 { .din { S [ 1 3 1 } , -d。ut ( Z-a [ 12 ] ) } J // a^12 ff_const_mu1 r_x_a13 ( . din(s ( 1 4 ) ) , .dout(r_a [ 1 3 ] ) ) ; // a"13 ff const mul r x a14 ( .din ( s [ 15 ] ) , .dout (r a [ 1 4 ] ) ) ; // a^14 ff_const_mul r_x_a 1S ( .din (s ( 1 6 ) ) , .dout (r_a [ 1 5 ) ) ) ; // a"15 defparam r_x_aO . CONST - 15'h4405, r_x_a1 . CONST - 1 S ' h6202, r x a2 . CONST - 1 S ' h7101, r x a3.CONST - 1 5 ' h3B80, r x a 4 . CONST = 15'hlC40, r x a S . CONST - 1 S ' hOE20, r x a6.CONST � 1 5 ' h4710, r x a 7 . CONST - 1 5 ' h2388, r x a8.CONST = 1 5 ' h11C4, r x a 9 . CONST - 1 S ' h48E2, r x a l 0 . CONST = 1 5 ' h 2 4 7 1 , r x a11 . CONST = 1 S ' h5238, r x a12 .CONST = l S ' h691C, r x a 1 3 . CONST - l S ' h748E, r x a 1 4 . CONST = 1 S ' h3A47, r x a15 . CONST = l S ' hlD23; /* 输出 sc done 销号, 指示后续电路边t行新的计算 食 / req sc-doneJ integer shift_count; always @ (posedge cLk) begìn if (counter == N ) begin sc done <= 1 ; 1 ; shift count <= end else begin sc done <= 0; 晶 晶 i f ( ( Otemp then + temp = temp B; C = C+li Else c 就是数A 除以数 B 的商 Endif 以上伪代码的意思是数 A 有多少个数 B. 那么数 A 除 以数 B 的商就是多少. 新建一个工程 mydiv 来验证以上算法, 新建一个 Verilog HDL 文件, 代码如下: module mydiv (clkt dataat databt startt datac ) i input clki input [ 7 : 0 ] dataai input [ 7 : 0 ] databi input start; 11被除戴 11除数 11 开始新的运rl output [ 7 : 0 ] datac; 11商 reg ( 7 : 0 ] dataci reg [ 7 : 0 ] cbufi reg [ 7 : 0 ] temp; always @ (posedge clk) begin i f ( l ' bl - start) 11重新W. temp 和 cbuf 为 o begin temp <- 8 ' dOi cbuf <= 8 ' d O ; end else if (dataa > temp) begio I ltemp 作-次�)JU. cbuf h11 1 temp <= temp + datab; 8'hOli cbuf <= cbuf + end eLse begin 队501\ 反幅幅兑 脯鹏出+实删 datac <= cbuf; end end endmodule 保 存 文 件 为 mydiv.v . 编 译 整 个 工 程 , 编 译 无 误 后 单 击 Processing - Generate Functional Simulation Netlist. 产生功能仿真间表. 新建波形仿真文件, 加入输入输出 信 号 , 设置时钟伯号 c1k 的周期为 10ns: 被除数信号 da阳 为 200: 除数信号 datab 为 20: 运算开 始信号 start 从 1 0005 到 1 200s 为 高 , 其他时间为低. 保存波彤文件为 mydiv.vwf. 单击 总 |按 钮进行除法运算披形仿 真 , 波形仿真报告如 国 L2-1 所示。 .... clk - 'ι一刷 E国 da\.. 国 d.\ob lïI d.\oc It... t 80. 0 • Iω. 0 1U 2‘0. 0 " . 320 . 0 "" 创10. 0 .. 唰弛 。 .. 560 . 0 "" m 10 制 12-1 除法运拟的旅形iJi真!IH斗 被形仿真报告说明z 在信号 start 由高到低后的第 10 个时钟用期, 除法运算结束 , 结果为 10=200/20, 即除 法运算的算法正确. 对代码与被形仿真报告进行分析得知, 商值越大, 所需要的计算时间 就越快. 丁 2.2 直接�9!1J频法 12.2.1 阐门产生模块 阳门产生模块的功能是产生单位时间的闸门信号, 本小节的闸门信号时间为 Is, 为了 便 f 仿真, 选择标准时钟为 1kHz. 代码如下: module gate(clk, gateout) ; input clk; 。utput gateout; reg ( 9 : 0 ) cnt; reg gatebuf; /502/ 第 12 章 assign gateout = gatebuf; always @ (posedge clk) begin i f ( l O ' d999 =罩 cnt) begin cnt <= 1 0 ' dO ; gatebuf <= ‘gatebuf; end else begin cnt <= cnt + 1 0 ' dl; end end //产生 15 9<1 闸 门 endmodu1e 保存文件为 gate.v, 单击 Fil臼 → Create/Update → Create Symbol Files for Curtren File 命令, 为 gate.v 生成原理因棋块。 新建一个原理国文件 , 在原理圈空白处攻击 , 在 弹 出 的 S沪巾。l对话框中选择 Project → gate 模块, 在l' 击 OK 按钮远 出 Symbol 对话框 . 在原碑固 的适当位置放置 gate 模块, 并添加输 入输出棋块。 保存原理图为 cefre.bdf。 编译工程文件, 编译无误后 止在击 Proc臼Sing → Generate Functional Simulation Netljst, 产生功能仿真网表。 新建被形仿真文件, 加入输入输出信号, 为 了便于仿真观察, 单击 Edit → End Time , 在 End Time 对话框中设置 time 为 1 邸 , 如 阻 12-2 所示. 1- 圃 「丁 「 MM…向 阳帽、也 ILotl伽k pall阳、 - 3 EM阳'"翩翩阳阳帽世 t 骂a SW回 11哩m 1如Oi自dJ由、 IIZZZREac茹旬 苦I 3笃E.笃酬自却1也也.. I ·、曹 ] C.-.C.I 1 阁 12-2 设置仿具结束时间 队 503\ A丽马跑 回脑网棚刷 设置时钟信号 clk 的周期为 lms. 波形文件保存为 cefre.vwf,。 单击 巳 !披组进行闸门产 生模块的被形仿真, 波形仿真.报告如圄 12-3 所示. ; 1 | 胃、 1"01 也.l,k IV II 二l>J阳帽 18. 阳..01 '80 S恤It 因 1 2-3 闸门产'仨筷块的旅形仿tHU岱 波形仿真报告说明z 闸门信号的商 也干持按时间 为 15. 闸 门 的 可· 儿l持烛的高低电 平变化信 号 , 这样可以便 F连续测试。 12.2.2 计数模块 计数模块的功能就是被测信号在闸门信 号商行 效的条竹下进行计数, 当闸 门信号变为 低电平时, 停止计数并输山计数结 果, 为 了 使 j三后端�尽, 本实例计数采用 5 位 卡进制计 数. Verilog HDL代码如下: module cn1:(clk, gate, done, dtwo, dthree, dfour, d:five ) ; input clk; input gate; 。utput done; 。utput dtwo; 。utput dthree; output dfour; output dfive; //被割fB U 输 入 • //个位络*输出 /1 I位给*输出 118位结果输出 11 下位结果输出 11 )j优纺织输出 reg [ 3 : 0 ] done , dtwo, dthree, dfour, dfive; reg [3 : 0J ddone , ddtwo, ddthree, ddfour, ddfive; reg gatebuf; always @ (posedge clk) begin gatebuf <- gate; end always @ ( posedge clk) begin && i f ( (gatebuf -- l ' bO ) (gate a_ l ' bl ) ) /1飞为削门的口的 J.JIjí\u.mr'?'�I敬德 / 504 / '目 12 j能 begin ddone <- 4 ' dli 11这时已经有一个被测俯号的上升沿过去 ddtwo <- 4'dOi ddthree <- 4 ' dO; ddfour <= 4 ' dOi ddfive <= 4 ' dOi end else if ( (gat由uf-l 'bl) 晶晶 (gate==l 'bO) ) 11 当为俐门俯号的下降沿时输出计数结果 begi.n done <= ddone; dtwo <= ddtwO i dthree <= ddthreei dfour <= ddfouri dfive <= ddfive; end else i f ( gate == l ' bl) begin 主f (ddone =- 4 ' d9) 11 个位JlJ 9 向十位进 l begin ddone <- 4 ' dO; l f (ddtwo == 4 ' d9) 1 1十位到 9 向百位进 l begin ddtwo <- 4 ' dO; i f (ddthree -- 4 ' d9 ) 11 百位JIJ 9 向千位边 l . begin ddthree <- 4 ' dOi ,_ 4 ' if (ddfour d9) begin 11 乎位到 9 向 力.位进 1 ddfour <'" 4 ' dOi if (ddfive -- 4 'd9) 11 万优势IJ 9 已走出测最范国 begin ddfive <- Oi end else begin ddfive <- ddfive + 4 ' dl; end end else begin ddfour <= ddfour + 4 ' dl; end . 心、505\ . 一 end else begin ddthree <= ddthree + 4 ' dl ; end end else begin ddtwo <= ddtwo + 4 ' dl; end end else be9in ddone <- ddone + 4 ' dl; end end end endmodule 保持文件为 cnt.v. 单击 Fi1es → CreatelUpdate → Create Symbo1 Files for Currenl file 命令为 cntv 生成原理回校块. 打开原理圄文件 cefre.bdf. 在原理图空白处双击, 在弹出的 Symbol )(I"Ì话框中选择 Project → cnt 棋块. .ql击 OK 按钮泡出 Symbol 对话框。 在原理图 的适当位置放置cnl 模块. 并添加输入输出棋块, 连接各个模块如图 12-4 所示。 elk gilte en地 gate曲jt 刷刷 q瞌回皿 cn‘ eI< 由_[3..01 9.t8 由嗣13..01 dl阳eIe 3..01 dfour[3..01 L dli\l叫3.01 嗣削1 由'叫3..01 cIto叫3..01 01 dtllr叫3. dfour[3 01 。11118(3..01 cl民血 国 l2-4 直接测版法锁块连接阁 保 有 原 理 因 为 cefre.bdf. 编 译 工 程 文 件 , 编译 无误后1'ji市 Pr∞essing → Generate Functional SimuJation NetliSl. 产生功能仿此间表. 打开披形iJi贝文件 cefre.vwf. 加入输入 输 出 信 号 , 设置被测信号的周期分别为 10ms、 25ms 和 O.lms. 即频率为 100Hz、 40Hz 和 10kl-旬, 单击 已 按钮进行放形仿真 , 披形仿真报告分别如 囱 12-鸟、 回 1 2-6、 国 12-7 所示。 / 5 06 � • 翩而\ 第 12 章 醉频率翩 ••• 圃"0 I ClJO ,.‘….l .1.1<\ 国 4f.... liI tr.町 Ii 4lhr.. E画 缸" [j d�n. &71.四.... .. . no '" ‘� • 2. 口I� • 2. 6刷 g 阁 1 2-5 被ilH白口的朋朋为 10ms的波}�仿五'*竹 3. 355 • ..-. 圃�O I <11< ‘.ho'U‘ <11" 曰 "‘.. [jj ,,_ æ .‘2、r.. 曰 趴脚 回 4.'n. J... "‘'"0 1 ckl , .,….l 拿1It‘ 曰 "‘.. [jj .r帽 æ d'hr.. B 缸脚 曰 ."M 171 回回 .. ... • 2 013 • 2 田" ‘ 3 3国 • ‘,( 因 12-6 被测{fi '� A'�结 果 分 别 为 100Hz、 40Hz、 I OOOOHz. 怀i此fH莫测顿怯�!J.到正确驰iTE. 12.3 周期测频法 周 期测 顿怯主 要是在被理Ij信 号 的一 个问lU1 内 , 计数标准信 号的个数 N, 俨I ( , 为标准 信号的刷 刷 〉 就是被视1)信 号的周期, 1 s/(N句)就J.tfJì测信号的,顿3丰1. 阴 阳 测颇法的 说 J;1 主 亚 体现在三个方面: 标准信可·的柏确j豆, 这将 1,0左 路响 , (t 巳emp) (cntflag -- l ' bl) ) begin + temp <= temp databbuf: cbuf <- cbuf + 20'dl: finish <= 1 'bl; end else begin datac <= cbuf: finish <= l ' bO; cntflag <= l ' bO ; end end endmodule 代码分析, 运rt时间与|部的大小有关, 尚越大, ',/J耍的时钟周朋就越多。 当本队;除法运到:没有结 束时, start 信号可能再次奇效, 所以EBEE-个 finisb 信 号· 来指示运算是有结束。 除法运rr 开始条件包括: start 信 号 高效、 t次除法运算结束和除数不 为 " 0"。 仅 有 文 件 为 perioddiv.v, 单 击 Files → Create/Update → Create Symbol Files for Current File 命令, 为 perioddiv.v I仨戚惊即.固慌块. 打开原理国文件 ceperiod.bdf. 征服到 国 空 白 处双击, 在弹山的 Symbol 对话缸巾选择 Project → perioddiv 模块, I'ji击 OK 按 钮且i 吐.1 Symbol 对话框。 在原理国的适当位置放到 perioddiv 模块, 并添加输入输出棋块, 连接各个模块 如阁 1 2-9 所示. u‘且.cj19 01 .闹。a ,.由。目唱 .I� ..r OJ ω民 6叫由AI19 .,kl clkt C耐。k .., "回阳 国民 .略.目>(19 .01 ".rt intl.. 。皿ltC(睛.01 jleI'国眠-,呻 甸 '‘… 阁 12-9 用j饲测额法的各 个模tÆi主攘阳 / 5 1 0 ;' "" 第 1 2 意 如频率...*.", 保仔原理图为 ceperiod.bdf. 编译工程文件, 编译无误后单占 Processing → Generate Functional SimulatioD Netlist, 产生功能仿页.问我. 打开被形仿;tt文件 ceperiod.vwf, 1m入输 入输HI信号, 设置被洲的号的周期为 1 00μs un频率为 10kHz, I萨 市 已 .�钮进行被形仿真 , 被}�仿J'L报告 如 图 12-10所示. '… 史已.J cl.k cl.kl enlok liI C1\loul 国 p.riodolll as 5. 2� •• 7. 86‘.. 1 0 创路 .. 13. 1 07 •• 15. 自fI 12-10 )苟WJ测顿法的放形ui豆豆报:‘r 被形彷真报告说 明 z |珠让运算结束时, 频率输出信号 periodouI !W:示 10000 . 单位丛.J Hz, 与 设贺的j削例 100f.lS 相对内, 剧] 频率 iý!IJ i在准确. 12.4 等精度溃。频、法 2字和I监测频法是在此接测频法的基础 )'.改进而来的 . 州f J 信 号 为 两个步骤: 白· 先 由 标准II.HII' 产牛.一个债设1"11) 门 信 号 , 然后用被测 信 守 |司 步 预 设 flfl) I丁 信 号产 牛. 实 际 闸 门 信 号 . 标准时钟和被测信号在实际闸门内进行计敛, 假设标准时钟的 计数结果为 的. 被测信号 的il ikfJi 枭 为 州, 标准IIH中的频率为 日, 惟位为 Hz, 贝IJ 融 测 信 号的频率 Ff rlJ jffi过下式 计算得到: = Ff Fs*(Nt I Ns) 1'.;'\可转化 为 : Ft = ( Fs * Nf) 1 屿 , 即先计算乘法, 问 j,I-fr.除法。 等精良现1]频法在测 蛙蚓卒较低的信号时, 抑fJ,U 比 111卖测硕泌千j·所diit: 在ìJ!� IIω员名 比标准时钊'总i11.5时, 相应 不会提内, 但是土1 的说差在测量结果巾的 比重己非常小。 12.4.1 预设闸门模块 j筑设伽rJ f J 模块的功能丛山标准时钟计数产生一个预泣的f'I'j f ) 信 号 . Verilog HDL 代问 如j F : module pregate(clk, gateouc) ; inpuc clk; / / �小f1�u.t钟 output gat:eout; I / �I设闸门fht; reg gateout , gatebuf; \ 511 \ / v.崎 岖跚鄙酣跚跚剖 reg [ 1 9 : 0 1 cnc; 11计放怨 always @ (posedge clk) begin 11 计数Í�l越火, (1jJIi' J n-tfil)A选 民 if (cnt == 2 0 ' d1000 ) 11 begin gðcebuf <= -gacebuf; gaceout <= gatebuf; cnC <- 2 0 ' dO ; end else oegl.n + cnc <- cnc 20 ' dl ; end end endmodule {呆碍文件为 pregale.v. 单出r Fil臼 → Create/Update → Create Symbol Fil臼 for Current File 命令, 为 pregate.v 'E成原押.图模块. 新过一个原理阁文件, 在原理图空h处双市, 在 弹 山 的 Symbol 对话桩'I1 ;i1排 Projecl → pregate 帧块, 单 占 OK 技钮i且出 Symbol 对话框。 在原到剧的适当位直a放眈 pregate 模块. )1,:添加输入输出棋块. 保存原理因为 equalfre.bdf. 编评l:f�文件, 编译无误后 1在市 Proc臼sing → Generate FunClional Simulalion Netlist. 产生 功能仿真.网点. 新建被形伪ftî文付, 加入输入输出信号 , 为 了便 f-flJ 页.观察, 单市 Edit → End Time , .(1: End Time 对 i1i.ft�' 1 1 设 在 lime 为 10so 设四时钟信号 c1k 的Ml期为 100间. !!P 10kHzo 将被)�文件保在为 equalrre.vwf。 单rtr 止 战m进行ffi设闸门产生模块的波形 仿丘, 波}�仿 真恨fi? 如l 回 12-1 1 所 示• ... 335.S4� _, 671.圆百 M 1 . 001 , 1. 3‘:.i: I 1. 1... I\S clk pre草.te l划 1 2.11 f.w设闸门户 't悦快的旅形仿tHIJ. �ti. 被形仿真报告说明z flllJ f J俏 号 pregate, 侮|辄 100ms 高低电子翻转一次- 12.4.2 实际阐i、丁模块 实 际 问 f J模块的功能是川 被测信 号来HJ步顶民闸 门榄主� 产 怕 的 闸 门信巧· 来产便新的 15121 第 12 . 实际闸门信号。 驰rilog HDL代码如下: module actgate (clk, gatein, gateout) i input clki input gateini output gateouti 11被测信号 11预设闸门输入 11实际闸门输出 reg gateouti always @ (posedge clk) /1用 。 触发器进行同步 begin gateout <= gateini end endmodule 代码分析z 实际闸 门 模块实 际上就是 一个 D 触发器 , 触发器的时钟为被测信号 , 输入为预设闸门 信号, 输出为实际闷门信号。 保存文件为 actgate.v, 单击 Files → Create/Update → Create Symbol Piles for Current File 命令, 为 actgate.v 生成原理图模块. 打开原理图文件 equalfre.bdf, 在原理囱宅白处 双击, 在 弹 山 的 Symbol 对话框中选择 Project → actgate 棋块 , 单 击 OK 按钮退出 Symbol 对话框。 在原理阁的适当位置放置 actgate 棋块, 井添加输入输出模块, 连接各个模块如 i组 12-12 所示。 pin_name pregale clk clk gale阻且 pregate actgat.Ð clk gatE出ut gatein Insl1 ,nst ecgale。叫 路1 12-12 ;实际闸f j仔f 苦t 的模.tk连接阎 保存原理图为 equ创fre.bdf.。 编 J译℃属文件, 编译无误后单而 Processing → Generate Functiooal Simulation Netlist, 产生功能仿真问我. 打开波形仿真文件 equalfre.vwf. 加入输 入输山信号, 单击 巳 技tll进行实际闸门信号的波形仿真, 被形仿真报告如 图 1 2-13 所示。 队513\ 蜡孔 噩噩程'也情伊翩翩 「 1... 19茸.911 •• 时一 accateout 阁 12-13 实际削f Hrl 口 的以�仿必拟� 被形仿真报告说明z 实 际 闷 门 信 号 己经被同步到被测信号的上升沿, 如 国 12-L3 I们 的游标所习2. 1 2 .4.3 计数模块 计数模块是在实际闷 f H.i号有效时, 标准时钟与被测信 号11iJ时进行计数, 在 闸 门 的 号 结束时输出计数结果o Verilog HDL 代码如 下: module cnt(clk, gate, cntoUt ) ; PUE MPUE Mω vt­eq争· ,、 -ny nu EPU l-KJ aEe., cnt。 u re 同qHd4q-f nwd 萨'』 ze , ., l -- ae n' huuUJai cn E '· c n ,." 。 u always @ (posedge clk) begin gatebuÍ <= gate; end always @ (posedge clk) begin 晶 晶 i f ( (gate -� l ' bl ) (gatebuf •• l ' bO ) ) begin cnl <= 20 ' dl ; end 晶晶 else i f ( (gate m� l ' bO) (gatebuf == l ' bl ) ) begin cntout: <= cnt; end else i f ( gatebuf == l ' bl) begin /514/ 第 叫 戴字蜘测量设计棚 \ cnt <- cnt + 2 0 ' d l ; end end endmodule 代码分析$ {f实际闸门信号的上升沿, 置计数,;},曾为 " 1 ,. 开始计敛, 在实际闸门信号的 F降沿输 出计数结果. 保梓文件为 cnt.v, 单击 Fi1es - Cr<ωtelUpdate → Create Symbo1 Fi1es for Current Fi1e 命令, 为 cnt.v 生成原到1阳模块。 打开原理阁文件 equalfre.bdf, 在跟到1图空 白 处 攻 击 , 在 弹出的 Symbo1 对话据中边择 Projecl - cnt 棋块, 单击 OK 拉宫ll且 i 山 Symbo1 对话框. 在 原理阳的远当位置放组 cnt 模块, 并添加输入输出模块 , 连接各个模块如国 12-14所示. CIOlC:'吨,. "1 ‘' pr�'. Z帽 阳‘'比..厅 "'1"1 "" eu. cntOU1I'O 01 911. ørag;嗣@ CIk @翩翩 CJI< h 酬" 恤 '‘... ""'帆' 响.。 -, ..‘. acg3"ωa ‘,. .,‘ C咱倒叫'8 呵 g:ate inst'" 01 〈 tlk目叫.9 EJII!.E 国 12-14 �I放模块连接阅 [到{!原理因为 equalfre.bdf.。 编 i学工桂文件, 编译无i具j二吧Lt:;. Procωsing - Generate Funcliona.l Simulation Netlist, 产生功能Vit�网点. 打开放*1Jj点文件 equalfre.vwf, hll入输 入输 tli b-i 号 , 单司T � 按钉l:进行计数模块的波JfHJj真, 被j�fJjt(.报告如国 12-15 所示. 11.. 167 712 .J 33s 544 .. S03 3 16 • • 671 0妇1 .. 8串3 串串1 •• 1.( I ‘;'0 cl.k pr.,.‘· clkl .cpl.oul æ clkcn‘ 回 cl.k龟四、 因 12-15 if �快快的谈形伤AJli ;., \515\ • 应黯瞿摩龄惯例制 被形仿真报告说明z 输出信号 clkcnt 为标准信号在实际闸门的计数结果, 输出信号 clktcnt 为被测信号在实 际闸门的计数结果. 1 2.4.4 频率计算模块 = 频率计算模块的功能是根据公式: Fr (Fs . Nr)1 Ns 来进行建模设计. 式中 , 日 是被 测信号的频率• Fs 是标准时钟信号的频率, Nr 是被测信号在实际闸门的计数结果, 的 是 标准时钟倍号在实际闸门的计数结果o Verilog HDL代码如下: module frediv (clk, datat , datas, freout ) i input clki input [ 1 9 : 0 ] datati input [ 1 9 : 0 ] datasi 。utput [ 1 9 : 0 ] freout; reg ( 1 9 : 0 ] datam, freout, databbuf i reg [ 1 9 : 0 ] cbufi reg [ 1 9 : 0 ] temp; reg finish, cntf1agi always @ (posedge c1k) begi n && ! .. & if ( ( finish '" l ' bO ) (datas 20 ' dO ) 矗 (datat begin datam <- 2 0 ' dlOOOO * datat; / 1作乘法运rr. != 20'dO)) temp <事 datasi cbuf <- 2 0 ' d1 ; databbuf <- datas; cntf1ag <- l ' bl ; fin. ish <= 1 'b1; end && else if ( (datam > temp) (cntf1ag == l ' bl) ) //作比较除法运fl begin + te.mp <回 temp databbufi + cbuf <- cbuf 20'dli end / 5 1 6 /1 第 12 童 胖胖测量设计棚\ else begin freout <= cbuf; l ' bO; fi!)ish <= cntflag <= 1 'bO; end end endmodule 保存文件为 frediv. V , 单 击 Files → Create/Update → Create Symbol Files for Currenl File 命令, 为 frediv.v 生成原理圈模块。 打开原理阁文件 equalfre.bdf, 在原理图空1' 1 处 双 击 , 在弹出的 Symbol 对话框中选择 Project → frediv 模块, J在击 OK 按钮退出 Symbol 对话框. 在原理圈的适当位置放置 frediv 模块, 并添加输入输出模块 , 连接各个模块如! 图 1 2-16 所示。 .., ,. � 阶削 箩画... ... .蜷- .鹏. - 仙,、喝.. ., ... ‘协 ‘明队a‘"" .凰. 'M‘】' " 警 _, ‘.. ι. .叶同队A(.. .. 事刷· "画画 曲"鸣" .. ,_ 肉 , 抽 罐_U OI "疆_111 甸 确. " t..1., 1 ‘� "叫M愉甸 回 1 2-16 等精度ì�11报法的秘块怎 i 核阳 保存原理国为 equalfre.bdfo 编译工程文件, 编译无以后.ì(!.击 Processing → Geoerate Functional Simulation Netlist, 产生功能仿真网表。 打开波形仿真文件 equalfre.vwf, 加入输 入输出信号, 单击 巳 技旬i进行等精度测频陆的放形仿真, 波形仿真报告 如 圄 1 2- 1 7 所乐。 回... 主� d.1< procat• .Uc飞 a.,.hou\ [i clk""t 国 cllt-tc:nt liI fr..旧 671. 089 •.$ 1.口[ff 塞 1. 342 s 1. &18 s 2. I 阁 1 2-17 �字精度测颇讼的被J� 1}itt11it �吁 \517\ 被形仿真报告说明 a 输出信号 clkcnt 为标准信号在实际闸门的计数结果 , 输 出信号 cLktcnt 为 被测信号在实 际闸门的计数结 果 。 输出信号 freout 为被测信号的频率值输 出 , 值为 1∞0, 单位为 Hz. 仿真结果正确. 12.5 本章小结 本章详细介绍了基于 FPGA 频率的测量方法, 包括直接测频法、 周期测频法和等精度 测频法, 并给出了详细的代码和注释. 通过本璋的学 习 , 读者加上被测信号的输入处理电 路和输出显示电路, 就可以构成一个简易的数字频率计。 /518/ -
  • Top_arrow
    回到顶部
    EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高进,我们会尽快处理。