主页 > 电脑硬件  > 

【FPGA开发】Verilog基础

【FPGA开发】Verilog基础

写在前面:本章将对 Verilog 进行简要介绍,并对其基本特性进行讲解说明。之后,我们将按步骤演示如何使用 Vivado 创建简单项目。手动实践部分将根据我们提供的 .v 和 .tb 代码,跟着步骤跑出 Simulation 结果即可。


Ⅰ. Verilog 基础速览 0x00 什么是 Verilog

HDL(Hardware Description Language),硬件描述语言。

Verilog 是一种用于描述电子系统的硬件描述语言(HDL)。它可以用来描述数字系统的结构和行为,并可以用于系统设计、模拟和综合。Verilog 最初是在 1984 年开发的,现在是电子设计自动化行业中使用最广泛的 HDL 之一。

Verilog 作为一种语言,它可以用于多种用途,包括电路设计、验证和实现。它具有类似于 C 语言的语法,因此用户可以轻松访问它。if 和 while 等控制结构相同,输出例程和运算符也相同差不多一样。与 C 语言这些语言不同,硬件描述语言的语法和含义描述了时间和并发性。还有就是的开头和结尾没有花括号,而是用 Begin 和 End 来区分。

 

0x01 Verilog 模块 module 模块名(端口列表) ; port 声明 reg 声明 wire 声明 parameter 声明 子模块实例 初识Gate always、initial assign function, task 定义 function, task 调用 endmodule

📚 Verilog 分为三个主要部分:头部、声明、主体。

头部以关键字 module 开头,后面跟模块名与端口列表,并以分号结尾。和大多数编程预压那一页,Verilog 也是不能用关键字命名的。声明部分包含方向、位宽和reg 和 wire 声明、参数声明等模块,即声明需要的东西。主体部分表示电路的功能、操作、结构等。它由各种 Verilog 语句组成。

 

0x02 Verilog 数据类型

  

Input:输入信号

Output:输出信号

寄存器:抽象存储设备

reg :通过程序赋值语句(always,initial)接收值的个体。integer:整型变量time, realtime:时间类型的变量(在需要时序检查的情况下处理仿真时间)real:实数型变量

Net : 设备的物理连接 wire :指示变量在模块中的连接方式。 tri:用于将导线相互连接。与 wire 不同,tri 用于 tri-state net。

 

0x03 Verilog HDL 的常数声明

当声明一个限制位数的 reg 值时:

(位数)'(输入格式)(输入值)

未指定大小的值(未指定大小也可以声明):

214; [整数 214] ‘h32; [16进制的 32] ‘o324; [8进制的 324]

指定大小的值(在开头声明位数):

4’b1111; [4bit的 2进制 1111] 4’hf; [4bit的 16进制 f(=4’b1111)] 4’d15; [4bit的 10进制 15(4’b1111)]

有符号数的处理(负值作为二进制补码处理):

-8'd6; [8bit的 -6]

 

0x04 Verilog 操作符

普通操作符:

符号功能符号功能{} , {{}}结合,循环^异或+, - , * , / , **算数^~ 或 ~^bit位等价%取余&and>, >=, <, <=关系~&nand!论理否定| or

 

 

 

 

 

 

 

// X=4'b1010, Y=4'b1101,Z=4'b10x1 ~X // Negation, Result is 4'b0101 X&Y // Bitwise AND, Result is 4'b1000 X | Y // Bitwise OR, Result is 4'b1111 X^Y // Bitwise XOR, Result is 4'b0111 X^~Y // Bitwise XNOR, Result is 4'b1000 X&Z // Bitwise AND, Result is 4'b10x0

 

移位操作符:

符号功能符号功能<<左移>>右移

 

 

 

 

// X=4'b1101 Y=X>>1 // Y is 0110 (0 is filled in MSB position) Y=X<<2 // Y is 0100 (0 is filled in LSB position)

 

条件运算符:

conditional_expression = exp1 ? exp2 : exp3

 

连接运算符(Concatenation Operators):    { }

// A = 1’b1 , B=2’b00 , C=2’b10 Y = {B,C} // Results Y is 4’b0010 X = {A, B, 3’b110} // Result X is 6’b100110 Z = {A, B[0], C[1]} // Result Z is 3’b101

复制运算符(Replication Operators):    {{ }}

//A = 1’b1 , B = 2’b01 , C = 2’b00 Y = {4{A}} // Result Y is 4’b1111 X = {4{A},2{B}} // Result X is 11110101 Z = {4{A}, {2{B}, C} // Result Z is 1111010100

 

