




已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Verilog学习心得因为Verilog是一种硬件描述语言,所以在写Verilog语言时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何去解释这个module. 比如在决定是否使用reg定义时,要问问自己物理上是不是真正存在这个register, 如果是,它的clock是什么? D端是什么?Q端是什么?有没有清零和置位?同步还是异步?再比如上面讨论的三态输出问题,首先想到的应该是在register的输出后面加一个三态门,而不是如何才能让编译器知道要“赋值”给一个信号为三态。同样,Verilog中没有“编译”的概念,而只有综合的概念。 写硬件描述语言的目的是为了综合,所以说要想写的好就要对综合器有很深的了解,这样写出来的代码才有效率。 曾经接触过motorola苏州设计中心的一位资深工程师,他忠告了一句:就是用verilog描述电路的时候,一定要清楚它实现的电路,很多人只顾学习verilog语言,而不熟悉它实现的电路,这是设计不出好的电路来的. 一般写verilog code时,对整个硬件的结构应该是很清楚了,最好有详细的电路图画出,时序问题等都应该考虑清楚了。可以看着图直接写code。 要知道,最初Verilog是为了实现仿真而发明的.不可综合的Verilog语句也是很重要的.因为在实际设计电路时,除了要实现一个可综合的module外,你还要知道它的外围电路是怎样的,以及我的这个电路与这些外围电路能否协调工作.这些外围电路就可以用不可综合的语句来实现而不必管它是如何实现的.因为它们可能已经实际存在了,我仅是用它来模拟的.所以,在写verilog的时候应该要先明确我是用它来仿真的还是综合的. 要是用来综合的话,就必须要严格地使用可综合的语句,而且不同的写法可能产生的电路会有很大差别,这时就要懂一些verilog综合方法的知识.就像前面说的,脑子里要有一个硬件的概念.特别是当综合报错时,就要想一想我这种写法能不能用硬件来实现,verilog毕竟还不是C,很多写法是不可实现的.要是这个module仅是用来仿真的,就要灵活得多了,这时你大可不必太在意硬件实现.只要满足它的语法,实现你要的功能就行了. 有网友说关于#10 clk=clk的问题,虽然这种语句是不可综合的,但是在做simulation和verification是常常用它在testbench中来产生一个clock信号。再比如常常用到的大容量memory, 一般是不会在片上实现的,这个时候也需要一个unsynthesizable module. mengxy所言切中肯罄。 我们设计的module的目的是为了可以综合出功能正确,符合标准的电路来。我想这是个反复的过程,就像我们在写design flow中总要注明前仿真,综合后的仿真,以及后仿真等。仿真是用来验证我们的设计的非常重要的手段。而verilog里那些看是无聊的语句这个时候就会发挥很大的作用。我想,用过verilog_xl的兄弟应该深有体会。verilog_xl里的操作,可以用verilog里的系统命令来完成。通过最近的应聘我也深有体会,很多公司看中你在写code时,是否考虑到timing,architecture,DFT等,这也说明verilog中的任何语句都非常重要的。 要写代码前必须对具体的硬件有一个比较清晰的概念但是想一次完成可综合代码就太夸张了,verilog的自顶向下设计方法就是从行为建模开始的,功能验证了以后再转向可综合模型.太在意与可综合令初期设计变得太累 很同意这种看法,在做逻辑结构设计时,综合的因素是要考虑的,但是有很多东西不能考虑的过于细致,就是在设计的时候不能过于紧卡时延,面积等因素,因为这样以来综合后优化的余量就会很小,反而不利与设计的优化,如果在时延和面积要求不是很紧张的情况下,其实代码写的行为级,利用综合工具进行优化也是一种方法。偶就听说有一家很有名的公司,非常相信综合工具的优化能力,从来不作综合后仿真的,hehe.当然,如果面积和时延的要求很高,最好还是把代码写的底层一点,调用库单元时,也要充分考虑其面积和时延的因素。Verilog与C+的类比1. Verilog中的module对应C+中的class。它们都可以实例化。例如可以写一个FullAdder module,表示全加器这种器件。module FullAdder(a, b, cin, sum, cout); input a, b, cin; output sum, cout; assign cout, sum = a + b + cin;endmodule 然后在执行8-bit补码加减运算的ALU module中实例化8个FullAdder,表示ALU用到了8个FullAdder。module ALU(a, b, result, cout, is_add); input7:0 a, b; input is_add; output7:0 result; output cout; wire7:0 b_not = b; wire7:0 b_in = is_add ? b : b_not; wire7:0 carry; assign carry0 = is_add ? 1b0 : 1b1; / module 实例化 / 8-bit ripple adder FullAdder fa0(a0, b_in0, carry0, result0, carry1); FullAdder fa1(a1, b_in1, carry1, result1, carry2); FullAdder fa2(a2, b_in2, carry2, result2, carry3); FullAdder fa3(a3, b_in3, carry3, result3, carry4); FullAdder fa4(a4, b_in4, carry4, result4, carry5); FullAdder fa5(a5, b_in5, carry5, result5, carry6); FullAdder fa6(a6, b_in6, carry6, result6, carry7); FullAdder fa7(a7, b_in7, carry7, result7, cout);endmodule 对应在C+中先写FullAdder class,然后在ALU class中以FullAdder作为data member。class FullAdder; class ALU FullAdder fa8;另外一点,moudle声明port的方式,像是从早期C语言的函数定义中学来的:char* strcpy(dst, src) char* dst; char* src; / .2. Verilog中的模块调用时,指定端口可以使用名称绑定。C+在调用函数时,参数只能按顺序书写。例如memset()的原型是:void *memset(void *s, int c, size_t n);如果你想将某个buf清零,应该这么写:char buf256;memset(buf, 0, sizeof(buf);但是如果你不小心写成了:memset(buf, sizeof(buf), 0); 编译器不会报错,但运行的实际效果是根本没有对buf清零。(记得Richard Stevens的书里提到过这一点。) 在Verilog中,如果要写一个测试ALU的module,那么其中对ALU实例化的指令可以这么写:module alu_test;reg8:0 a_in, b_in;reg op_in;wire7:0 result_out;wire carry_out;ALU alu0(.a(a_in7:0), .b(b_in7:0), .is_add(op_in), .result(result_out), .cout(carry_out); / .endmodule这样就比较容易检查接线错误。另外,在C+中,如果所有参数类型不同,而且之间没有隐式类型转换,那么可以利用C+的强类型机制在编译期检查出这种调用错误。3. Verilog中把大括弧用作bit的并置,因此语句块要用begin/end标示。Verilog中小括号()和中括号的作用与C+中类似,前者用于函数或模块调用,后者用于下标索引。我想如果Verilog把尖括号用作bit并置的话,就能把大括号解放出来,用作标示语句块,这样写起来更舒服一些。4.Verilog本质上是测试驱动开发的。对于每个module都应该有对应的test bench(或称test fixture)。比较好的情况是,一个工程师写module,另一个工程师写对应的testbench,这样很容易检查出对电路功能需求理解不一致的地方。因此还可以说Verilog主张结对编程(pair programming)。例如对前面的ALU module的test bench可以写成:timescale 1ns / 1ns module alu_test;reg8:0 a_in, b_in;reg op_in;wire7:0 result_out;wire carry_out;ALU alu0(.a(a_in7:0), .b(b_in7:0), .is_add(op_in), .result(result_out), .cout(carry_out);reg9:0 get, expected;reg has_error;initial beginhas_error = 1b0;op_in = 1b1; / test additionfor (a_in = 9b0; a_in != 256; a_in = a_in + 1) for (b_in = 9b0; b_in != 256; b_in = b_in + 1) begin #1; get = carry_out, result_out; expected = a_in + b_in; if (get != expected) begin $display(a_in = %d, b_in = %d, expected %d, get %d, a_in, b_in, expected, get); has_error = 1b1; end endop_in = 1b0; / test subtraction/ .if (has_error = 1b0) begin$display(ALL TESTS PASSED!);end$finish;endendmodule5. Verilog比起VHDL的不足之处在于,它只能定义concrete class,不能定义abstract class。也就是说interface和implementation不能分离。这在设计大型电路时就显得表现力不足。不过这关系不大,因为可以在编译时选择同一模块的不同实现版本,间接实现了接口与实现的分离。在VHDL中,强制将接口与实现分离。对每个模块,你都得先写接口(定义输入输出信号),即ENTITY;然后至少写一份实现,即ARCHITECTURE。每个ENTITY可以有不止一份实现,例如可以有行为描述的,也有数据流描述的。然后在配置文件中选择该ENTITY到底用哪一份实现。举例来说(选自VHDL入门解惑经典实例经验总结一书),分频器模块可以这么写,先定义其接口FreqDevider,然后定义两份实现Behavior和Dataflow:LIBRARY IEEE;USE IEEE.Std_Logic_1164.All; ENTITY FreqDevider ISPORT( Clock : IN Std_Logic; Clkout : OUT Std_Logic);END; ARCHITECTURE Behavior OF FreqDevider ISSIGNAL Clk : Std_Logic;BEGIN PROCESS (Clock) BEGIN IF rising_edge(Clock) THEN Clk = NOT Clk; END IF; END PROCESS; Clkout = Clk;END;ARCHITECTURE Dataflow OF FreqDevider IS- signal declarationsBEGIN- processesEND; 在C+中,既可以写concrete class,也可以写abstract class。比Verilog和VHDL都方便。6. Verilog和VHDL都有模板的概念,Verilog称为参数(parameter),VHDL称为类属(generic)。不过好像都只能用整数作为模板参数,不能像C+那样用类型作为模板参数。7. 目前来看,Verilog是硬件描述语言,不是硬件设计语言。在用Verilog设计电路的时候,我们是把脑子中想好的电路用Verilog“描述”出来:哪里是寄存器、哪里是组合逻辑、数据通路是怎样、流水线如何运作等等都要在脑子里有清晰的映象。然后用RTL代码写出来,经过综合器综合出的电路与大脑中的设想相比八九不离十。这就像说C语言是可移植的汇编语言,以前好的C程序员在写代码的时候,能够知道每条语句背后对应的汇编代码是什么。verilog设计经验点滴1,敏感变量的描述完备性Verilog中,用always块设计组合逻辑电路时,在赋值表达式右端参与赋值的所有信号都必须在always (敏感电平列表)中列出,always中if语句的判断表达式必须在敏感电平列表中列出。如果在赋值表达式右端引用了敏感电平列表中没有列出的信号,在综合时将会为没有列出的信号隐含地产生一个透明锁存器。这是因为该信号的变化不会立刻引起所赋值的变化,而必须等到敏感电平列表中的某一个信号变化时,它的作用才表现出来,即相当于存在一个透明锁存器,把该信号的变化暂存起来,待敏感电平列表中的某一个信号变化时再起作用,纯组合逻辑电路不可能作到这一点。综合器会发出警告。Example1:input a,b,c;reg e,d;always (a or b or c) begin e=d&a&b; /*d没有在敏感电平列表中,d变化时e不会立刻变化,直到a,b,c中某一个变化*/ d=e |c; endExample2:input a,b,c;reg e,d;always (a or b or c or d) begin e=d&a&b; /*d在敏感电平列表中,d变化时e立刻变化*/ d=e |c; end2, 条件的描述完备性如果if语句和case语句的条件描述不完备,也会造成不必要的锁存器。Example1:if (a=1b1) q=1b1;/如果a=1b0,q=? q将保持原值不变,生成锁存器!Example2:if (a=1b1) q=1b1;else q=1b0;/q有明确的值。不会生成锁存器!Example3: reg1:0 a,q; . case (a) 2b00 : q=2b00; 2b01 : q=2b11;/如果a=2b10或a=2b11,q=? q将保持原值不变,锁存器! endcaseExample4: reg1:0 a,q; . case (a) 2b00 : q=2b00; 2b01 : q=2b11; default: q=2b00;/q有明确的值。不会生成锁存器! endcaseVerilog中端口的描述1,端口的位宽最好定义在I/O说明中,不要放在数据类型定义中;Example1:module test(addr,read,write,datain,dataout)input7:0datain;input15:0 addr;input read,write;output7:0 dataout;/要这样定义端口的位宽!wire addr,read,write,datain;regdataout;Example2:module test(addr,read,write,datain,dataout)inputdatain,addr,read,write;output dataout;wire15:0 addr;wire7:0datain;wire read,write;reg7:0 dataout; / 不要这样定义端口的位宽!2,端口的I/O与数据类型的关系: 端口的I/O 端 口 的 数 据 类 型 module内部 module外部 input wire wire或reg output wire或reg wire inout wire wire3,assign语句的左端变量必须是wire;直接用=给变量赋值时左端变量必须是reg!Example:assign a=b; /a必须被定义为wire!*begin a=b; /a必须被定义为reg!endVHDL 中 STD_LOGIC_VECTOR 和 INTEGER 的区别例如 A 是INTEGER型,范围从0到255;B是STD_LOGIC_VECTOR,定义为8位。A累加到255时,再加1就一直保持255不变,不会自动反转到0,除非令其为0;而B累加到255时,再加1就会自动反转到0。所以在使用时要特别注意!以触发器为例说明描述的规范性1,无置位/清零的时序逻辑 always ( posedge CLK) begin Q=D; end2,有异步置位/清零的时序逻辑 异步置位/清零是与时钟无关的,当异步置位/清零信号到来时,触发器的输出立即被置为1或0,不需要等到时钟沿到来才置位/清零。所以,必须要把置位/清零信号列入always块的事件控制表达式。 always ( posedge CLK or negedge RESET) begin if (!RESET) Q=0; else Q=D; end3,有同步置位/清零的时序逻辑 同步置位/清零是指只有在时钟的有效跳变时刻置位/清零,才能使触发器的输出分别转
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年河北廊坊开发区公开选调工作人员40名备考练习题库及答案解析
- 空间病毒消毒合同范本
- 打混凝土合同范本
- 2025年合肥市朝霞小学教师招聘备考练习试题及答案解析
- 2025年实验诊断学实验室检查常见异常结果解释试题答案及解析
- 棚户租房合同范本
- 私人屋建筑合同范本
- 2025年食品卫生学科学科食品中毒事件处理流程考核答案及解析
- 热计量改造合同范本
- 2025年口腔颌面外科手术并发症处理模拟考核试卷答案及解析
- 《社交媒体的传播》课件
- DB33T 768.3-2024安全技术防范系统建设技术规范 第3部分:汽车客运站与客运码头
- 利用数字化工具改善医共体慢病管理水平
- 氧化铝工艺流程图解析
- 北京银行招聘考试真题2024
- 2025医院医保培训
- 医院法律法规专题培训课件
- 2025-2030中国电气火灾监控模块竞争战略规划与需求预测分析研究报告
- 构建企业ESG与可持续发展计划
- 制造业生产组织协调措施探讨
- 企业战略合作协议签署备忘录
评论
0/150
提交评论