verilog总结
- 格式:doc
- 大小:52.00 KB
- 文档页数:8
vivado工具与verilog语言的使用实验总结文章标题:深入探讨vivado工具与verilog语言的使用实验总结导言:在数字电路设计与实现的过程中,vivado工具与verilog语言的使用至关重要。
通过一系列的实验,我们能够全面地了解这两者在数字电路设计中的应用,并掌握它们的使用技巧。
本文将以从简到繁、由浅入深的方式,深入探讨vivado工具与verilog语言的使用实验总结,帮助读者全面理解这一主题。
一、vivado工具的基本介绍在数字电路设计中,vivado工具是一款由Xilinx公司推出的集成化开发环境。
它拥有丰富的功能和强大的性能,能够帮助设计者完成从设计到验证的全流程。
在实验中,我们首先对vivado工具的基本操作进行了学习,包括创建工程、添加设计文件、进行综合与实现等一系列步骤。
通过实践,我们能更加熟练地运用vivado工具进行数字电路设计。
二、verilog语言的基础知识verilog语言是一种硬件描述语言,广泛应用于数字电路的设计与验证。
在实验中,我们深入学习了verilog语言的基础知识,包括模块化的设计思想、信号的赋值与传输、行为级建模和结构级建模等内容。
通过对verilog语言的学习,我们能够更好地理解数字电路的工作原理,提高设计的效率和准确性。
三、vivado工具与verilog语言的综合应用在实验的进阶阶段,我们将vivado工具与verilog语言相结合,进行了一系列的综合应用实验。
通过实际的案例学习,我们掌握了如何利用vivado工具进行综合、仿真和验证,并通过verilog语言实现各种功能模块。
这些实验不仅加深了我们对vivado工具和verilog语言的理解,同时也提高了我们的综合应用能力。
总结与回顾:通过以上的实验学习,我们对vivado工具与verilog语言的使用有了更深入的了解。
vivado工具作为一款集成化开发环境,能够为数字电路设计者提供全方位的支持;而verilog语言则作为一种硬件描述语言,能够帮助设计者更加灵活地进行数字电路设计与验证。
3Verilog1.Verilog HDL是一种硬件描述语言,用于从算法级、RTL级、门级到开关级的多种抽象设计层次的数字系统建模。
令行为级描述:数据结构和过程类似C;用于描述算法级和RTL级的Verilog模型。
令结构级描述:用于描述门级和开关级电路;特点:支持门级延时信息和驱动能力等的描述。
VHDL侧重于系统级描述,从而更多的为系统级设计人员所采用;Verilog侧重于电路级描述,从而更多的为电路级设计人员所采用。
2. Verilog HDL设计入门模块(module)模块是Verilog 的基本描述单位模块的定义从关键词module开始,到关键词endmodule结束每条Verilog HDL语句以分号“;”作为结束模块的基本结构(1)、模块定义行以module开头接着给出所定义模块的;模块名括号内给出端口名列表(端口名等价于硬件中的外接引脚,模块通过这些端口与外界发生联系)以分号结束(2)、端口类型说明端口类型只有input、output、inout三种(3)、数据类型说明支持的数据类型有连线类(wire)和寄存器(reg)类两个大类一位宽的wire类可被缺省外,其它凡将在在后面的描述中出现的变量都应给出相应的数据类型说明(4)、描述体部具体)展开对模块的描述(5)、结束行用关键词endmodule标志模块定义的结束它的后面没有分号令行为描述(Behavior)描述行为或功能特性令结构描述(Structure)描述通过什么样的结构方式将不同的实体连接起来用以实现所要求的行为或功能。
测试与仿真令测试平台(Test Bench):在输入端口加入测试信号,从输出端口检测其输出结果是否正确。
令通常将需要测试的对象称之为DUT (Device Under Test)。
令测试模块:要调用DUT;包含用于测试的激励信号源;能够实施对输出信号的检测,并报告检测的结果。
过程语句令Initial:只顺序地执行一次;没有触发条件。
verilog算法小结2009-11-0923:20:45|分类:FPGA|字号大中小订阅编程要点:1、RTL中基本上不用for语句,它会被综合器展开为所有变量情况的执行语句,每个变量独立占用寄存器资源,造成资源浪费。
For语句大多数用在testbeach中。
能复用的的处理模块尽量复用,即使所有操作都不能复用,也要用case语句展开处理。
2、if—else if—else应该避免使用,因为它综合出来会产生“优先级”,消耗资源。
if—if、case是平行结构的,不产生“优先级”。
尽量使用case和if—if。
3、系统上复用模块节省的面积远比代码上优化来的实惠的多。
4、使用FPGA,还是CPLD:FPGA触发器资源丰富;——时序逻辑设计CPLD组合逻辑资源丰富。
——组合逻辑设计5、只采用同步时序电路,不采用异步时序电路。
6、延时:同步时序电路的延时最常用的设计方法是用分频或倍频的时钟或者同步计数器完成所需要的延时。
对于比较大的和特殊定时要求的延时,一般用高速时钟产生一个计算器;对于比较小的延时,可以用一个D触发器打一下。
#n一般只用在testbeach,在电路综合时会被忽略,所以不用。
常用代码总结:D触发器:always@(posedge clk or negedge rst)if(rst==0)dout<=0;else dout<=din;应用:1、由于是在clk上升沿才打入,所以可以消除din存在的毛刺。
2、延时Gray码计数器:000-001-011-010-110-100-101-111module gray_cnt(//inputclk,rst//outputgray_cnt_out);input clk;input rst;output[4:0]gray_cnt_out;reg[4:0]gray_cnt_out;reg[4:0]cnt;reg[4:0]gray_cnt_temp;integer i;always@(posedge clk or negedge rst)beginif(rst==0)cnt<=0;elsecnt<=cnt+1;endalways@(cnt)//二进制转gray码begingray_cnt_temp[4:0]=cnt[4:0];for(i=0;i<=4;i++)gray_cnt_temp[i-1]=cnt[i-1]^cnt[i]; endalways@(posedge clk or negedge rst)beginif(rst=0)gray_cnt_out<=0;elsegray_cnt_out<=gray_cnt_temp;endendmodule应用:时钟域设计中,计数器值由时钟域a传到时钟域b采用gray码。
verilog instance 语句-概述说明以及解释1.引言1.1 概述Verilog是一种硬件描述语言,用于设计数字电路并进行硬件仿真。
在Verilog中,Instance语句被广泛应用于电路的模块化设计和组件重用。
它提供了一种简单而有效的方法,将已设计好的模块实例化为一个更大的电路系统。
Instance语句的概念类似于面向对象编程中的对象实例化,可以理解为在设计电路中创建了一个特定的实例。
通过使用Instance语句,可以将多个独立的模块连接在一起,形成一个完整的系统。
每个实例都具有自己的输入和输出端口,可以通过连接这些端口来实现数据的传输和处理。
使用Instance语句的一个主要优势是可以提高电路设计的可复用性。
通过将已验证和经过测试的模块实例化,可以减少重新设计和验证的工作量,同时确保了系统的稳定性和可靠性。
此外,Instance语句还提供了一种结构化编程的方式,使得电路设计更加清晰和易于维护。
然而,Instance语句也存在一些局限性。
首先,实例化的过程需要消耗一定的资源,包括时间和空间。
因此,在设计复杂的电路系统时,可能需要考虑资源的分配和优化。
其次,Instance语句只能在静态的编程环境中使用,在设计时需要提前确定系统的结构和连接方式,不适用于动态变化的场景。
尽管Instance语句在当前的硬件设计中已经得到了广泛应用,但它的未来发展仍然受到一些限制。
未来的发展方向可能包括提供更好的资源管理机制,以及支持动态配置和重构的能力。
同时,随着硬件设计的不断演进,Instance语句可能会与其他编程语言或工具进行更紧密的集成,以提高设计效率和灵活性。
综上所述,Verilog Instance语句是一种用于实例化模块并连接电路的重要概念。
它可以提供电路设计的可复用性和结构化编程的优势,但也存在一些局限性。
未来,我们可以期待Instance语句在硬件设计中的进一步发展和应用。
1.2 文章结构本篇文章主要围绕Verilog Instance语句展开论述。
Verilog程序运行原理详解1. 引言Verilog是一种硬件描述语言,用于描述和设计数字电路。
在Verilog程序中,我们可以通过编写逻辑门等硬件元件的描述来实现电路的功能。
Verilog程序的运行原理涉及到编译、仿真和综合等多个步骤。
本文将详细解释这些步骤的基本原理,并对Verilog程序的运行过程进行全面、详细、完整和深入的探讨。
2. 编译编译是将Verilog程序翻译成计算机可以理解和执行的指令的过程。
Verilog程序通常包含模块定义、端口声明、信号声明、逻辑描述等部分。
2.1 模块定义在Verilog程序中,模块是描述电路功能的基本单元。
模块定义由关键字module 开始,后面跟着模块的名称和端口定义。
例如:module my_module(input A, input B, output C);// 逻辑描述endmodule2.2 端口声明模块的端口声明定义了输入和输出信号的名称和类型。
输入信号使用关键字input 声明,输出信号使用关键字output声明。
例如:module my_module(input A, input B, output C);// 逻辑描述endmodule2.3 信号声明信号声明定义了在模块中使用的内部信号的名称和类型。
信号可以是输入信号、输出信号或内部信号。
例如:module my_module(input A, input B, output C);wire D;// 逻辑描述endmodule2.4 逻辑描述逻辑描述部分包含了对电路功能的具体描述,通常使用逻辑门和时序元件的描述来实现。
例如:module my_module(input A, input B, output C);wire D;assign D = A & B;assign C = D;endmodule在编译过程中,编译器将对Verilog程序进行语法分析、词法分析和语义分析,生成对应的语法树和符号表。
verilog条件运算符摘要:一、引言二、Verilog条件运算符的概念1.逻辑运算符2.关系运算符3.条件运算符三、Verilog条件运算符的用法1.逻辑运算符的用法2.关系运算符的用法3.条件运算符的用法四、Verilog条件运算符的实例1.逻辑运算符实例2.关系运算符实例3.条件运算符实例五、总结正文:一、引言Verilog是一种硬件描述语言,广泛应用于数字电路和模拟电路的设计领域。
在Verilog中,条件运算符是用于实现逻辑判断的重要工具,可以帮助设计者实现复杂的逻辑功能。
本文将对Verilog条件运算符进行详细介绍。
二、Verilog条件运算符的概念Verilog条件运算符主要包括逻辑运算符、关系运算符和条件运算符。
1.逻辑运算符逻辑运算符主要有与(&)、或(|)、异或(^)、非(~)等。
这些运算符用于对逻辑信号进行操作,实现逻辑门的功能。
2.关系运算符关系运算符主要有小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、等于(==)、不等于(!=)等。
这些运算符用于比较两个值的大小关系。
3.条件运算符条件运算符主要有逻辑与(&&)、逻辑或(||)等。
这些运算符用于组合多个条件,实现更复杂的逻辑功能。
三、Verilog条件运算符的用法1.逻辑运算符的用法逻辑运算符主要应用于逻辑表达式的计算。
例如,A & B表示A和B的逻辑与操作,A | B表示A和B的逻辑或操作,A ^ B表示A和B的异或操作,~A表示A的非操作。
2.关系运算符的用法关系运算符主要应用于比较两个值的大小关系。
例如,A < B表示A小于B,A > B表示A大于B,A <= B表示A小于等于B,A >= B表示A大于等于B,A == B表示A等于B,A != B表示A不等于B。
3.条件运算符的用法条件运算符主要应用于组合多个条件,实现更复杂的逻辑功能。
1、verilog特点:★区分大小写,所有关键字都要求小写★不是强类型语言,不同类型数据之间可以赋值和运算★ //是单行注释可以跨行注释★描述风格有系统级描述、行为级描述、RTL级描述、门级描述,其中RTL级和门级别与具体电路结构有关,行为级描述要遵守可综合原★门级描述使用门级模型或者用户自定义模型UDP来代替具体基本元件,在IDE中针对不同FPGA器件已经有对应的基本元件原语verlog语法要点2、语句组成:★ module endmodule之间由两部分构成:接口描述和逻辑功能描述★ IO端口种类: input output inout★相同位宽的输入输出信号可以一起声明, input[3:0] a,b; 不同位宽的必须分开写★内部信号为reg类型,内部信号信号的状态: 0 1 x z, 3‘bx1=3’bxx1 x/z会往左扩展 3‘b1=3’b001 数字不往左扩展★逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能★ always之间、assign之间、实例引用之间以及它们之间都是并行执行,always内部是顺序执行3、常量格式: <二进制位宽><‘><进制><该进制的数值>:默认进制为10进制默认位宽为32位位宽是从二进制宽度角度而言的由位宽决定从低位截取二进制数2’hFF=2‘b11,通常由被赋值的reg变量位宽决定parameter常用于定义延迟和变量位宽,可用常量或常量表达式定义4、变量种类: wire reg memory① IO信号默认为wire类型,除非指定为reg类型(reg和wire 的区别)wire可以用作任何输入输出端口wire包括input output inoutwire不带寄存功能assign赋值语句中,被赋值的信号都是wire类型assign之所以称为连续赋值,是因为不断检测表达式的变化reg类型可以被赋值后再使用,而不是向wire一样只能输出reg类型变量初始值为xalways模块里被赋值的信号都必须定义为reg类型,因为always 可以反复执行,而reg表示信号的寄存,可以保留上次执行的值reg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来② memory型只有一维数组,由reg型变量组成memory初始化只能按地址赋值,不能一次性赋值1*256的memory写法: reg mema[255:0] mema[3]=0; 不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取A[a:b] 无论a b谁大,a总是实际电路的信号高位,b总是实际电路的信号低位算术运算中如果有X值则结果为Xfor循环中的变量另外定义成integer,因为它不是实际信号,有正负;reg则以无符号数存在5、运算符(其他简单的书上有自己看)== 和!=只比较0、1,遇到z或x时结果都为x (x在if中算做假条件),结果可能是1、0、x===和!==比较更加苛刻,包括x和z的精确比较,结果可能是0、1 &&的结果只有1‘b1或1’b0两种, A&A的结果位宽则是与A相同的{1,0}为 64‘h100000000,所以拼接运算中各信号一定要指定位宽移位运算左移将保留 4'b1000<<1等于5'b10000,右移则舍弃 4'b0011等于4'b0001数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算6、非阻塞式赋值<=与阻塞式赋值=(比较)阻塞:在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句阻塞非阻塞:在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞<=:块结束后才能完成赋值块内所有<=语句在always块结束时刻同时赋值<=右边各变量的值是上一次时钟边沿时,这些变量当时的值用于描述可综合的时序电路=:=语句结束之后过程always才可能结束在always过程中,begin end块内按先后顺序立即赋值,在fork join内同时赋值(可能造成冲突)与assign连用描述组合电路begin end中阻塞的含义:begin ...@(A) B=C...; end 如果A事件不发生则永远不能执行下去,被阻塞了由于时钟的延时(往往在ps级),多个always(posedge)之间究竟谁先执行是个未知数使用八原则:(1)时序电路建模时,采用非阻塞赋值(2)锁存器电路建模时,采用非阻塞赋值。
fpga语法知识点总结一、Verilog语言Verilog是一种硬件描述语言(HDL),用于描述数字电路和系统级设计。
在FPGA设计中,Verilog语言常常用于描述逻辑功能和时序控制。
Verilog语言包括模块、端口、信号声明、组合逻辑、时序逻辑、行为模拟等部分。
1. 模块:Verilog中的模块是一个最基本的组织单位,它类似于面向对象编程中的类。
每个模块都有自己的输入输出端口和内部逻辑实现。
在FPGA设计中,通常会设计多个模块来实现不同的功能,然后将这些模块连接起来,构成一个完整的系统。
2. 端口:在Verilog中,端口用于定义模块与外部环境的接口。
端口可以被定义为输入端口(input)、输出端口(output)、双向端口(inout)等,用于进行与外部信号的通信。
3. 信号声明:在Verilog中,信号用于传递逻辑信息。
信号可以是单个的位(bit)信号,也可以是多位(bus)信号。
在FPGA设计中,对信号的声明和使用是非常重要的,可以影响到设计的性能和资源占用。
4. 组合逻辑:组合逻辑是一种不含时钟的逻辑电路,其输出仅由输入决定。
在Verilog中,组合逻辑常常使用逻辑运算符和条件语句来描述。
5. 时序逻辑:时序逻辑是一种包含时钟信号的逻辑电路,其输出由时钟信号和输入信号共同决定。
在FPGA设计中,时序逻辑和时序约束非常重要,可以影响到设计的时序性能。
6. 行为模拟:行为模拟是一种用于验证设计功能和性能的技术。
在Verilog中,可以使用行为模拟语句来描述设计的行为,并进行仿真验证。
二、VHDL语言VHDL(VHSIC Hardware Description Language)是一种硬件描述语言,用于描述数字电路和系统级设计。
在FPGA设计中,VHDL语言和Verilog语言一样,用于描述逻辑功能和时序控制。
VHDL语言包括实体、端口、信号声明、组合逻辑、时序逻辑、行为模拟等部分。
1. 实体:在VHDL中,实体是描述一个硬件单元的基本描述。
verilog知识点总结Verilog知识点总结Verilog是一种硬件描述语言(HDL),用于描述数字电路和系统。
在数字电路设计中,Verilog是一种重要的工具,它可以描述组合逻辑和时序逻辑,以及设计和验证硬件。
本文将总结Verilog的一些重要知识点,包括模块化设计、数据类型、运算符、时序建模和测试基础等。
一、模块化设计在Verilog中,模块是设计的基本单元。
模块化设计可以使复杂的电路设计更加可管理和可重用。
在Verilog中,模块由模块声明和模块体组成。
模块声明定义了模块的接口,包括输入、输出和内部信号。
模块体定义了模块的功能,包括组合逻辑和时序逻辑。
二、数据类型Verilog支持多种数据类型,包括位、字、整数和实数。
位是最基本的数据类型,用于表示二进制数。
字是一组连续的位,用于表示整数或实数。
整数是有符号或无符号的整数,用于表示整数值。
实数是浮点数,用于表示小数值。
三、运算符Verilog支持多种运算符,包括算术运算符、逻辑运算符、位运算符和关系运算符。
算术运算符包括加法、减法、乘法和除法。
逻辑运算符包括与、或、非和异或。
位运算符包括位与、位或、位非和位异或。
关系运算符包括等于、不等于、大于、小于、大于等于和小于等于。
四、时序建模时序建模是描述时序电路行为的重要方面。
在Verilog中,可以使用时钟信号和时钟边沿来定义时序行为。
时钟信号用于同步电路的操作,时钟边沿用于触发电路的操作。
常用的时序建模语句包括时钟边沿敏感的always语句和延迟语句。
五、测试基础测试是硬件设计过程中的重要环节。
Verilog提供了多种测试方法,包括模拟仿真、自动测试生成和形式验证。
模拟仿真是通过模拟输入信号并观察输出信号来验证电路的功能。
自动测试生成是通过生成测试向量来覆盖电路的所有可能输入组合。
形式验证是通过数学证明来验证电路的正确性。
六、常用编码风格在Verilog中,编码风格是编写可读性高且易于理解的代码的重要因素。
verilog知识点总结Verilog是一种硬件描述语言(HDL),用于描述数字电路和系统,它广泛应用于数字系统设计和仿真领域。
本文将总结一些Verilog 的重要知识点,以帮助读者更好地理解和应用Verilog。
一、Verilog的基本语法Verilog的基本语法包括模块声明、端口声明、信号声明、数据类型、运算符等。
Verilog中的模块是设计的基本单元,模块声明包括模块名和端口声明。
端口可以是输入、输出或双向的。
信号声明用于定义内部信号,可以是寄存器或线网类型。
Verilog支持多种数据类型,包括整数、浮点数、向量、数组等。
Verilog还提供了丰富的运算符,包括算术运算符、逻辑运算符、位运算符等。
二、组合逻辑电路描述Verilog可以用来描述各种组合逻辑电路,如与门、或门、非门等。
通过使用逻辑运算符和条件语句,可以很方便地描述组合逻辑电路的功能。
Verilog还提供了多种语法结构,如if语句、case语句等,用于描述复杂的逻辑功能。
三、时序逻辑电路描述时序逻辑电路是一种带有状态的电路,Verilog可以用来描述各种时序逻辑电路,如触发器、计数器、状态机等。
通过使用时钟信号和触发器,可以实现电路的时序行为。
Verilog提供了多种触发器类型,如D触发器、JK触发器、T触发器等,可以根据实际需求选择合适的触发器类型。
四、模块实例化和层次化设计Verilog支持模块的实例化和层次化设计,可以将一个模块实例化为另一个模块的一部分。
通过模块实例化,可以方便地实现模块的复用和层次化设计。
层次化设计可以使整个系统更加清晰和模块化,方便调试和维护。
五、仿真和验证Verilog可以用于对设计进行仿真和验证,以确保设计的正确性。
Verilog提供了仿真器,可以对设计进行时序仿真和波形查看。
通过仿真,可以验证设计的功能和时序行为是否符合要求。
Verilog 还支持测试向量的生成和自动验证,可以自动生成测试向量并进行自动验证。
verilog基本运算符一、概述在verilog中,运算符是用来对信号进行操作和计算的关键元素。
它们可以用于实现各种逻辑和算术运算,从而实现电路的功能。
本文将介绍verilog中的基本运算符,包括逻辑运算符、位运算符、算术运算符和关系运算符。
二、逻辑运算符1. 逻辑与运算符(AND):用符号"&"表示,当两个操作数都为1时,结果为1,否则为0。
2. 逻辑或运算符(OR):用符号"|"表示,当两个操作数至少有一个为1时,结果为1,否则为0。
3. 逻辑非运算符(NOT):用符号"~"表示,对操作数进行取反操作,即1变为0,0变为1。
4. 逻辑异或运算符(XOR):用符号"^"表示,当两个操作数中只有一个为1时,结果为1,否则为0。
三、位运算符1. 按位与运算符(AND):用符号"&"表示,对操作数的每一位进行与操作。
2. 按位或运算符(OR):用符号"|"表示,对操作数的每一位进行或操作。
3. 按位非运算符(NOT):用符号"~"表示,对操作数的每一位进行取反操作。
4. 按位异或运算符(XOR):用符号"^"表示,对操作数的每一位进行异或操作。
四、算术运算符1. 加法运算符(+):用符号"+"表示,对操作数进行相加操作。
2. 减法运算符(-):用符号"-"表示,对操作数进行相减操作。
3. 乘法运算符(*):用符号"*"表示,对操作数进行相乘操作。
4. 除法运算符(/):用符号"/"表示,对操作数进行相除操作。
5. 取模运算符(%):用符号"%"表示,取两个操作数相除的余数。
五、关系运算符1. 等于运算符(==):用符号"=="表示,当两个操作数相等时,结果为1,否则为0。
[转]Verilog 代码风格-供参考Description本文主要是收集一些重要的Verilog coding style。
一个好的coding style可以减少错误的发生,增加电路的效能,以及较好的可读性。
TextThe order of module signals一个module signal顺序如下(由左至右):Inputclock signals(clk_*)set/reset signals(set_*, rst_*)enable/disble signals(en_*, dis_*)read/write enable signals(we_*, re_*, rw_*)control signals(i_*)address signals(i_*)data signals(i_*)Outputclock signals(o_clk_*)set/reset signals(o_set_*, o_rst_*)enable/disable signals(o_en_*, o_dis_*)control signals(o_*)address signals(o_*)data signals(o_*)In/Outcontrol signals(io_*)address signals(io_*)data signals(io_*)Naming Rule以下的namign rule为个人使用的规则。
命名方式分类底线分隔型:xxx_yyy_zzz大写底线分隔型:XXX_YYY_ZZZ首字大写型:AbcDefGhi首字小写型:avcDefGhi各种元素所使用的命名文件名称:底线分隔型, Ex: xxx_yyy_zzz.vmodule名称:底线分隔型, Ex: xxx_yyy_zzzmodule instance名称:底线分隔型, Ex: xxx_yyy_zzzlocal wire名称:底线分隔型:Ex: xxx_yyy_zzzlocal reg名称:底线分隔型, Ex: xxx_yyy_zzzinput signal名称:前置i_的底线分隔型, Ex: i_xxx_yyy_zzzoutput signal名称:前置o_的底线分隔型, Ex: o_xxx_yyy_zzzinput/output signal名称:前置io_的底线分隔型, Ex: io_xxx_yyy_zzz常数名称:大写底线分隔型, `XXX_YYY_ZZZparameter参数名称:大写底线分隔型, Ex: XXX_YYY_ZZZblock名称:大写底线分隔型, Ex: XXX_YYY_ZZZ特殊讯号名称单一的clock signal: clk多个clock signal: clk_xxx负缘触发的clock signal: clk_n, clk_xxx_n单一的reset signal: rst多个reset signal: rst_xxx负缘触发的reset signal: rst_n , rst_xxx_n单一的set signal: set多个set signals: set_xxx负缘触发的set signals: set_n, set_xxx_n致能讯号: en_xxx除能讯号: dis_xxxProcedural Assignments使用指引在撰写sequential logic时,使用nonblocking assignment。
System verilog数据类型总结1 逻辑数据类型(logic)可替reg和wire,但是不能有多个驱动,有多个驱动的信号还是要定义成wire型2 双状态数据类型(只有0/1两个状态)无符号:bit有符号:byteshortintintlongint$sunknown操作符可检查双状态数据类型位是否出现X、Z状态,若出现,返回1例If ($sunknown(iport)==1)$display( )3 定宽数组1)声明:在数组声明中允许给出数组宽度如:int c_style[16] 等同于int c_style[15:0] //16个整数2)多维数组int array[8][4];int array [7:0][3:0];//8行4列数组array[7][3]=1 //设置最后一个元素为1从越界地址中读数,SV返回数组元素缺省值四状态类型,返回X;双状态类型,返回0;3)存放:32比特字边界存放数组元素4)非合并数组声明:bit[7:0] b_unpack[3]低位存放数据5)常量数组声明:单引号和大括号初始化数组例:int a[4] = '{0,1,2,1}; //4个元素初始化int b[5];a[0:2] = '{1,2,2}; //为前三个元素赋值b = '{5{1}}; //5个值全为1a= '{3,2,default:1} //为没有赋值元素,指定缺省值1, a='{3,2,1,1} 4 基本数组操作1)遍历数组---for /foreachforeach要指定数组名,且要用方括号中给出索引变量initial beginbit[31:0] arc[5],drc[5];for(int i=0;i<$size(src);i++)src[i]= i;foreach (drc[j])drc[j]=src[j]*2;end多维数组遍历foreach语法用[ i,j], 如int mid[2][3]='{'{1,2,3},'{3,4,5}} foreach(mid[i,j])2)比较和复制聚合比较和赋值(适用于整个数组而非单个元素)比较只有等于和不等于比较可使用?:操作符比较$display ("src[1:4] %s dst[1:4]", src[1:4]==drc[1:4]? "==":"!==");3)赋值src=drc //drc所有元素赋值给srcsrc[3]=4; //第三个元素赋值为44)同时使用数组下标和位下标如指定第一个数组的第一位和第二位:bit[31:0] src[5] = '{5{5}};$display ("src[0],, //'b101src[0][2:1] ); //'b105)合并数组连续的比特集存放,既可以当成数组,也可以当单独数据,如32比特数据,可以看成4个8比特数据合并的位和数组大小必须放在变量明前指定如bit[3:0] [7:0] byte1; //四个8比特数组成32比特byte1[2][7] //第3个字节的第8位合并/非合并混合数组(详见SV验证测试平台编写指南P26)和标量进行相互转换,建议使用合并数组,如以字节或字对存储单元进行操作,需要等待数组中变化,必须使用合并数组,如用@()等待触发,只能用标量或合并数组5 动态数组仿真过程中再分配空间或调整宽度,在声明时用空的[ ],在执行过程中使用new[]操作符分配空间,[ ] 内给定数组宽度int dyn[],d2[];initial begindyn = new[5]; //分配5个元素foreach (dyn[j]) dyn[j]=j;//对元素进行初始化d2=dyn //复制dyndyn=new[20](dyn);dyn.delete(); //删除所有元素想声明一个常数数组但不想统计元素个数,可以使用动态数组bit[7:0] mask[ ] = '{3'b101,3'011};数据类型相同,定宽数组和动态数组之间可以相互赋值6 队列结合链表和数组优点:1)可在队列任何地方添加,删除元素;动态数组需要分配新的数组并复制元素的值2)可通过索引实现访问元素;链表需要遍历目标元素之前的元素声明:[$]int j=1;q2 [$] = {3,4} , //队列常量不需要使用’q [$] = {0,2,5};initial beginq.insert(1,j); // {0,1,2,5}q.delete(1); // {0,2,5} 删除第一个元素q.push_front(6) //{6,0,2,5}q.push_back(8) //{6,0,2,5,8}q[$,2] //$放最左边,代表最小值0;$放最右边则代表最大值7 关联数组用来保存稀疏矩阵的元素,只为实际写入的元素分配空间8 数组方法数组缩减sum/product/and/or/xor 注意位宽定位方法min/max/unique/find数组排序re verse/sort/rsort/shuffle9 枚举类型10 表达式位宽可强制转换bit [7:0] b8;bit one= 1'b1;$displayb(one+one) // 1+1=0; 两个单比特变量b8=one+one;$displayb(b8); //=2,为了避免溢出造成精度受损,可使用临时变量b8$displayb(one+one+2'b0); // =2,采用哑元常数2'b0$displayb(2'(one)+one); //=2, 第一个值被强制转换。
Verilog语言是一种硬件描述语言(HDL),用于描述和设计数字电路。
它广泛应用于数字系统的建模、验证和综合,是数字电路设计领域中的重要工具之一。
在Verilog中,模块是最基本的组织单位,模块中包含了电路的功能和行为描述。
本文将介绍Verilog语言的基本语法和模块写法,以帮助读者更好地理解和应用Verilog语言。
一、Verilog基本语法1. 注释在Verilog中,使用双斜杠(//)进行单行注释,使用/* */进行多行注释。
注释可以提高代码的可读性,便于他人理解和维护。
2. 变量声明Verilog中的变量可以分为寄存器变量(reg)和线网(wire)两种类型。
寄存器变量用于存储状态信息,线网用于连接各个逻辑门的输入和输出。
3. 逻辑运算符和位运算符Verilog中包括逻辑运算符(与、或、非等)和位运算符(与、或、异或等),用于对信号进行逻辑和位级操作。
4. 控制语句Verilog支持if-else语句、case语句等控制语句,用于根据不同条件执行不同的操作。
5. 模拟时钟在Verilog中,时钟是电路中的重要部分,通常使用时钟信号来同步各个元件的动作。
时钟可以通过周期性方波信号来模拟,使用$period 函数可以定义时钟的周期。
6. 仿真指令Verilog提供了多种仿真指令,用于初始化信号、设置仿真时间、输出波形图等操作,有助于仿真和调试电路。
二、模块写法1. 模块定义在Verilog中,一个模块包含了一组功能相关的硬件描述,可以看作是一个小型电路的抽象。
模块通过module关键字进行定义,其中包括模块名、输入输出端口声明等信息。
```verilogmodule adder(input wire [3:0] a,input wire [3:0] b,output reg [4:0] c);// 模块内部逻辑描述endmodule```2. 端口声明模块的端口包括输入端口(input)和输出端口(output),可以通过wire和reg进行声明。
Verilog语句讲解一、Verilog语言简介1.1 什么是Verilog语言Verilog是一种硬件描述语言(HDL),用于描述数字电路和系统的行为和结构。
它是一种高级语言,可以用于设计和验证各种电子系统,从简单的门电路到复杂的处理器和系统芯片。
1.2 Verilog语言的特点•面向事件的建模:Verilog可以描述数字电路中的事件和信号变化,使得设计者可以更好地理解和建模系统的行为。
•层次化建模:Verilog允许设计者使用模块化的方式组织代码,从而实现对复杂系统的分层描述。
•并发性支持:Verilog支持并发执行,可以同时执行多个操作,从而提高了系统的性能和效率。
•灵活性:Verilog可以描述各种类型的电路和系统,包括数字逻辑电路、时序电路、存储器和通信接口等。
二、Verilog语句的基本结构2.1 模块定义语句在Verilog中,一个模块是由输入、输出和内部逻辑组成的。
模块定义语句用于定义一个模块的接口和行为。
module module_name(input_list, output_list);// 内部逻辑endmodule•module_name:模块的名称,用于在其他模块中引用该模块。
•input_list:输入端口列表,用于定义模块的输入信号。
•output_list:输出端口列表,用于定义模块的输出信号。
2.2 信号定义语句Verilog中使用信号来表示数据和控制信号。
信号定义语句用于定义信号的类型和宽度。
reg [width-1:0] signal_name;•reg:表示信号的类型为寄存器,可以存储数据。
•[width-1:0]:表示信号的位宽,从高位到低位。
•signal_name:信号的名称,用于在模块内部引用该信号。
2.3 时钟信号定义语句在时序电路中,时钟信号是非常重要的。
Verilog中使用时钟信号来同步和控制电路的操作。
input wire clk;•input wire:表示时钟信号是一个输入信号。
verilog case语法Verilog Case语法详解Verilog是一种硬件描述语言,用于描述数字电路和系统。
在Verilog中,Case语法是一种常用的控制结构,用于根据不同的输入值执行不同的操作。
Case语法的基本结构如下:case (expression)value1: statement1;value2: statement2;...default: statementN;endcase其中,expression是一个表达式,可以是任何Verilog数据类型。
value1、value2等是表达式的值,statement1、statement2等是与每个值相关联的语句。
default是可选的,用于指定当表达式的值与所有其他值都不匹配时要执行的语句。
Case语法的执行过程如下:1.计算表达式的值。
2.将表达式的值与每个值进行比较,直到找到匹配的值。
3.执行与匹配值相关联的语句。
4.如果没有匹配的值,则执行default语句(如果存在)。
下面是一个简单的例子,演示了如何使用Case语法:module example(input [1:0] a, output reg [3:0] b);always @ (a)begincase (a)2'b00: b = 4'b0000;2'b01: b = 4'b0001;2'b10: b = 4'b0010;2'b11: b = 4'b0011;default: b = 4'b1111;endcaseendendmodule在这个例子中,输入a是一个2位二进制数,输出b是一个4位二进制数。
根据a的值,Case语法将b设置为不同的值。
如果a的值与任何值都不匹配,则将b设置为1111。
总结Case语法是Verilog中常用的控制结构之一,用于根据不同的输入值执行不同的操作。
它的基本结构包括一个表达式、一组值和与每个值相关联的语句。
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信号。
SystemVerilog基本语法总结(中)Systemverilog 语法总结(中)上⼀个博客分享了SV基本的概念,这⼀博客继续分享,等下⼀个博客分享⼀个公司的验证的笔试题⽬。
l 事件背景:Verilog中当⼀个线程在⼀个事件上发⽣阻塞的同时,正好另⼀个线程触发了这个事件,则竞争就出现了。
如果触发线程先于阻塞线程,则触发⽆效(触发是⼀个零宽度的脉冲)。
解决⽅法:Systemverilog 引⼊了triggered()函数,⽤于检测某个事件是否已被触发过,包括正在触发。
线程可以等待这个结果,⽽不⽤在@操作符上阻塞。
例⼦:event e1,e2;Initial begin->e1;@e2;endInitial begin->e2;@e1;end上⾯的代码,假设先执⾏第⼀个块,再执⾏第⼆个块。
第⼀个块会阻塞在@e2(阻塞先执⾏),直到e2触发,再运⾏(触发后执⾏);在执⾏第⼆个块时,会阻塞在@e1,但是e1已经触发(触发先执⾏,阻塞后执⾏,触发是个零宽度的脉冲,会错过第⼀个事件⽽锁住)解决⽅法:⽤wait(e1.triggered())来代替阻塞@e1,如果先触发,也可以执⾏。
l 等待多个事件最好的办法是:采⽤线程计数器来等待多个线程。
l 旗语get()可以获取⼀个或多个钥匙,put()可以返回⼀个或多个钥匙。
try_get()获取⼀个旗语⽽不被阻塞。
l 信箱背景:如何在两个线程中传递信息?考虑发⽣器需要创建很多事物并传递给驱动器的情况。
问题:如果使⽤发⽣器的线程去调⽤驱动器的任务。
这样,发⽣器需要知道驱动器的层次化路径(类的层次化),降低了代码的可重⽤性;还迫使发⽣器和驱动器同⼀速率运⾏,当⼀个发⽣器需控制多个驱动器时会发⽣同步问题。
解决办法:把驱动器和发⽣器当成各个处理事物的对象,之间通过信道交换数据。
信道允许驱动器和发⽣器异步操作;引⼊问题:你可能倾向于仅仅使⽤⼀个共享的数据或队列,但这样,编写实现线程间的读写和阻塞代码会很困难。
verilog x,z 在综合时的理解Verilog是一种硬件描述语言,用于设计和描述数字电路的行为。
在综合过程中,x和z是两个重要的逻辑值,它们分别表示未知和高阻态。
在Verilog中,x表示未知逻辑值,即信号的状态无法确定。
当信号的输入或输出存在多个驱动时,x的值会出现。
这种情况通常发生在电路设计不完整或存在冲突的情况下。
在综合时,x的处理方式取决于具体的综合工具和设置。
综合工具可能会将x视为0或1,也可能会保留其未知状态。
与x相似,z表示高阻态,也称为高阻(high-impedance)。
高阻态是指信号的输出电平处于中间状态,既不是高电平也不是低电平,而是处于一种不确定的状态。
高阻态通常用于多驱动电路,其中多个信号源可以同时驱动同一个信号线。
在综合过程中,x和z的处理是由具体的综合工具和设置决定的。
综合工具会根据输入的Verilog代码和设置来生成等效的门级电路描述。
对于x和z,综合工具可能会将其转换为特定的逻辑门电路,以确保电路的正确性和功能。
由于综合过程的复杂性,设计者需要仔细考虑信号的驱动和逻辑关系,以避免x和z的出现。
在Verilog中,x和z的存在可能会导致设计错误和功能故障。
因此,设计者需要通过正确的设计和验证方法来避免它们的出现。
这包括使用合适的电路设计规范,进行仿真和验证,在设计过程中避免冲突和不完整的逻辑,以及正确设置综合工具和其它相关工具。
总结起来,Verilog中的x和z代表未知和高阻态,在综合过程中需要注意其存在可能导致的设计错误和功能故障。
设计者需要通过正确的设计和验证方法来避免x和z的出现,并确保电路的正确性和功能。
1. Assign 语句中赋值的变量不能定义为reg型。
2 Always块里面写的是触发信息。
3 测试模块里要包含所有的情况。
如果可以先把波形图画出来,再按照波形图写测试模块会好写些,并且能写全。
4 在进行测试模块编程时,输入定义为寄存器类型,输出定义为线性。
5 信号初始化放在initial中。
6 可以用计数来实现分频。
比如根据时钟的周期计算出记一个数所用的时间。
高电平的时间内计多少数,低电平的时间记多少数。
高低电平时间之和加起来就是周期。
再求倒数就是频率。
7 在always模块中被赋值的语句的变量应定义为reg型。
8 被测试模块的输出信号定义为wire型。
被测试模块的输入信号定义为reg型。
9 If块里面的语句如果有两句以上,要加上begin end 否则会出错。
else 里面的语句如有有两个以上,也要加上begin end。
10 If 语句中给RB赋值,要写成非阻塞赋值,RB《=0;如果写成阻塞,报错。
11 一般情况下,要有一个总体系统的复位信号,否则,由于初始状态不定,所以仿真时,第一个周期容易不准确12 Always模块里面语句是时刻赋值,意思是,比如一个上升沿作为触发信号,如果在模块里面你写f0=f1,你的意思是想把信号f1赋给f0,这是错误的,它只能将f1此刻的值赋给f013. if 可以和else不配对使用,if可以单独使用14.If else 里面可以再嵌套if elseEg if(MSL==9)beginif(MSH==9)beginMSH<=0;cn1<=1;endelseMSH<=MSH 1;endelsebeginMSL<=MSL 1;cn1<=0;end15. else if 里面仍然可以嵌套if else语句Egelse if(SL==9)beginif(SH==5)beginSH<=0;cn2<=1;endelseSH<=SH 1;endelsebeginSL<=SL 1;cn2<=0;End16. 如果问题老是出在第一行,很可能是没有写endmodule17.每个端口除了要声明是输入,输出,还是双向端口外,还要声明其数据类型是连线性还是寄存器类型。
如果没有声明,综合器默认为wire型18. 输入和双向端口不能声明为寄存器类型19.调用子模块时,里面变量的例化写法要一致。
如COUNT U2(.RB(RBB),.CLK(CLK),.EN(FD),.Q(Q)); 是正确的COUNT U2(RBB, CLK,.EN(FD), Q);是错误的。
20. reg [3:0]MSH,MSL,SH,SL,MH,ML=0;表示的是只将ML赋0,其他都没有赋0verlog语法要点:module endmodule之间由两部分构成:接口描述和逻辑功能描述IO端口种类:input output inout相同位宽的输入输出信号可以一起声明,input[3:0] a,b; 不同位宽的必须分开写内部信号为reg类型,内部信号的状态:0 1 x z,3'bx1=3'bxx1 x/z会往左扩展3'b1=3'b001 数字不往左扩展逻辑功能描述中常用assign描述组合逻辑电路,always既可以描述组合逻辑电路又可以描述时序逻辑电路,还可以用元件调用方法描述逻辑功能always之间、assign之间、实例引用之间以及它们之间都是并行执行,always内部是顺序执行常量格式:< /-><二进制位宽><'><进制><该进制的数值>:默认进制为10进制默认位宽为32位位宽是从二进制宽度角度而言的由位宽决定从低位截取二进制数2'hFF=2'b11,通常由被赋值的reg变量位宽决定parameter常用于定义延迟和变量位宽,可用常量或常量表达式定义变量种类:wire reg memoryIO信号默认为wire类型,除非指定为reg类型wire可以用作任何输入输出端口wire包括input output inoutwire不带寄存功能assign赋值语句中,被赋值的信号都是wire类型assign之所以称为连续赋值,是因为不断检测表达式的变化reg类型可以被赋值后再使用,而不是向wire一样只能输出,类似VHDL中的buffer 端口reg类型变量初始值为x (VHDL中初始值为本类型最小值,通常是0)always模块里被赋值的信号都必须定义为reg类型,因为always可以反复执行,而reg 表示信号的寄存,可以保留上次执行的值reg类型变量与integer变量不同,即使赋负值,实质上也是按二进制无符号数存储的,integer是有符号数verilog中所有内部信号都是静态变量,因为它们的值都在reg中存储起来了memory型只有一维数组,由reg型变量组成memory初始化只能按地址赋值,不能一次性赋值1*256的memory写法:reg mema[255:0] mema[3]=0;不同位宽的变量之间赋值,处理之前都以被赋值的变量位宽为准扩展或截取A[a:b] 无论a b谁大,a总是实际电路的信号高位,b总是实际电路的信号低位算术运算中如果有X值则结果为Xfor循环中的变量另外定义成integer,因为它不是实际信号,有正负;reg则以无符号数存在== 和!=只比较0、1,遇到z或x时结果都为x (x在if中算做假条件),结果可能是1、0、x===和!==比较更加苛刻,包括x和z的精确比较,结果可能是0、1&&的结果只有1'b1或1'b0两种,A&A的结果位宽则是与A相同的{1,0}为64'h100000000,所以拼接运算中各信号一定要指定位宽移位运算左移将保留4'b1000<<1等于5'b10000,右移则舍弃4'b0011等于4'b0001 数字电路里位运算应用普遍,包括按位逻辑运算、移位运算、拼接运算、缩减运算非阻塞式赋值<=与阻塞式赋值=阻塞:在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完,后面的语句被该赋值语句阻塞非阻塞:在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞<=:块结束后才能完成赋值块内所有<=语句在always块结束时刻同时赋值<=右边各变量的值是上一次时钟边沿时,这些变量当时的值用于描述可综合的时序电路=:=语句结束之后过程always才可能结束在always过程中,begin end块内按先后顺序立即赋值,在fork join内同时赋值(可能造成冲突)与assign连用描述组合电路begin end中阻塞的含义:begin ...@(A) B="C"...; end 如果A事件不发生则永远不能执行下去,被阻塞了由于时钟的延时(往往在ps级),多个always(posedge)之间究竟谁先执行是个未知数使用原则:同一个always过程块内建立时序电路用<=纯组合逻辑电路用=,生成的电路结构最简单,执行速度最快同一个always块内不要混用<=和=不要在多个always块内对同一个变量赋值(多源驱动)if else的三种形式,第三种形式适合描述优先编码器if条件中0/x/z当成假,1当成真,非0的数值也当成真case语句的三种:case(四种状态的比较) casez(忽略z) casex(忽略x和z,只看哪些位的信号有用)case语句中所有表达式值的位宽必须相等,default中不能将n'bx用'bx代替避免生成锁存器的方法:电平触发时if后加else case中加default ?使用casex会将不必要的状态视为无关项,使得综合出来的电路最简单两种特殊的括号:begin 顺序语句... end fork 并行语句... join,其差别在于块内语句的起止时间、执行顺序、相对延时块被命名后,其内部变量可以被调用,因为变量都是静态的(调用信号:对应电路中的一个信号线被引到另一处)initial块只无条件执行一次always块在满足条件时不断执行initial常用来写测试文件,always块常用来写电路描述always既可以描述组合逻辑电路又可以描述时序逻辑电路always如果后面有敏感信号列表则不能用wait语句always既可以描述电平触发又可以描述边沿触发,wait只能描述电平触发assign常用于描述组合逻辑电路测试文件中一般都是现initial 后always生成语句:生成快的本质是使用循环内的一条语句代替多条重复的verilog语句,简化了用户的编程genvar用于声明生成变量,生成变量只能用在生成快之间仿真时,仿真器会将生成块中的代码展平,在确立后的方针代码中,生成变量是不存在的最好是先想象出来循环生成语句被展平后的电路样子,再写相关的描述语句task和function的区别:task可以定义自己的仿真时间单位,function与主模块共用同一个仿真时间单位函数不能启动任务,任务能够启动函数函数至少要有一个输入变量,任务没有输入变量函数返回一个值,任务不返回值一个模块的设计包括3个部分:电路模块的设计测试模块的设计设计文档的编写设计者通过布局布线工具生成具有布线延迟的电路,再进行后仿真,得到时序分析报告从时序分析报告中可以知道电路的实际延迟t,同步电路内每个时钟周期要大于t,从而可确定该运算逻辑的最高频率综合器之所以能够实现加法器、乘法器是因为库中已经存在可配置的参数化器件模型FPGA内总线宽度容易自定义,以便实现高速数据流,三态数据总线相当于数据流的控制阀门数字系统内数据流的控制:开关(或三态数据总线)、数据暂存部件(寄存器)、同步状态机控制(整个系统在一个时钟域内)流水线操作pipe line:K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组,上一级的输出是下一级的输入流水线操作获得第一个结果的时间要比不用流水线操作的时间长,但以后结果获得时间都只需要一个时钟周期,提高了数据吞吐量流水线操作的保证:Tclk>K*(组合逻辑延迟触发器的建立保持时间/触发时间),即时间片段要长于最大路径延迟体现了面积换速度的思想,在综合时考虑的是以面积小为主还是以速度为主本质上是一种同步逻辑同步时序逻辑和异步时序逻辑:同步时序逻辑指所有寄存器组由唯一时钟触发always@(posedge clk) 或always@(negedage clk)异步时序逻辑指触发条件不唯一,任意一个条件都会引起触发always@(posedge clk or posedage reset)目前的综合器是以同步时序逻辑综合的,因为同步时序逻辑较异步时序逻辑可靠严格的同步要求时钟信号传递速度远远大于各部分的延迟,实际中clk要单独用线,而不要经过反相器等部件always @(posedge.. ) begin ...<=... end 表示同步时序逻辑(同时刻赋值)不同速率数据接口的处理方法(异步数据的处理方法):帧同步FIFO 双端口RAM同步状态机:包括moore和mealy型两种,及其反馈模型(是一种反馈控制系统,当前状态就是其内部状态变量)状态机的开发步骤:根据实际问题列出输入输出变量和状态数画出状态图并化简写出状态转移真值表得到逻辑表达式用D触发器或JK触发器构建电路(目前用D触发器多)verilog描述时只需要得到简化的状态图就可以描述状态编码方式:独热码格雷码状态机主体程序有单always描述方式和多always描述方式采用case/casez/casex建立模型最好,因为x是无关态,生成的电路最简单default: state='bx与实际情况更一致,效果等同于default: state<=idle只有同步状态机才能被目前的综合for语句会将所有变量的情况展开,占用巨量逻辑资源,替代办法是用计数器和case语句说明所有情况有优先级的if else结构会消耗更多资源,建议用无优先级的case替代模块的复用往往比代码上修改节省的资源多PLL的分频、倍频、移相操作会增加设计精度同步时序电路的延时:#x通常用于仿真测试,实际硬件延时是:长延迟用计数器,小延迟用D触发器,此方法用来取代延迟链同步电路中,稳定的数据采用必须满足采样寄存器的建立和保持时间reg类型在always中不一定综合成时序电路,也可能是组合逻辑电路乒乓操作与作用异步时钟域同步问题延迟包括门延迟和线延迟组合逻辑产生的时钟仅能应用在时钟频率较低、精度要求不高的情况下增减敏感信号得到的结果一样补充部分:verilog HDL起初是作为写testbench而产生的verilog 有1995进入IEEE标准,为IEEE-1364, 于2001年进行了扩展,为IEEE 1364-2001;verilog AMS可用于模拟电路和数字电路的综合,目前正在不断发展和完善中;verilog的标识符区分大小写,关键字使用小写;用\\来进行单行注释,用\* *\来进行跨行注释;标识符由字母、数字、下划线构成,并以字母开头;关键字又叫保留字,只有小写的关键字才是保留字;信号的状态有4种:0 1 x zx和z在描述电路时不区分大小写,在仿真时大小写有不同意义;常量表达式中:x z不区分大小写;进制符号h o d b与H O D B不区分大小写;十六进制中a~f不区分大小写;下划线_用于提高可读性;?在数中可以代替z;x和z的左端补位;字符和字符串都以ASICII码形式存在,也可以当成电路内的信号;字符串必须包含在同一行,不能分成多行书写;如果表达式或者赋值语句中将字符串当成操作数,则字符串中的每个字符都被看成8位的ASCII值序列;可综合的信号类型:wire reg memory 它们用来描述数字电路不可综合的数据类型:integer real 它们只用仿真,位于testbench中wire是连线的抽象模型,不能保存数据,其值由驱动元的值决定;wire不能用在always或initial块中;wire的默认值为高阻z;wire的使用情形:1.作为模块的输出端口 2.用连续赋值语句assign赋值;reg是1位寄存器(触发器)的抽象模型,可以保存数据;reg必须用在always或initial块中;reg的默认值为x;reg的使用情形:1.阻塞赋值<= 2.非阻塞赋值=memory只能是一维的;memory只能对每个单元分别初始化,方法:1.一个一个赋值 2. 通过系统任务$readmem 赋值reg[3:0] fc;//一个4位寄存器reg fc[3:0] //4个一位寄存器parameter的作用:仿真开始以前对其进行赋值,整个仿真过程中保持其值不变;关系运算符将以逻辑1或逻辑0返回比较的结果;== !=的返回值有0 1 x三种情况,=== !==的返回值只有0 1两种情况;verilog由于是描述电路的,用于位的操作较多,有: 位逻辑操作,移位操作,并置操作,归约操作;位逻辑运算的结果中,位数与原操作数一样多;归约符是在原操作数的所有位上进行操作,并产生1位结果;并置运算可以发生在bit与bit之间bit与矢量之间矢量与矢量之间用于仿真的系统任务:所有系统任务都必须在initial或always内;所有系统任务都必须以$开头;常见系统任务:显示任务($diplay系列和$write系列)监控任务($monitor系列)探测任务($strobe系列)文件打开、输入、关闭任务(&fopen &fclose &fdisplay...)读取文件任务($readmemb $readmemh)仿真结束控制任务($finish $stop)随即信号任务($random)过程块:initial块和always块一个module内可以包含多个initial或always模块;所有initial或always块在0时刻开始并行执行,各initial或always块内部顺序执行;initial过程块主要是面向testbench的,通常不具有可综合性;always过程块在描述电路时既可以描述组合逻辑电路(电平敏感)又可以描述时序逻辑电路(边沿敏感);写testbench时initial通常用于初始化以及顺序波形的描述,always通常用于重复波形的描述;任务task与函数function: 为了描述模块中被多次执行的部分以及为了增强代码的易读性verilog中的高级程序语句如for循环语句只用在写testbench中;begin end和fork join是两种特殊的括号if语句的第三种形式适合描述优先编码器,case语句适合描述数据选择器和状态机;case的条件表达式如果与分支项表达式长度不同,则在比较前将所有表达式都统一为这些表达式的最长长度;casez忽略z,casex忽略z和x;assign语句只在右端表达式发生变化时才重新计算并重新赋值,其余时间都是连续赋值;assign语句可以指定bit、vector或是任意拼接操作的结果;assign语句是连续赋值的,用于驱动网线wire,reg类型不需要连续赋值,reg类型一旦被赋值就会一直保存;过程赋值语句有两种:阻塞式=和非阻塞式<=,只能在过程块initial和always中使用;@对事件触发的控制与wait语句不能同时使用;。