0x05 Timescale 'timescale <时间单位> / <精密度>

<时间单位>:如果声明了该值,则文件中的所有时间单位都更改为声明的值。

(举个例子,如果声明“1ns”,文件中的所有时间单位都变为 1ns)

<精度> :表示给定时间单位内的最小可构成延迟,与 <时间单位> 关联使用,表示可使用的小数点的范围。

'timescale 10ns/1ns #1.55a=b; // 所有时间单位都是10ns,1.55*10ns = 15.5ns。 // 此处精度值向上舍入为1ns,结果为16ns。 'timescale 1ns/1ps #1.0055a=b; // 所有时间单位都是1ns,所以1.0055*1ns = 1.0055。 // 此处精度值向上舍入到1ps,得到1.006ns。 (1ps=0.001ns)

 

0x06 assign 语句 assign

当输入操作数的值中发生变化(event)时,assign 语句都会计算右侧的表达式。 因此该值具有围绕赋值语句驱动(drive)net 的硬件特性。 简单来说,就是用来给 net 变量赋值一个特定的逻辑值。

deassign

deassign 语句用于消除 assign 语句对变量的影响。

assign wire1 = reg1; // 简单的连接线 assign wire2 = (pin1) ? reg2[0] : reg2[1]; assign wire2 = {reg1,reg2[0]}; // 将两个不同的信号放入一个总线

 

0x07 alway 语句

always 语句在仿真运行时重复执行,因此它对于与时序控制相关的表达式很有用。@(sensitivity_list) 控制 always 语句的执行,并响应灵敏度列表中列出的一个或多个信号。当事件(event)发生时,总是执行里面的 begin-end 块。

always @(sensitivity_list) begin // Blocking or nonBlocking statements; end

 

0x08 initial 语句

与在模拟过程中无限重复的 always 语句不同,initial 语句仅在模拟运行时执行一次。 initial 语句的开始-结束块由过程语句组成,这些过程语句按列出的顺序执行。

initial begin // Blocking or nonBlocking statements; end

 

0x09 赋值语句

这些语句按照它们列出的顺序执行,并且具有更新赋值语句左侧变量值的软件特性。

always 语法,在 initial 语句中使用。

阻塞语句(Blocking statement):

blocking 符号:  =Begin ~ end 位置 Line by Line 的顺序计算并完成保存当任务都执行完毕后执行下面语句 -> 即,语句在执行完成之前 blocking#t 变量 = 计算;    ->  t事件后,计算并分配给变量。 变量 C = A & B; //读取A和B的值进行 & 运算并赋值给C. 然后执行下一条语句 变量 D = A | B; // 读取A和B的值进行 | 运算并复制给D,此时它们的执行过程没有延迟

 

非阻塞语句(Non blocking statement):

non Blocking 符号:<=在执行完从 Begin ~ End 的所有计算后,立即执行保存操作。多个非阻塞语句同时求值后分配。变量 <= #t 计算;    -> 计算t 后,保留变量赋值。

(* 用于在共同事件发生后同时传输多个数据)

变量 C <= A & B; // 读取A和B的值,并进行&操作 变量 D <= A | B; // 同时读取A和B的值, |操作, 然后将它们同时分配给 C 和 D。

💬 Verilog Blocking 语法举例:

 

Ⅱ. 动手操作

 

 

🔍 我的是 xc7a75tfgg484:

继续点 Finish:

在创建项目,等一会:

  

 保存项目:

 

 我们来写点代码试试:

 💬 inv.v

`timescale 1ns / 1ps module inv( input a, output y ); assign y = ~a; endmodule

再创建一个 csdn.tb 的 Sources:

💬 csdn.tb​​​​​​​

`timescale 1ns / 1ps module inv_tb; reg aa; wire y; inv u_inv ( .a (aa ), .y (y ) ); initial aa = 1'b0; always aa = #100 ~aa; initial begin #1000 $finish; end endmodule

 仿真:

等待

 

🚩 仿真结果如下:

 

📌 [ 笔者 ]   王亦优 📃 [ 更新 ]   2022.9.20 ❌ [ 勘误 ]   /* 暂无 */ 📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免, 本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

Introduction to Logic and Computer Design, Alan Marcovitz, McGrawHill, 2008

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. baike.baidu /.

 

标签:

【FPGA开发】Verilog基础由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【FPGA开发】Verilog基础