可综合的Verilog语法子集总汇
systemverilog 可综合 语法
systemverilog 可综合语法-概述说明以及解释1.引言1.1 概述SystemVerilog是一种硬件描述语言,其可综合语法用于描述硬件设计的行为和结构。
可综合语法是指在编写SystemVerilog代码时,能够被综合工具翻译成底层硬件电路,并最终映射到FPGA或ASIC等可编程器件上的语法规则和风格。
因此,可综合语法在硬件设计中起着至关重要的作用。
在硬件设计中,可综合语法使设计工程师能够通过代码描述硬件的功能和结构,包括处理器、逻辑电路、存储器等。
通过使用可综合语法,设计工程师可以更加灵活地实现各种功能和性能要求,同时也能提高设计的可维护性和可重用性。
SystemVerilog的可综合语法特点是其结构化的设计风格,丰富的数据类型和内置的高级语言功能。
与传统的硬件描述语言相比,SystemVerilog提供了更多的抽象层次和编程特性,可以更高效地完成复杂的硬件设计任务。
例如,SystemVerilog支持面向对象的设计方法,可以使用类和对象对设计进行建模和封装。
此外,SystemVerilog还提供了多种数据类型和运算符,使设计工程师可以更方便地处理各种数据和信号。
综上所述,可综合语法在SystemVerilog中具有重要的地位和作用。
通过使用可综合语法,设计工程师能够更加方便地描述和实现各种硬件功能,提高设计的效率和可靠性。
在今后的硬件设计中,可综合语法的应用将更加广泛,并且不断发展和完善,以满足不断变化的设计需求。
1.2 文章结构文章结构部分的内容可以包括以下内容:文章结构的目的是为了给读者提供清晰的导航和理解文章的逻辑框架。
通过合理的结构,读者可以更好地理解文章的目的和内容,并能够有序地阅读和理解整个文档。
本文的结构如下:第一部分是引言部分,用于介绍文章的背景和相关信息。
在引言部分,我们将概述SystemVerilog可综合语法的定义和作用,并介绍本文的结构和目的。
第二部分是正文部分,主要内容是关于SystemVerilog可综合语法的定义和特点。
第三章 Verilog HDL的基本语法汇总
512个单元,每个单元为32位
3.3 Verilog HDL的运算符
算术运算符 逻辑运算符 关系运算符 等值运算符 位运算符 缩减运算符 移位运算符 条件运算符 拼接运算符
1.算术运算符
算术运算符包括: + (加法运算符或正值运算符,如x+y,+8) - (减法运算符或负值运算符,如x-y,-90) * (乘法运算符,如x*y) / (除法运算符,如x/y) % (取模运算符,如x % y)
1.间隔符: Verilog 的间隔符主要起分隔文本的作用,可以使 文本错落有致,便于阅读与修改。
间隔符包括空格符(\b)、TAB 键(\t)、换行符(\n)及 换页符。
2.注释符:注释只是为了改善程序的可读性,在编译时不起作用。 多行注释符(用于写多行注释): /* --- */; 单行注释符 :以//开始到行尾结束为注释文字。
3.标识符和关键词
标识符:给对象(如模块名、电路的输入与输出端口、变
量等)取名所用的字符串。以英文字母或下划线开始
如,clk、counter8、_net、bus_A 。
关键词:是Verilog语言本身规定的特殊字符串,用来定义 语言的结构。例如,module、endmodule、input、 output、wire、reg、and等都是关键词。关键词都是小 写,关键词不能作为标识符使用 。出始终根据输入的变化而 更新其值的变量,它一般指的是硬件电路中的各种物理 连接.
例:网络型变量L的值由与门的驱动信号 a和b所决定,即L=a&b。a、b的值发 生变化,线网L的值会立即跟着变化。
a
&L
Verilog可综合与不可综合语句汇总
1)所有综合工具都支持的结构:always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter。
(2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait。
(3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。
建立可综合模型的原则要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:(1)不使用initial。
(2)不使用#10。
(3)不使用循环次数不确定的循环语句,如forever、while等。
(4)不使用用户自定义原语(UDP元件)。
(5)尽量使用同步方式设计电路。
(6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
(7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。
(8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
(9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。
对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。
但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。
(10)不能在一个以上的always过程块中对同一个变量赋值。
可综合的verilog语句
可综合的verilog语句(原创版)目录1.Verilog 语言概述2.Verilog 语句的分类3.可综合的 Verilog 语句4.应用举例正文1.Verilog 语言概述Verilog 是一种硬件描述语言,主要用于数字系统硬件的描述、模拟和验证。
它最初由 Phil Moorby 在 1983 年开发,后来由 Cadence 公司进行商业化推广。
Verilog 具有易学易用、功能强大的特点,广泛应用于集成电路设计、计算机体系结构、数字信号处理等领域。
2.Verilog 语句的分类Verilog 语句主要分为两大类:行为描述语句(Behavioral Description)和结构描述语句(Structure Description)。
行为描述语句主要用于描述数字电路的功能和行为,包括 always 语句、initial 语句等;结构描述语句主要用于描述数字电路的物理结构,包括 module 语句、wire 语句等。
3.可综合的 Verilog 语句可综合的 Verilog 语句是指在数字集成电路设计中,可以被合成器(Synthesizer)转换为实际硬件电路的 Verilog 语句。
这类语句主要包括以下几类:(1)简单的逻辑门和寄存器:如与门、或门、非门、与非门、或非门、异或门等,以及触发器、计数器、寄存器等。
(2)各种运算和操作:如算术运算(加、减、乘、除等)、关系运算(大于、小于、等于、不等于等)、位运算(按位与、按位或、按位异或、取反等)、移位运算等。
(3)控制结构:如 if-else 语句、case 语句、for 循环、while 循环等。
(4)其他:如声明、实例化、端口定义、模块调用等。
4.应用举例以下是一个可综合的 Verilog 语句示例,用于实现一个 4 位全加器的功能:```verilogmodule full_adder(input a, input b, input cin, output sum, output cout);assign sum = a ^ b ^ cin; // 异或运算实现和assign cout = (a & b) | (a & cin) | (b & cin); // 与、或运算实现进位endmodule```在这个例子中,我们声明了一个名为 full_adder 的模块,包含两个输入端口 a、b,一个输入端口 cin,以及两个输出端口 sum 和 cout。
常用VerilogHDL 语法总结
常用VerilogHDL 语法总结1 模块(1)端口定义:声明模块的输入输出口。
引用模块时端口的两种连接方法。
(2)模块内容:I/O说明(输入输出)、内部信号说明(和端口有关的变量说明)、功能定义(定义逻辑功能的三种方式:assign 声明语句;实例元件;always 块)。
(3)理解要点:整体语句并发执行,always块内顺序执行。
2 常量(1)数字:整数及三种表达方式x和z值负数:减号的位置下划线:位置和作用(2)参数:parameter符号常量,常用于定义延迟时间(使用#)和变量宽度。
3 变量(1)wire:表示易assign指定的组合逻辑信号;默认值;任何方程式的输入或assign语句及实例元件的输出;定义格式。
(2)reg:表示always块中指定的信号,代表触发器;寄存器数据类型(触发器存储值),默认值为x;定义格式。
(3)memory:reg的数组;描述RAM、ROM、reg文件;单元索引;一个n为寄存器和n个一位数组的区别。
4 运算符与表达式(1)算术运算符:五种(2)位运算符:五种(3)逻辑运算符:三种(4)关系运算符:四种(3种不同的返回值)(5)等式运算符:四种(6)移位运算符:两种(移位补零)(7)位拼接运算符:{},常用于某些控制信号位;重复与嵌套使用(8)缩减运算符:类似于逻辑运算符,结果为一位二进制数(9)运算符优先级5 语句(1)赋值语句阻塞赋值:b<=a;块结束后完成赋值,b的值不是立即改变的,较为常用;非阻塞赋值:b=a;赋值语句执行后块才结束,b的值马上改变,在沿触发的always块中使用可能引起错误后果。
(2)块语句顺序块begin-end:顺序执行,最后语句执行完流程跳出语句块;并行块fork-join:同时执行,时间最长语句执行完或disable语句执行时跳出程序块;块名的作用;起始时间和结束时间(3)条件语句If-else语句:三种形式;if表达式判断;分号;复合语句;表达式简写;if语句嵌套;if与else的配对。
Verilog语法知识点总结(转)
Verilog语法知识点总结(转)1.1 概述条⽬说明分类1>> ⾯向设计的语句; // 可综合。
2>> ⾯向测试的语句; //testbench ,不可综合。
特点设计语句 assign , always ,模块例化,都对应实际电路,并⾏执⾏。
构造1.2 模块 Module条⽬说明模块名(端⼝列表)整个电路的外特性,抽象为⿊盒⼦;端⼝⽅向input , output ; inout ;端⼝类型wire , reg ;端⼝类型是 wire 时可以省略。
例: input a ; // 端⼝⽅向为输⼊,类型默认为 wire ;1.3 数据类型1.3.1 wire/reg 线⽹wire 和 reg 都是线类型,⼯程上没区别;只是 always/initial 模块中输出定义需要为 reg 型;注意:不要将 reg 类型与 D 触发器混淆, reg 理解为因为代码所产⽣的。
例如:wire [7:0] a; // 定义了 8 位的 wire 型数据wireb; // 定义了 1 位的 wire 型数据reg [3:0]sum ; // 定义了⼀个 4 位的 reg 型数据1.3.2 常量类型格式说明parameter parameter 数据名 = 表达式parameterMSB = 7 ;// 定义参数 MSB 为常量 7 ;推荐⼤写;常量< 位宽 >< 进制 >< 数字 >⼆进制: B 或 b ;⼗进制: D 或 d ;⼋进制: O 或 o ;⼗六进制: H 或 h ;8’b1010_1100 (‘b 表⽰⼆进制 )下画线“ _”, 提⾼阅读性。
< 数字 >默认⼗进制;4 值逻辑0 : Logic Low低电平;1 : Logic High⾼电平;x : Unknow ;不确定;z : High Impedance ;⾼阻态; // 三态门1.4 运算符1.4.1 概述运算符说明算术运算符+ ( 加 ) , - (减), * (乘), / (除), % (取模);每个运算符在电路中都是个模块,如加法器,减法器;!注意:除法,除 2^n ,是移位运算,浮点运算就复杂了,因此浮点运算要专⽤除法器;关系运算符>, <, >=, <= , == (相等),! = (不相等);逻辑运算符&& (逻辑与) . || (逻辑或) , ! (逻辑⾮);条件判断语句中,为避免歧义,逻辑运算符⼆边推荐为 1bit ;位运算符& (与), | (或), ~ (⾮) , ^ (异或) ; ~^ (同或);移位运算符<< (左移), >> (右移);归约操作& , ~& , | , ~| , ^, ~^;//unary reduction ;条件运算符?:拼接运算符{}//{3{a[0]}}: 代表 3 根同样的 a[0] 线, {a[0],a[0],a[0]} 1.5 设计语句1.5.1 assign (连续赋值)实例说明assigny = ~ b ;assign out = a==1 && c==1 ;assign f =sel ? a : b ;>> 实现可以⽤布尔函数描述的组合逻辑电路;>>“=” 后⾯可以是任何布尔函数;>> 并⾏执⾏;典型错误 1 :assigna = b + a;避免出现反馈电路:变为了不可知时序逻辑电路;1.5.2 always (过程块)a、赋值赋值⽅式说明= ,阻塞赋值always @ ( a or b or C or … )begin语句块( = , if 语句, case 语句)end实现:组合逻辑电路;(注意!禁⽌⽤于时序逻辑电路)always 块内,阻塞赋值:是顺序执⾏(类似 C );敏感表: @ ( * ) //“*” ⾃动添加相关输⼊信号;敏感表: @ ( * ) //“*” ⾃动添加相关输⼊信号;避免出现 Latch (锁存器)分⽀语句( if 语句, case 语句)条件不满时,会在电路中⾃动⽣成锁存器来保存不满⾜条件的值,因此要补全 if-else ,和 case 的 defalut 语句;<= ,⾮阻塞赋值always @ ( posedge clk or negedge rst_n )begin语句块( <= , if 语句, case 语句)end实现:时序逻辑电路;(注意!禁⽌⽤于组合逻辑电路)always 块内,阻塞赋值:并⾏执⾏;b、if 语句条⽬说明格式 1if( 条件 )begin 语句 1;语句 2 ;endelse begin语句 1 ;语句 2 ;end格式 2if( 条件 )begin 语句 1;语句 2 ;endelse if begin 语句 1 ;语句 2 ;endelse begin语句 1 ;语句 2end特点分⽀语句,各个分⽀条件不同;顺序执⾏判断;注意if-else 成对使⽤;c、case 语句条⽬说明格式case( 表达式 )常量表达式 1:begin 语句;end常量表达式 2:begin 语句;end常量表达式 3:begin 语句;enddefault :语句;endcase特点分⽀语句,各个分⽀条件相同;并⾏执⾏判断;注意default 语句不可省略;d、代码 & 硬件条⽬说明映射赋值语句 -> 逻辑函数; // 加法器,减法器等;边沿型条件分⽀ -> D 触发器;条件分⽀ -> 多路选择器;⽰例1.5.3 模块例化a、作⽤系统设计时,建议遵循以下设计原则:b、常见的典型错误如下所⽰:1.5.4 全加器全加器顶层: w1 , w2 , w3 :模块之间连线;半加强: 2 种描述⽅法,如下:描述⽅式描述⽅式说明位置关联AND u1(a, b, and_out);名字关联AND u1(.a(a), .b(b), .o ( and_out ) ); // 推荐使⽤1.6 测试语句1.6.1 结构Testbench1.6.2 特殊符号语句说明`< 标识符 >表⽰:编译引导语,⽤于指导仿真编译器在编译时采取⼀些特殊处理;编译引导语句⼀直保持有效,直到被取消或重写;`timescale `timescale < 时间单位 >/< 时间精度 >例 1 :`timescale 1ns/1ns // 时间单位 1ns ;时间精度 1ns ;#2 // 延时 2 ×1=2ns ;#2.1// 延时 2.1 × 1 = 2.1ns, 精确到 1ns ,为 2ns ;例 2 :`timescale 1ns/100ps // 时间单位 1ns ;时间精度 100ps ;#2 // 延时 2 ×1= 2ns ;#2.1// 延时 2.1 × 1 = 2.1ns, 精确到 100s ,为 2.1ns ;`define`include`include “global.v”包含另⼀个⽂件,完整拷贝过来;`restall把所有设置的编译引导恢复到缺省状态;#<num>;#10; // 延迟 10 个时间单位1.6.3 语句语句说明initial 块语句:只执⾏⼀次, always 循环执⾏;不可综合;作⽤:initial产⽣激励信号;检查输出波形;赋初值;forever // 产⽣周期信号:intial beginclk = 0 ;forever#10 clk = ~clk; // 时钟信号end1.6.4 系统任务和函数条⽬说明$< 标识符 >表⽰ Verilg 的系统任务和函数$time当前的仿真时间$display 显⽰信号值变化:只执⾏⼀次,打印当前时刻;$display($time, “b% %b %b” , rst,clk,dout);$monitor 监视信号值变化:所有过程时刻;$monitor($time, “b% %b %b” , rst,clk,dout);$stop暂停仿真$finish结束仿真,释放电脑资源;1.7 代码模板1.7.1 组合逻辑电路条⽬说明assign assign add_cnt = flag==1; // ⽤于简单的组合逻辑电路;always always @(*)begin// 统⼀采⽤“ *” 为敏感列表;( =,if,case )语句; // 只能使⽤“ =” 赋值end1.7.2 时序逻辑电路a、计数器模板 13 段式模板模板 1always @( posedge cllk or negedge rst_n) begin1计数段always @( posedge cllk or negedge rst_n) begin if (!rst_n)cnt <= 0; // 初值规定为 0else if (add_cnt)begin// 【位置 1 】if(end_cnt)cnt <= 0;elsecnt <= cnt + 1;endend2加 1 条件assingadd_cnt = d==1; //d==1 :什么时候开始数脉冲3结束条件assing end_cnt = add_cnt&& cnt == X-1; // X: 数多少个脉冲b、计数器模板 23 段式模板模板 11计数段always @( posedge cllk or negedge rst_n) begin if (!rst_n)cnt <= 0; // 初值规定为 0else if (add_cnt) begin// 【位置 1 】if(end_cnt)cnt <= 0;elsecnt <= cnt + 1;endelsecnt <= 0; // 不连续,需要清 0 时,使⽤模板 2 ;end2加 1 条件assingadd_cnt = d==1; //d==1 :什么时候开始数脉冲3结束条件assing end_cnt = add_cnt&& cnt == X-1; // X: 数多少个脉冲c、 4 段式状态机模板段号代码// 初始化,次态赋值给现态,明确当前状态;1always @(posedge clk or negedge rst_n) begin if(!rst_n)state_c <= S00;// 初始状态elsestate_c <= state_n;end2always @( * ) begin // 组合逻辑,描述状态转换⽬标case(state_c)S00: beginif(s00_s20_start) // 条件名 S00->S20state_n = S20;elsestate_n = state_c; // ⽅便拷贝endS20: beginif(s20_s21_start)state_n = S21;elsestate_n = state_c;endS21: beginif(s21_s00_start)state_n = S00;elsestate_n = state_c;enddefault: beginstate_n = S00;endendcaseend3// 具体的转换条件内容assign s00_s20_start = state_c==S00&& ( 条件 ) ;assign s20_s21_start = state_c==S20&& ( 条件 ); assign s21_s20_start = state_c==S21&& ( 条件 );4根据转态设计输出:1 个 always 设计 1 个输出信号;1.7.3 Testbencha、框架条⽬内容模块名`timescale 1 ns/1 nsmodule testbench_name();信号定义reg clk ; // 时钟reg rst_n; // 复位reg[3:0] din0 ; //uut 的输⼊信号,定义为 reg 型,在 initial 中reg din1 ;wire dout0;//uut 的输出信号,定义为 wire 型wire[4:0] dout1;parameter CYCLE = 20; // 参数定义,⽅便修改;parameter RST_TIME = 3 ;待测模块例化module_name uut( // 统⼀采⽤名字关联.clk ( clk ),.rst_n ( rst_n ),.din0 ( din0 ),.din1 ( din1 ),.dout0 ( dout0 ),.dout1 ( dout1 ));激励产⽣// 复位,时钟,等显⽰输出结果$display // 类似 printf ;b、复位复位initial beginrst_n = 1;#2;rst_n = 0;#(CYCLE*RST_TIME);rst_n = 1;endc、仿真时钟仿真时钟initial beginclk = 0;forever#(CYCLE/2)clk=~clk;endd、激励信号激励信号initial begin#1;// ⽅便观测din1 = 0; // 赋初值#(10*CYCLE);// 开始赋值end以上就是总结的 Verilog 语法相关知识点,转⾃明德扬论坛。
verilog可综合语句
②若if和else后面有多个操作语句 ………
则用begin_end封装。 else
③允许一定形式的简写。如: if(表达式 m)
if(!aa)等同于if(aa!=1)。 语句m;
and: 与门。
nand: 与非门。
or: 或门。
nor: 或非门。
xor: 异或门。
xnor: 异或非门。
buf: 缓冲器。
not: 非门。
语句;
注释:①先求解表达式1。
②在求解表达式2的值,其值为真,则执行for语句指定的内嵌语句,然后执行下面的第③步;为假,则结束循环,转到第⑤步。
③若表达式2为真,在执行指定的语句后,求解表达式3。
④转回第二步继续执行。
module:模块的端口定义。用法:module 模块名(输入和输出口名);
…………………
endmodule
parameter:用来定义一个标识符代表一个常数。用法:parameter 参数名=常量表达式;
作用:常用于定义延迟时间和变量宽度。
⑤执行for下面的语句。
always:在仿真过程中是不断执行的。常用于描述时序行为。
用法:沿触发—— always @(posedge ×× or negedge××)
begin
………
end
电平触发—— always @(×or×or×)
wire:表示单个门驱动或连续赋值语句驱动的网络型数据。用法:wire[n-1:0] 数据名1,数据名2,……数据名i;
reg:寄存器数据类型,常用来表示“always”模块内的指定信号,常代表触发器。用法:reg[n-1:0] 数据名1,数据名2,……数据名i;
verilog之可综合与不可综合
verilog之可综合与不可综合可综合的意思是说所编写的代码可以对应成详细的,不行综合就是所写代码没有对应的电路结构,例如行为级语法就是一种不行综合的代码,通常用于写测试文件。
建立可综合模型时,需注重以下几点:不用法initial不用法10之类的延时语句不用法循环次数不确定的循环语句,如forever,while等不用法用户自定义原语(UDP元件)尽量用法同步方式设计电路用always块来描述组合规律时,应列出全部输入信号作为敏感信号列表,即always@(*)全部的内部寄存器都应当能够被复位,在用法实现设计时,尽量用法器件的全局复位端作为系统的总复位对时序规律描述和建模,尽量用法非堵塞赋值的方式,对组合规律描述和建模,虽然堵塞和非堵塞赋值的方式都可以,但在同一过程快中最好不要同时用法堵塞赋值和非堵塞赋值。
我个人比较推举用堵塞赋值的方式描述组合规律不能在多个always块中对同一个变量举行赋值。
对同一个对象不能既用法非堵塞赋值,又用法堵塞赋值假如不决定让变量生成锁存器,那么必需在用法if语句或case语句时补全全部条件不行综合语句:initial 初始化语句,只能在testbench中用法,不行综合event event在同步testbench时更实用,不能综合real 不支持real数据类型的综合time 不支持time数据类型的综合assign 和 deassign 不支持对reg数据类型赋值的综合,但支持wire类型赋值的综合以开始的延时语句不能被综合verilog是一种硬件描述语言,我们在写verilog 代码时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何说明这个module。
比如在打算是否用法 reg 定义时,要问问自己物理上是不是真正存在这个 register, 假如是,它的clock 是什么? D 端是什么?Q 端是什么?有没有清零和置位?同步还是异步?再比如上面研究的三态输出问题,首先想到的应当是在 register 的输出后面加一个三态门,而不是如何才干让编译器知道要“赋值”给一个信号为三态。
verilog综合心得
综合:不可综合的运算符:= = = ,!= =,/(除法),%(取余数)。
1、不使用初始化语句。
2、不使用带有延时的描述。
3、不使用循环次数不确定的循环语句,如:forever、while等。
4、尽量采用同步方式设计电路。
5、除非是关键路径的设计,一般不调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
6、用always过程块描述组合逻辑,应在信号敏感列表中列出所有的输入信号。
7、所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
8、在verilog模块中,任务(task)通常被综合成组合逻辑的形式,每个函数(function)在调用时通常也被综合为一个独立的组合电路模块。
9、用户自定义原语(UDP)是不可综合的,它只能用来建立门级元件的仿真模型。
移位运算符:Verilog HDL提供向右(>>)及向左(<<)两种运算符,运算符高位或地位一旦移出即予丢弃,其空缺的位则予以补零。
连续赋值语句(assign)、case语句、if…else语句都是可以综合的initial 语句内若包含有多个语句时,必须以begin end 作聚合;单一的初值赋值,因此并不需以begin end做聚合。
循环(Loops)并不能单独地在程序中存在,而必须在initial和always块中才能使用。
initial过程块中的语句仅执行一次,而always块中的语句是不断重复执行的。
编写顶层模块的注意事项每个端口除了要声明是输入、输出还是双向外,还要声明其数据类型,是连线型(wire)还是寄存器型(reg),如果没有声明则综合器默认为wire型。
1、输入和双向端口不能声明为寄存器型。
2、在测试模块中不需要定义端口。
编写testbentch所归纳的心得module 模块名称;将input 定义为reg;将output定义为wire;引用欲测试的module 别名initial begin设定reg 初始值endalways处理变化值endmodule在always 、initial 过程块内,被赋值的每一个信号都必须定义成寄存器型。
Verilog基础语法总结
Verilog基础语法总结去年⼩学期写的,push到博客上好了Verilog 的基本声明类型wire w1; // 线路类型reg [-3:4] r1; // ⼋位寄存器integer mem[0:2047]; // 2048 个整数的阵列reg [31:0] cache[0:63]; // 32 位数据的64个存储单元//通常称为内存或记忆体//更多阵列类型的声明reg [7:0] array [0:1023];reg [7:0] array [0:1023][0:511];module⾥的声明类型parameter 参数声明port 脚位声明基本语法`define 常数名数字//定义⼀个宏常量,引⽤⽅法是:`常数名//其中数字的格式为:x’(b/h/d)x位数//b是⼆进制,h是16进制,d是10进制#10 <item>//经过10个时延单位执⾏后⾯的程式`timescale 1ns/10ns//定义时延单位`include”<name>.v”//将⼯作⽬录下的该⽂件的内容扩充到本⽂件中//注意是⼯作⽬录,include其他路径下的⽂件是不⾏的module <模组名>(参数列表);endmodule//声明⼀个模块assign//主要⽤来描述组合逻辑//与always语句块相⽐较不必强制使等号左边的数必须为寄存器类型//等号左边可以是wire或reg或output//两种 Assign :Blocking v.s. Nonblocking//a = b ; // Blocking assignment : 执⾏顺序不⼀定,//a <= b; // Nonblocking assignment : 所有可同时执⾏的东西都执⾏完⼀次后,才会前进到下//⼀个时间点。
Always//声明⼀个语句块//⽤法⼀ always #时延语句//⽤法⼆ always @(posedge clk)//当clk信号处于上升沿的时候要执⾏的语句块//这⾥posedge代表信号的上升沿//negedge代表信号的下降沿举例说明阻塞式赋值(Blocking)与⾮阻塞式(Non-Blocking)赋值的区别下⾯是阻塞式赋值的例⼦reg d1, d2, d3, d4;always @(posedge clk) d2 = d1;always @(posedge clk) d3 = d2;always @(posedge clk) d4 = d3;由于这是⼀门硬件描述语⾔,语句的声明顺序与执⾏顺序⽆关,这样的写法我们是⽆法得知这三条语句的执⾏顺序的,所以,d2,d3,d4的结果都将是不固定的下⾯是⾮阻塞式赋值的例⼦reg d1, d2, d3, d4;always @(posedge clk) d2 <= d1;always @(posedge clk) d3 <= d2;always @(posedge clk) d4 <= d3;因为可以同时执⾏的事件都执⾏完⼀次之后才会执⾏下⼀时间点的事件,所以d2,d3,d4会得到上⼀轮的d1,d2,d3下⾯仍然是⼀个阻塞式赋值的例⼦a = 1;b = a;c = b;执⾏结果相当于a=1,b=1,c=1;下⾯是⼀个⾮阻塞式赋值的例⼦a <= 1;b <= a;c <= b;执⾏结果相当于a=1;b=上⼀轮a的值;c=上⼀轮b的值//initial语句块:常⽤于testbench实时赋值initialbegin// 程序end//当模拟⼀开始会被执⾏//到end会结束系统函数与常量$readmemh("cpu0s.hex", m);将对应的⽂件写到m这个阵列⾥⾯$time是显⽰执⾏时间的常量,其单位是ns$display(“printf的格式控制符”,输出参数列表); $monitor的语法完全类似verilog中所有变量都是全局变量,例如module top;integer myglobalvar;endmodulemodule any;initial $display(top.myglobalvar);Endmodule关于模组内模块的合法性说明module <module name> (<port list>);<declares><module items>endmodule其中的 <module items> 可能是以下类型的语句:1. initial2. always3. assign4. module 实例基本语句说明-分⽀语句1.简易分⽀f = sel ? a : b; // 右邊的任何改變都會引發左邊的重新計算2.IF分⽀if (s == 1'b0)y = 0;elsey = 1;if (select == 1) y = a;else y = b;3.case分⽀case ({a,b})2'b00: t = 1;2'b11: t = 4;default: t = 0;endcasecase (op)2'b00: y = a + b;2'b01: y = a - b;2'b10: y = a ˆ b;default: y = ’hxxxx;endcase4.casez : 将z当做⽆关项处理casez (f)2'b00: y=a+b;2'b01: y=a-b;2'b10: y=a&b;2'b11: y=a^b;default: y=0;Endcase语句说明-循环语句1.forfor (i=0; i<16; i=i+1)m[i] = i;reg [3:0] i, output;for ( i = 0 ; i <= 15 ; i = i + 1 ) begin output = i;#10;End2.whilei=0while (i<16) beginm[i] = i;i = i + 1;endreg [3:0] i, output;i = 0;while (i <= 15) beginend运算式与反运算符运算符:~代表取反位运算,!代表取⾮,^代表异或,+,-合并运算:reg [2:0] a;reg [4:0] b;{a, b} = 8'b10011110 // 此时会把100给a,111110给breg [15:0] c;c = {a, b, {2{a}}, 2'b11} // 此时 c 会是 {a, b, a, a, 11} 衔接后的结果。
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语言的可综合性
V e r i l o g 语言的可综合性可综合的Verilog HDL 语句都是V e r i l o g H D L 标准( I E E E 1 3 6 4 ) 的一个子集,并且因所用工具不同而异。
在设计中不能采用不可综合的语句( 测试代码除外) 。
下面我们讨论一下大部分综合工具都支持的语句,具体到某种工具的特性还要查看说明文档。
对于数据类型、运算符、赋值语句、基本门级元件等的可综合性问题,因为都有固定的规定,这里就不多讨论了。
组合逻辑和时序逻辑的可综合性: 用a s s i g n 语句对w i r e 型变量进行赋值,综合后的结果是组合逻辑电路。
用a l w a y s @ ( 电平敏感变量表) ,即电平敏感的a l w a y s 块描述的电路综合后的结果是组合逻辑电路或电平敏感的锁存器,此时,a l w a y s 块内赋值语句左边的变量是r e g或i n t e g e r 型,块中要避免组合反馈回路,每次执行a l w a y s 块时,在生成组合逻辑的a l w a y s 块中被赋值的所有信号必须都在敏感电平列表中列出,否则在综合时将会为没有列出的信号隐含的产生一个透明的锁存器,这时综合后的电路已不是纯组合电路了。
用a l w a y s @( p o s e d g e c l o c k ) 或a l w a y s @ ( n e g e d g e c l o c k ) 块描述的电路综合为同步时序逻辑电路,设计同步时序逻辑电路的关键是建立描述该电路状态转移的可综合的有限状态机模型,在V e r i l o g H D L语言中最常用的描述同步时序状态机的结构是a l w a y s 和块内的c a s e . i f 语句,除了紧跟在a l w a y s 后的@( p o s e d g e c l o c k ) , @ ( n e g e d g e c l o c k ) 外,a l w a y s 块中不允许其他的@ ( e v e n t ) 语句,目前大多数综合工具不能综合V e r i l o g H D L描述的异步状态机,所以用V e r i l o g 设计的时序电路应该是同步时序电路。
可综合的verilog语句
可综合的verilog语句摘要:一、引言1.Verilog 简介2.Verilog 语句的可综合性二、可综合的Verilog 语句1.基本赋值语句2.组合逻辑实现3.时序逻辑实现4.实例化模块三、Verilog 语句的可综合性分析1.基本赋值语句的可综合性2.组合逻辑实现的可综合性3.时序逻辑实现的可综合性4.实例化模块的可综合性四、提高Verilog 代码可综合性的方法1.遵循可综合编程规范2.使用可综合的语法结构3.模块划分与层次设计五、总结1.Verilog 语句可综合性的重要性2.提高代码可综合性的实际应用价值正文:【引言】Verilog 是一种广泛应用于数字电路设计和验证的硬件描述语言。
在Verilog 中,语句的可综合性指的是能否将Verilog 代码转换为实际硬件电路。
了解可综合的Verilog 语句对于编写高效的硬件描述语言代码至关重要。
本文将介绍可综合的Verilog 语句及其可综合性分析,并提出提高代码可综合性的方法。
【可综合的Verilog 语句】Verilog 中有很多可综合的语句,包括基本赋值语句、组合逻辑实现、时序逻辑实现和实例化模块。
1.基本赋值语句基本赋值语句包括阻塞赋值(assignment)和非阻塞赋值(non-blocking assignment)。
这两种赋值语句都是可综合的。
2.组合逻辑实现组合逻辑实现通常使用与门(and)、或门(or)、非门(not)等基本逻辑门实现。
这些逻辑门的Verilog 实现都是可综合的。
3.时序逻辑实现时序逻辑实现通常使用寄存器(register)、计数器(counter)等元件实现。
这些元件的Verilog 实现都是可综合的。
4.实例化模块实例化模块是通过使用`实例化`关键字将一个模块复制多次。
实例化模块的Verilog 实现也是可综合的。
【Verilog 语句的可综合性分析】1.基本赋值语句的可综合性基本赋值语句的可综合性取决于赋值的目标。
VerilogHDL常用综合语法
VerilogHDL常⽤综合语法 前⾯已经记录了⼀些组成Verilog的基本组成,可以⽤这些基本组成来构成表达式。
这⼀节,就来记录⼀下把这些表达式构成⼀个⽂件的各种⾏为描述语句。
①这⾥⽤Verilog基本要素进⾏的⾏为描述主要是针对综合来的,也就是可以设计出实际电路来的(⾏为描述语句有两⼤⼦集,⼀个是⾯向综合,⼀个是⾯向仿真)。
②⾏为描述语句⼀般指放在always语句中。
内容提纲如下所⽰: ·触发事件控制 ·条件语句(if与case语句) ·循环语句 ·任务和函数 ·编译预处理⼀、触发事件控制 ①电平敏感事件是指指定信号的电平发⽣变化时发⽣指定的⾏为。
②边沿触发事件(信号跳变沿)是指指定信号的边沿信号跳变时发⽣指定的⾏为,分为信号的上升沿(x→1或者z→1或者0→1)和下降沿x→0或者z→0或者1→0)。
③信号跳变沿触发电路对信号的某⼀跳变沿敏感名字⼀个时钟周期内,只有⼀个上升沿和⼀个下降沿,因此计算结果在⼀个周期内保持不变,⽽电平触发电路则可能会引起数据在⼀个时钟周期内变化⼀次或多次。
其他敏感列表的事项请查看这篇博⽂:。
⼆、条件语句 Verilog的条件语句包括if语句和case语句。
(1)if语句 ①if语句中的条件判断表达式(括号中的那个)⼀般为逻辑表达式或者关系表达式或者就⼀个变量。
如果表达式的值是0、X或者Z,则全部按照“假”处理;若为1,则按照“真”处理。
②在应⽤中,else if 分⽀的语句数⽬由实际情况决定;else分⽀可以省略,但在描述组合逻辑中,会综合得到锁存器。
(2)case语句 ①case语句,case语句是⼀个多路条件分⽀的形式,常⽤于多路译码、状态机以及微处理器的指令译码等场合,有case 分⽀、casez分⽀、casex分⽀这三种形式。
②case语句⾸先对条件表达式求值,然后同时并⾏对各分⽀项求值并进⾏⽐较;当case语句跳转到某⼀分⽀后,控制指针将转移到endcase。
3讲 Verilog语法
本章主要内容
◆ 过程语句(initial、always) 过程语句(initial、always) ◆ 块语句(begin-end、fork-join) 块语句(begin-end、fork-join) 赋值语句(assign、 <=) ◆ 赋值语句(assign、=、<=) 条件语句(if-else、case、casez、casex) ◆ 条件语句(if-else、case、casez、casex) 循环语句 for、forever、repeat、while) 语句( ◆ 循环语句(for、forever、repeat、while) ◆ 编译指示语句 define、`include、`ifdef、`else、`endif) (`define、`include、`ifdef、`else、`endif) 任务(task) 函数(function) ◆ 任务(task)与 函数(function) ◆ 顺序执行与并发执行
(2)过程赋值语句(Procedural Assignments) )过程赋值语句( ) 过程赋值语句多用于对reg型变量进行赋值 型变量进行赋值。 过程赋值语句多用于对 型变量进行赋值。过程赋值有阻塞赋值和 非阻塞赋值两种方式。 非阻塞赋值两种方式。 非阻塞( (Ⅰ)非阻塞(non_blocking)赋值方式 ) 赋值符号为“ ” 赋值符号为“<=”, 如:b<= a; ; 非阻塞赋值在整个过程块结束时才完成赋值操作, 非阻塞赋值在整个过程块结束时才完成赋值操作,即b的值并不是立刻 的值并不是立刻 就改变的。 就改变的。 阻塞( (Ⅱ)阻塞(blocking)赋值方式 ) 赋值符号为“ ” 赋值符号为“=”, 如:b= a; ; 阻塞赋值在该语句结束时就立即完成赋值操作, 阻塞赋值在该语句结束时就立即完成赋值操作,即b的值在该条语句 的值在该条语句 结束后立刻改变。如果在一个块语句中,有多条阻塞赋值语句, 结束后立刻改变。如果在一个块语句中,有多条阻塞赋值语句,那么在前 面的赋值语句没有完成之前,后面的语句就不能被执行,仿佛被阻塞了( 面的赋值语句没有完成之前,后面的语句就不能被执行,仿佛被阻塞了( blocking)一样,因此称为阻塞赋值方式。 )一样,因此称为阻塞赋值方式。
Verilog RTL级语法常用概念整理
Verilog RTL级语法常用概念整理RTL级语法就是可综合的那部分语法内容,它主要用于描述数据如何在寄存器之间传输、控制和处理。
所谓RTL级建模也就是用这部分语法内容区描述实际电路的行为。
RTL级编码过程是心中先有电路,再将它翻译成Verilog代码。
电路行为的先后顺序通过时钟节拍的顺序来实现。
RTL级语法:能综合成门级电路一、语法基本概念1、模块基本结构:基本单元是“模块(module)”,一个Verilog里可以有很多module。
2、端口定义:在顶层模块中,端口对应的物理模型是芯片的管脚,在内部子模块中,端口对应的物理模型则为内部连线。
3、三态输出端口:信号设三态,相当于与总线断开。
4、对双向口(inout)建模:FPGA内部没有双向端口,内部信号均为单一流向,输入输出采用单独信号表示,不能复用在一起,只有芯片接口的信号才能定义为双向口。
二、数据类型1、数据宽度:wire[15:0] a; //描述了一个位宽为16的信号。
2、接线(Net):凡电路连接支点均称为接线,声明用wire 型,并以Z为default值。
总线(Bus)则是接线的组合,声明也用wire型(wire型数据不能赋值)。
在实际应用中,凡是使用连续赋值语句(assign)赋值的信号都定义为wire型,在模块例化时,要将具有连线意义的信号定义为wire型。
3、寄存器型(reg型):在时序逻辑中它对应的是寄存器,在组合逻辑中表示一个节点,在实际应用中,凡是在initial/always块中的被赋值信号都必须定义为reg型。
reg[31:0] mem[1023:0];//定义了一个位宽为32,深度为1024的存储单元。
4、参数型(parameter):用来定义在程序内部仿真时保持不变的常数,以增进程序的可读性。
三、语句1、assign语句:无论等式右端怎样变化,等式左端的值马上产生相应变化。
连续赋值是对组合逻辑的描述。
等式左端的数据必须是wire型,右端的数据可以是wire/reg。
可综合的verilog语法子集
可综合的verilog语法子集
常用的RTL语法结构如下:
☆ 模块声明: module……endmodule
☆ 端口声明:input,output,inout(inout的用法比较特殊,需要注意)
☆ 信号类型:wire,reg,tri等,integer常用语for语句中(reg,wire时最常用的,一般tri和integer不用)☆ 参数定义:parameter
☆ 运算操作符:各种逻辑操作符、移位操作符、算术操作符大多时可综合的(注:===与!==是不可综合的)
☆ 比较判断:if……else,case(casex,casez)……default endcase
☆ 连续赋值:assign,问号表达式(?:)
☆ always模块:(敏感表可以为电平、沿信号posedge/negedge;通常和@连用)
☆ begin……end(通俗的说,它就是C语言里的 “{ }”)
☆ 任务定义:task……endtask
☆ 循环语句:for(用的也比较少,但是在一些特定的设计中使用它会起到事半功倍的效果)
☆ 赋值符号:= 和 <= (阻塞和非阻塞赋值,在具体设计中时很有讲究的)
可综合的语法时verilog可用语法里很小的一个子集,用最精简的语句描述最复杂的硬件,这也正是硬件描述语言的本质。
对于做RTL级设计来说,掌握好上面这些基本语法是很重要。
常用可综合Verilog HDL语法总结
常用可综合Verilog HDL语法总结
基本语法结构
module module_name(port1,port2,…);//Declarations 模块声明input,output,inout, //端口声明
reg,wire, //信号类型
parameter, //参数定义
function,task,…//任务函数声明
//Statements 以下功能描述语句部分
initial statement //初始化,用于仿真
always statement // always模块,敏感表可以为电平或边沿信号posedge/negedge,通常和@连用
Module instantiation
Gate instantiation
Continuous assignment
endmodule
运算操作符:各种逻辑操作符、移位操作符和算术操作符如下:按优先级排列
操作符类型符号
连接及复制操作符一元操作符
算术操作符
逻辑移位操作符关系操作符
相等操作符
按位操作符
逻辑操作符
条件操作符{} {{}}
!~ & | ^ * / %
+ -
<< >>
> < >= <=
= = = = = != != = &
^ ~^
|
&&
||
?:
连续赋值语句:assign ( ?: )
过程赋值语句:begin … end 阻塞= 非阻塞<= 比较判断:if else ; case default endcase
循环语句for。
可综合的verilog语法
(1)所有综合工具都支持的结构:always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter。
(2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait。
(3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。
建立可综合模型的原则要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:(1)不使用initial。
(2)不使用#10。
(3)不使用循环次数不确定的循环语句,如forever、while等。
(4)不使用用户自定义原语(UDP元件)。
(5)尽量使用同步方式设计电路。
(6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
(7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。
(8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
(9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。
对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。
但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。
(10)不能在一个以上的always过程块中对同一个变量赋值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
常用的RTL语法结构如下:☆模块声明:module……endmodule☆端口声明:input,output,inout(inout的用法比较特殊,需要注意)☆信号类型:wire,reg,tri等,integer常用语for语句中(reg,wire时最常用的,一般tri和integer 不用)☆参数定义:parameter☆运算操作符:各种逻辑操作符、移位操作符、算术操作符大多时可综合的(注:===与!==是不可综合的)☆比较判断:if……else,case(casex,casez)……default endcase☆连续赋值:assign,问号表达式(?:)☆always模块:(敏感表可以为电平、沿信号posedge/negedge;通常和@连用)☆begin……end(通俗的说,它就是C语言里的“{ }”)☆任务定义:task……endtask☆循环语句:for(用的也比较少,但是在一些特定的设计中使用它会起到事半功倍的效果)☆赋值符号:= 和<= (阻塞和非阻塞赋值,在具体设计中时很有讲究的)可综合的语法时verilog可用语法里很小的一个子集,用最精简的语句描述最复杂的硬件,这也正是硬件描述语言的本质。
对于做RTL级设计来说,掌握好上面这些基本语法是很重要。
相信大家在看了这么多了verilog语法书籍以后一定有点烦了,那么现在我告诉大家一个好消息,对于一个RTL级的设计来说,掌握了上面的语法就已经足够了,无论多么牛逼的工程师,在他的代码里无非也就是上面一些语法而已。
当然了,对于一个能够进行很好的仿真验证的代码,一般还需要在RTL级的设计代码中添加一些延时之类的语句,比如大家一定知道#10的作用,就是延时10个单位时间,这个语句虽然在仿真的时候是实实在在的延时,但是这个语句在综合后是会被忽略的,也就是说在我们综合并且布局布线最后烧进FPGA里,这个#10的延时是不会在硬件上实现的。
所以说,上面给出的这些语法才是可以最后在硬件上实现的,其它的语法大多会在综合后被忽略。
这么一来大家就要问了,为什么语法书里又要给出这么多的语法呢?呵呵,它们大都是为仿真验证是写testbench 准备的,先点到为止,下集继续!对于模型(module)的建立,要保证可综合性应该注意:(1)不使用initial。
(被忽略)(2)不使用#10。
(被忽略)(3)不使用循环次数不确定的循环语句,如forever、while等。
(4)不使用用户自定义原语(UDP元件)。
(5)尽量使用同步方式设计电路。
(6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
(7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。
(8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
(9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。
对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。
但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。
(10)不能在一个以上的always过程块中对同一个变量赋值。
而对同一个赋值对象不能既使用阻塞式赋值,又使用非阻塞式赋值。
(11)如果不打算把变量推导成锁存器,那么必须在if语句或case语句的所有条件分支中都对变量明确地赋值。
(12)避免混合使用上升沿和下降沿触发的触发器。
(13)同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。
(14)避免在case语句的分支项中使用x值或z值。
但是在仿真验证程序中,一般VerilogHDL语法都是容许的。
Verilog语法需要注意的一些要点1.Testbench中时钟和数据比特流的简单设计方法always clock = ~clock;always @(posedge clock)begindata_in_a = {$radom} % 2; // 产生-1到1之间随机的比特流data_in_b = 16’b1101_1011_1110_0011; // 产生固定的比特流$display(“a= %d\n”, a); // 与C语言类似end2.Verilog语法中的并行与顺序模块(1)连续赋值语句、always模块之间、实例模块之间都是并行语句(2)always模块内部是分情况而定,对于if…else…而言,总是有优先级的顺序的,对于case而言,无优先级,是完全顺序执行的,此外,还要对阻塞语句和非阻塞语句具体分析。
3.Verilog中四种最常见的变量(1)wire,即线网形变量,它不能存储值,必须受到驱动器或者连续赋值语句的驱动,如果没有驱动,那么它将会是高阻态(2)reg是数据存储单元的抽象,通过赋值语句可以改变寄存器存储的值,其作用与改变触发器存储的值相当。
寄存器变量的初时值为不确定态。
在always内部用到的变量必须是reg型的。
(3)prarmeter相当与VHDL中的constant4.注意区分集中容易混淆的运算符(1)位运算符,按位操作,~,|,&,^,其输出与输出一样位宽(2)逻辑运算符,输出0或者1,&&,||,!(3)缩减运算符,按位递归运算,&,|,!,其输出仅仅是1或者05.阻塞语句(blocking)与非阻塞赋值语句(non-blocking)(1)非连续赋值语句(non-blocking)(b <= a)在always块结束后才完成赋值操作,并且赋值后b不是立即就改变,在时序逻辑或者既有时序逻辑也有组合逻辑中一定要用这种赋值方式(2)阻塞语句(blocking)(b = a)赋值之后,b就立即改变,也就是在赋值语句完成以后,always才结束,在综合时,如果不注意,将产生意想不到的结果一个非常典型的例子:always @(clock)beginb = a;c = b;endalways @(clock)beginc = b;b = a;endalways @(clock)beginb <= a;c <= b;end6.使用if或者是case进行综合时,一定要覆盖所有可能的情况,防止锁存器的综合7.写testbench一些常见的保留字$display(“print_word_value = %d”, print_word_value); // 与C语言类似$display(“%h, %o”, 12’b1101_0100_0111); // 结果是0xD47和o6507 $monitoron; // 监控开始$mointor($time, “rxd = %b”, “txd = %b”, rxd, txd); // 打印当前时刻的监控值$monitoroff;$finish; // 仿真结束$readmemb(“数据文件名”, 存储器名); // 把数据读入到当前指定的存储器内rand_data = {random} % 60; // 产生-59到59之间的随机数8.比较下面代码,分别综合出什么,可能出现什么问题module dff_en(I_en, I_data, I_clock, O_data);input I_clock;input I_en;input I_data;output O_data;reg R_data;assign O_data = R_data;always @(I_clock)beginif (I_en == 1) R_data <= I_data;endendmodule有以下告警(用synplify综合)(1)Incomplete sensitivity list - assuming completeness(2)Referenced variable I_en is not in sensitivity list(3)Referenced variable I_data is not in sensitivity list(4)Latch generated from always block for signal如果改always @(I_clock)为always @(posedge I_clock)就可以避免,并产生一个带使能的DFF 9.下面逻辑有没有问题?module dff_en(I_reset1, I_reset2, I_data, I_clock, O_data);input I_clock;input I_reset1;input I_reset2;input I_data;output O_data;reg R_data;assign O_data = R_data;always @(negedge I_reset1 or posedge I_clock) // 敏感变量I_reset2在时钟beginif (I_reset1 == 0) R_data <= 0;else if (I_reset2 == 0) R_data <= 1;else R_data <= I_data;endendmodule综合时不会有告警,产生一个带复位和置位的DFF,最好改always @(negedge I_reset1 or posedge I_clock)为always @(negedge I_reset1 or negedge I_reset2 or posedge I_clock)10.逻辑综合结果是什么?module mux2s1(I_sel, I_a, I_b, O_c, O_d)input I_sel, I_a, I_b;output O_c, O_d;reg R_c;reg R_d;assign O_c = R_c;assign O_d = R_d;always @(I_sel, I_a, I_b)begincase (I_sel)1'b0: R_c = I_a; // 综合出latch1'b1: R_d = I_b; // latchendcaseendendmodule该逻辑将产生锁存器。
11.下面代码综合结果是什么?module dff_sys(I_clock, I_data, O_data); input I_clock, I_data;output O_data;reg R_b, R_c, R_d;always @(posedge I_clock)beginR_c = R_b;R_b = I_data;R_d <= R_c;endendmodulemodule dff_sys(I_clock, I_data, O_data); input I_clock, I_data;output O_data;reg R_b, R_c, R_d;beginR_c = R_b;R_d <= R_c;R_b = I_data;endendmodule两段逻辑都没有任何区别,综合电路如下,这也说明了non-block语句的特点下面逻辑呢?module dff_sys(I_clock, I_data, O_data);input I_clock, I_data;output O_data;reg R_b, R_c, R_d;assign O_data = R_d;always @(posedge I_clock)beginR_b = I_data;R_c = R_b;R_d <= R_c;endendmodulemodule dff_sys(I_clock, I_data, O_data);input I_clock, I_data;output O_data;reg R_b, R_c, R_d;assign O_data = R_d;beginR_b <= I_data; R_c <= R_b; R_d <= R_c; end endmodule。