verilog设计知识集合
一、基本知识
verilog HDL,verilog硬件描述语言,可从上层到下层一直设计,使用一些列分层的模块来表示极其复杂的数字系统的语言。利用EDA工具将模块转化为网表,再使用FPGA或者ASIC实现具体的电路结构。
另外一门比较出名的是硬件描述语言是VHDL,偏重标准化考虑。
两门语言的描述能力略有差别,verilog的系统抽象能力的较弱,门级和开关电路级的描述能力比VHDL强。
主流设计方法是RTL设计,从RTL描述生成网表;行为级综合工具允许直接对电路的算法和行为描述。
二、设计流程和通用设计方法论
1、完整工程通用设计方法
(1)设计规范
对整个项目的设计情况和要求具体描述:
1️⃣展示芯片与系统关系的外部框图:系统描述
2️⃣展示每一部分功能的内部框图:功能描述
3️⃣IO引脚的描述:引脚描述
4️⃣定时估计:时序描述
5️⃣器件门数估计:面积估计
6️⃣封装形式:封装估计
7️⃣功耗形式:功耗估计
8️⃣价格目标:价格估计
还有测试程序,这个是在设计中不断添加的。
(2)设计规范评估
用于设计规范的可用性的评估,决定是否可行。
(3)选择器件和工具
选择芯片和对应的EDA工具,如Xilinx的芯片和vivado、Altera(inter)的芯片和quartus或者其他的系列。
(4)设计
采用从上到下的方法,按照器件的结构来工作,使用合适的设计方法,解决设计中的问题。
(5)检验
对设计的源码进行仿真,完成RTL级仿真结果和门级仿真结果的一致。这简称前仿真。在布局布线前还需要时序分析和后仿真。
(6)最终的评估
形式上确认无误
(7)系统集成和测试
芯片投产后进行连续的器件和系统的可靠性测试。
2、verilog HDL设计方法
(1)Bottom-Up
先出系统框图,然后划分模块,再进行设计,然后将设计综合成系统。
优点实现各个子模块的时间较短。
缺点是对整个系统的功能把握不足,整个系统实现时间较长,对设计人员相互协作的能力要求较高,结构设计错误容易造成较大损失。
(2)Top-Down
对整个系统进行方案设计和高层次的功能划分,使用低层次实现高层次的功能,一个设计分为树形结构。可以购买末端的设计。
优点:设计开始时就完成了系统分析,主要仿真和调试过程在高层次完成,可以尽早完成结构设计上的错误。方便了从系统级划分和管理整个项目。
缺点:得到的最小单元不标准,制作成本可能比较高。
(3)综合使用
1️⃣设计开始时,对系统的行为进行仿真,仿真成功后转化为RTL级描述
2️⃣RTL级描述,RTL级行为级描述硬件有关。
3️⃣逻辑综合,将RTL级描述转化为网表。
三、verilog语法的基本概念
1、模块(module)
verilog的模块可以对应不同级别的抽象:
1️⃣系统级2️⃣算法级3️⃣RTL级4️⃣门级5️⃣开关级
其中123是行为级,前端需要掌握4,后端还需要掌握5,在学习中了解每个模块的层次是重要的。
2、功能
(1)顺序执行(begin-end)或者并行执行(fork-join)
(2)延时表达式(#)或者事件表达式
(3)通过命名事件触发其他事件
(4)条件语句(if,case)等循环程序结构
(5)提供可带参数且非零延续的时间的任务task结构
(6)提供可以自定义新的操作符的函数function结构
(7)用于建立表达式的运算符(算数、逻辑、位运算符)
(8)结构化语言也是用于门级和开关级
3、模块的调用
通过模块名可以调用其他模块,注意端口的一致性。
4、模块测试
模块测试的语法较可综合的语法会宽泛,允许使用各种测试系统函数(stop,display)。测试的方法就是测试信号对呗测试模块的调用。
四、模块的结构
1、模块的结构
verilog程序包括四个部分:
端口定义,IO说明、内部信号声明和功能定义。
module name(io1,io2,io3); input io1; output io2,io3; endmodule
2、数据类型及常量和变量
reg、wire、integer、parameter
reg:寄存器型,always内部赋值专用
wire:连线变量,assign内部赋值专用变量
integer:整型,用于语法描述所需的整数,
parameter:参数,用于模块内部的常量。
具体实例:
1️⃣整型
1'b1,2'o1,3'd1.4'h1,
'b1,'h2,'d3,
1,2,3,
x,z,
2️⃣字符串
"abcd","abc ","ab\",
"ad%%"
3️⃣变量
wire,tri
reg,integer
memory (reg的数组)
wire a;
reg [7:0] b;
reg [7:0] b [255:0];
五、verilog HDL运算符
基本原则:
wire和reg是无符号数,
整型和实数型有符号数,
操作数存在x,结果即为x,
//算数操作
a=4’b1100; /*a=12*/ b=4’b0011; /*b=3*/ c=4’b1011; /*b=11*/ $display(a*b); //结果4 (10 0100,按操作数最长位数截短) $display(a/b); //4 $display(a+b); //15 $display(a+c); //7 (1_0111截短到4位) $display(a-b); //9 $display((a+1’b1)%b); //1 $display(-10%3); //-1 $display(11%-3); //2
//位操作
a=4’b1100; b=4’b0011; c=4’b0101; d = 4’b1xx0; e = 4’b0; $displayb(~a); //结果0011 $displayb(a&c); //0100 $displayb(a|b); //1111 $displayb(b^c); //0110 $displayb(a~^c); //0110 $displayb(d&e); //0000
//逻辑操作
a=2; b=0; c=4’hx; $display(a&&b); //结果0 $display(a||b); //1 $display(!a); //0 $display(a||c); //1 $display(a&&c); //x $display(!c); //x $display(b&&c); //0
//比较操作
a=2; b=5; c=2; d=4’hx; e= -2; $display(a<b); // 1 $display(a>b); // 0 $display(a>=c); // 1 $display(d<=a); // x $display(4'b0 <= 4'hx); // x
$display(-2<b); // 0
$display(-2<5); // 1
$display(2-5); // -3
$display(a-b); // 13
$display(e); // 14
这里注意display显示符号位和不显示符号位的要求:全reg型变量显示符号位,全常量不显示符号位。混合未知。(在编译器中会出现乱码)
//移位操作
a=4’b1010; $displayb(a<<1); //结果4’b0100 $displayb(a>>2); // 4'b0010 $displayb(4'bx<<2); // 4'bxx00 $displayb(4'b1101<<2); // 4'b0100
//连接操作
a=1’b1; b=2’b00; c=6’b101001; $displayb({a, b}); //结果3’b100 $displayb({c[5:3], a}); // 4’b1011 $displayb({4{a}}); // 4’b1111
//缩位操作
a=4’b1111; b=4’b0101; c = 4’b0x1z; $displayb(&a); //结果1 $displayb(|b); // 1 $displayb(^b); // 0
$displayb(&c); //结果0
$displayb(|c); // 1
$displayb(^c); // x
//判断操作
result = (op==ADD)? a+b : a-b;
止于运算优先级,多错几次就知道了。基本按照C语言走的。
六、verilog语句
1、块语句
顺序快(begin-end)和并行块(fork-join),两者的区别在于执行方法。顺序块逐条执行,并行块整体执行。一般使用begin-end比较符合C的设计习惯。主要差别在于延时的判断。
2、赋值语句
=阻塞赋值,等式右边先计算,再一起赋值给左式。
<=非阻塞赋值,等式右边计算后赋值给左式,然后计算下一条。
起始时间和结束时间:
对于并行块,最长的就是结束时间。对于顺序块,结束时间是所有延时相加。
3、条件语句
if-else语句和case语句,和C语言大致相似。case的形式有所区别:
case ( rega ) 16’d0: result=7’b0111111; 16’d1: result=7’b1011111; 16’d2: result=7’b1101111; 16’d3: result=7’b1110111; 16’d4: result=7’b1111011; 16’d5: result=7’b1111101; 16’d6: result=7’b1111110; default: result=7’bx; endcase
casez不考虑z,casex不考虑x和z,可以灵活使用。
4、循环语句
forever、repeat、while、for
这四个循环语句都不可以直接综合,不能独立放在程序中。
forever begin end
repeat (numb)begin end
while (条件)begin end
for(初始化,跳出条件,执行语句)begin end
5、结构说明语句
initial always task function
initial:只是执行一次的语句
always:总是执行
task:带参数的复用模块
function:带参数的关键字声明。函数不能启动任务。
task通过参数传递结果,function通过返回值传递结果。简单理解,task是可快速调用的代码,function是自定义的关键字。
6、系统函数
• $display和$write 标准输出任务
• $monitor 仿真监控任务
• $finish和$stop 仿真结束任务
• $time和$realtime等 时间函数
• $fopen…$readmemh等 文件、存储器处理
• $random 随机数函数
7、系统预编译
• `define 宏定义
• `include 文件包含
• `ifdef…`else…`endif 条件编译
• `timescale 时间定标
• `uselib 工作库定义