当前位置: 首页 > news >正文

【FPGA开发】Verilog 基础

ad3718d78f554c928635349fc40a3bd1.png

写在前面:本章将对 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 数据类型

e84f81be32b04d6d8ba14f92b350a445.png  

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 语句对变量的影响。

14dcddbdc9d8424083eed445ecaf9141.png

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 语法举例:

77a36c47b84d46e1b224db43e84f2965.png

c1051a7ccc0142ebac5ed2033d2d5f1c.png

 

Ⅱ. 动手操作

cabca19d70f2411ebd65c79e351f5cf6.png

360f78b68d984bd78fe82e94f3ddf9c6.png

43890eca8c214096bd6a868453f1661a.png

 70381ba6b5304603996dd20b7951ce84.png

 6d5610074f894fea86f149ed9dd08a4e.png

df1428850c244b8ea6148084f9b78997.png

f21a52014b114252a06bf686743bd113.png

2ead50cc4df04a74b08c4ecb44b18c60.png

f71e351d9f9743088615787edcd3aec1.png

🔍 我的是 xc7a75tfgg484:71db7d2e8460476e8b804f11c5883745.png

继续点 Finish:

bcd77ed9189f46e0a5a591470316b58b.png

在创建项目,等一会:

019ebf1cc7a14db5bb5916ff9b68fcdf.png

 5f01548f1f9042b89373a5623e0aae43.png 

 保存项目:

e8c9971663e642dbb116d5573d4eff1a.png

 

 我们来写点代码试试:

4dc9ee6ac7444d78a66188ca169d331a.png

 💬 inv.v

`timescale 1ns / 1ps

  module inv(
  input a,
  output y
  );

assign y = ~a;
 

endmodule

再创建一个 csdn.tb 的 Sources:

e68535ffb9ef453483c7fbea3f0fa7cf.png

💬 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

 仿真:

ec0493a7b13345ec883c3aae3213de7c.png

等待

 f0e8e6d4c873456ea2fdb23a4c41d355.png

🚩 仿真结果如下:

0f5e8840580b42d9bb48f62c8b9cfc36.png

 

7a80245f0b5f4021a033b3789a9efdeb.png

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

📜 参考资料 

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

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

百度百科[EB/OL]. []. https://baike.baidu.com/.

 

相关文章:

  • 【闲来无聊写个几个小特效——五角星,小光圈,探照灯】
  • Java爬虫 爬取某招聘网站招聘信息
  • 1.1
  • 字符串大小写转化,有序数组二分查找个人心得等若干内容
  • Dijkstra求最短路(堆优化)
  • 使用python实现跨年烟花代码
  • 2022年终总结
  • 【JavaScript】JS的三大组成-DOM
  • 【Linux】Linux进程的理解
  • bash 查看变量函数定义和值 (type declare)
  • html+css设计两个摆动的大灯笼
  • 音视频知识介绍(二)
  • github上传代码(亲测实用)
  • Vue 中 CSS scoped 的原理
  • MySQL 数据库练习题记录01
  • 142.环形链表II
  • java短网址平台
  • 【论文阅读】《知识图谱研究综述》;Knowledge Graph:概念及主要应用,主要特征、构建的主要技术、未来研究方向。
  • 通过Django发送邮件
  • 【数组】leetcode27.移除元素(C/C++/Java/Js)
  • 五一假期上海铁路预计发送446万人次,同比增长8.4%
  • 国家发改委:我国能源进口来源多元,企业减少甚至停止自美能源进口对国内能源供应没有影响
  • 校长套取学生伙食费设小金库,重庆通报6起违反八项规定典型问题
  • 知名计算机专家、浙江大学教授张森逝世
  • “冲刺万亿城市”首季表现如何?温州领跑,大连GDP超徐州
  • 视频丨伊朗阿巴斯港一处油罐发生高强度爆炸:造成大面积破坏,伤亡不明