【准研一学习】狂肝15小时整理的Verilog语言入门知识 | 您所在的位置:网站首页 › 自学硬件 › 【准研一学习】狂肝15小时整理的Verilog语言入门知识 |
文章目录
闲言稍叙一、简介二、模块2.1 模块是Verilog的设计实体2.2 模块声明2.3 模块的实例化
三、Verilog基本要素3.1 数字3.2 变量3.3 运算符
四、Verilog行为语句4.1 过程语句4.2 块语句4.3 赋值语句4.4 条件语句4.4.1 if-else语句4.4.2 case语句
4.5 循环语句4.6 编译指示语句
五、Testbench5.1 为什么需要Testbench5.2 Testbench的目的和结构5.3 激励产生的方式5.3.1 产生时钟的方式5.3.2 产生复位信号的方式
5.4 仿真结果分析的方式5.5 Testbench实例5.5.1 2-4解码器5.5.2 时序检测器
5.6 常用的系统函数
闲言稍叙
Verilog和VHDL就是目前使用最多的两个硬件描述语言(HDL),如果阅读本文的你也是Verilog新手,这部分闲言或许对你有所启发。 作者本科是计算机科学与技术专业,现在是准研一,方向和硬件相关。 由于学艺不精,只会点C、Java,电路、信号、单片机等硬件课程都只懂皮毛。由于课题组研究需要,学习了Verilog语言并总结为本文。 C语言是软件描述语言,编码的核心目的在于经过编译、链接后能够产生机器能够识别的指令序列,进而完成代码功能。而Verilog是硬件描述语言,编码的核心目的在于描述门与门之间的连接,通过综合、实现所写的代码,产生可以转化为芯片的图纸,交由厂商通过光刻来生产所设计的电路,最终经过封装、测试,即通常所称的芯片。 要学习Verilog首先需要一个编程平台,有Vivado、Modelsim等,其中Vivado是用的最多的,但是运行比较慢,Modelsim运行的快,但是界面丑,这个看个人喜好安装就好。 有编程平台后,通过在网站上刷题和看书,逐渐就可以上手了。那么下面列举出我学习Verilog所使用过的网站、书籍: 网站: 1.HDLBits 网站地址 该网站是全英文的,里面有100多道练习题,题解可以在Github上找到。 2.VLab Verilog OJ 网站地址 这是由中科大团队开发的Verilog在线评测系统,类似于软件编程的洛谷等网站。 其中每个题都会给出比较充分的知识点叙述,然后再让你动手编码,目的在于帮助大家学习Verilog。 有挺多的简单题,适合我这样的零基础菜鸟,但这个网站没有题解,网上只能查到前27题的题解。 其他网站: 菜鸟教程(有Verilog的内容,但没有OJ)EDA Playground(英文网站,可以在线运行代码,很流畅)书籍 《EDA技术与Verilog HDL》 王金明编著 清华大学出版社 这本书是基于Vivado平台的,讲了Vivado的基本操作、Verilog语法和一些实例,硬件用EGO1实验板。 《自己动手写CPU》 雷思磊 电子工业出版社 这本书是基于Modelsim平台的,主要是使用Verilog设计能运行mips32指令的处理器。 《Vivado入门与FPGA设计实例》 廉玉欣 侯博雅编著 电子工业出版社 这本书也是基于Vivado和EGO1的,介绍了不少组合逻辑和时序逻辑的基本器件设计,如加法器设计。 一、简介Verilog HDL(Hardware Description Language)是IC设计者常用的两种HDL之一,另一种是VHDL,通过比较Verilog和C语言的区别可以更好地理解它。 Verilog和C语言的区别: 描述对象不同: Verilog语法和C接近,但C描述的是算法逻辑,依赖于硬件对其进行实现。而Verilog是硬件描述语言,描述的是硬件本身。处理方式不同: C需要经过编译、汇编、链接来将代码转化为可由计算机执行的二进制代码,而Verilog则需要经过综合来生成描述门与门之间互联关系的网表文件。执行方式不同: Verilog的部分描述语句可以并行执行,而C只能串行执行。 二、模块 2.1 模块是Verilog的设计实体Verilog的基本设计思想是自顶向下(top-down),设计实体是模块,所有Verilog代码都将在模块内书写。 如下图所示,先定义顶层模块,分析顶层模块中所需的各个子模块,然后进一步对各个子模块进行分解和设计,最终可以将一个大的系统分解为多个子系统。 在Verilog中,成熟的、封装好的模块称为IP(intelligent property),调用已有IP的本质就是模块实例化。 模块是Verilog的基本设计实体,模块声明的第一行指定了模块名称和端口列表,下面若干行指定了每个端口的方向、位宽、数据类型。 例如定义一个32位加法器模块: module add32(in1,in2,out); input wire[31:0] in1,in2; output wire[31:0] out; assign out=in1+in2; endmodule其中in1,in2,out是该模块的三个端口,采用上述代码较为简洁,也可以采用如下定义: module add32( input wire[31:0] in1, input wire[31:0] in2, output wire[31:0] out ); assign out=in1+in2; endmodule 2.3 模块的实例化模块实例化有两种方式, 一是按照名称: .模板中端口名称 (要连接到端口的线名), 二是按照位置 和定义时一一对应 下面我们将在top_module顶层模块中实例化mod_a,如图所示: 在top_module中两种实例化mod_a模块的代码如下: module top_module( input a, input b, input c, input d, output out1, output out2 ); //基于端口位置的实例化如下 mod_a inst_1( out1,out2,a,b,c,d ); //基于端口名称的实例化如下 mod_a inst_2( .out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d) ); endmodule 三、Verilog基本要素 3.1 数字在Verilog HDL中,整型常量即整常数有以下四种进制表示形式: 二进制整数(b或B)十进制整数(d或D)十六进制整数(h或H)八进制整数(o或O)数字表达方式有以下三种: 这是一种全面的描述方式。 在这种描述方式中,数字的位宽采用缺省位宽(这由具体的机器系统决定,但至少32位)。 在这种描述方式中,采用缺省进制十进制。 举例: 8’b11000101 相当于十进制的197 8’h8a 相当于十进制138 12 即十进制的12 3.2 变量声明格式如下: 其中数据类型和变量名是必要的,其余均可省略。 数据类型可以是net型、variable型, net型变量 相当于硬件电路中的物理连接,特点是输出的值随着输入值的变化而变化。![]() ![]() 1.算术运算符 +,-,×,/,%其中/和%不可综合 2.赋值运算符 =,,cout,sum}=ina+inb; 缩位运算符 缩位运算符是对单个操作数的递推运算,它放在操作数的前面,能将一个矢量缩减为一个标量。 如:reg [3:0] a; b=&a; 该代码等效于b=((a[0]&a[1])&a[2])&a[3] 四、Verilog行为语句 4.1 过程语句always过程语句 always过程语句是重复执行的,可综合的。 格式: always@() begin //语句序列 end always过程语句是有触发条件的,触发条件写在敏感信号表达式中。 敏感信号表达式的格式: 电平敏感型 always@(in1 or in2) always@(in1,in2) 用or和逗号都表示任一信号可触发事件 边沿敏感性 posedge表示上升沿,negedge表示下降沿。 为32位加法器添加一个时钟同步信号clk always@(posedge clk) begin out=in1+in2; end 在时钟信号的上升沿才会进行加法运算。initial过程语句 initial过程语句不带出发条件且仅执行一次。 initial语句通常用于仿真模块中对激励向量的描述,或者用于给寄存器变量赋初值。 它是面向模拟仿真的过程语句,通常不能被逻辑综合工具支持。 4.2 块语句块语句是由块标识符begin-end或者fork-join界定的一组语句,当块语句只包含一条语句时,块标识符可以缺省。 下面分别介绍串行块begin-end和并行块fork-join 串行块begin-end 串行块中的语句按串行方式顺序执行 module wave1 parameter cycle=10; reg wave; initial begin #(CYCLE/2) wave=0; #(CYCLE/2) wave=1; #(CYCLE/2) wave=0; #(CYCLE/2) wave=1; end initial $monitor($time,,,”wave=%b”,wave); endmodule并行块fork-join 并行块fork-join中的所有语句是并发执行的。例如: fork regb=rega; regc=regb; join用fork-join并行块产生信号波形 module wave2; parameter CYCLE=5; reg wave; initial fork wave=0; #(CYCLE) wave=1; #(2*CYCLE) wave=0; #(3*CYCLE) wave=1; #(4*CYCLE) wave=0; #(5*CYCLE) wave=1; #(6*CYCLE) $stop; join initial $monitor($time,,,”wave=%b”,wave); endmodule 4.3 赋值语句1.连续赋值(Continuous Assignment)语句 用assign对wire型变量进行赋值的语句。 等式右边的任何变化都将随时反映到左边去。 2.过程赋值(Procedural Assignment)语句 1)非阻塞赋值(Non-Blocking) 赋值符号为” |
CopyRight 2018-2019 实验室设备网 版权所有 |