1.基础知识

所有的verilog代码都是以module(模块)的方式存在,一个简单的逻辑可以由一个module组成,复杂的逻辑可以包含多个modules,每个module有独立的功能,
并可通过输入、输出端口被其它module调用。通过module的方式可以将一些比较独立、可以复用的功能进行模块化。verilog语法有很多,而且分为可综合(
综合后可以生成对应的硬件电路)的语法和不可综合(综合后不可以生成对应的硬件电路)的语法,可综合的代码是非常少的,大多数代码是不可以综合的,
但是可以再仿真用于验证逻辑的正确性,十分方便。

2.常量与变量

常量是verilog中不变的数值,verilog中的常量有3种类型
(1)整数型
(2)实数型
(3)字符串型
变量类型:
(1)线网型:表示电路间的物理连线
(2)寄存器型:verilog中一个抽象的数据存储单元线网型和寄存器类型具体又包含很多种变量,线网型变量最常用的变量就是wire,而寄存器最常用的变量是reg,wire可以看成直接的连接,
在可综合的逻辑中会被映射成一根真实的物理连线,而reg具有对某个时间点状态进行保存的功能,如果在可综合的时序逻辑中表达,会被
映射成一个真实的物理寄存器,而在verilog仿真器中,寄存器类型的变量通常要占用一个仿真内存空间。因此在设计逻辑的时候要明确定义
信号是wire还是reg属性,凡是在always或initial语句中被赋值的变量(赋值号左边的变量),不论是表达的是组合逻辑电路还是时序逻辑,都一定
是reg变量,凡是在assign语句中被赋值的变量,一定是wire型变量基数表达法的基本格式:
[换算为二进制后位宽的总长度][’][数值进制符号][与数值进制符号对应的数值],其中[位宽的总长度]可有可无。当[换算为二进制后位宽的总长度]比[与数值进制符号对应的数值]
的实际位数多,则自动在[与数值进制符号对应的数值]的左边补足0,如果位数少,则自动截断[与数值进制符号对应的数值]左边超出的位数h:十六进制
d:十进制
b:二进制
//1.测试verilog的基本变量`timescale 1ns/1ps
module tb_led();parameter TIME=8'h50; //整数型
parameter NAME="ycl"; //字符串型
parameter WEIGHT=12.3; //实数型reg [15:0] a; //定义一个16位reg类型变量a
reg [15:0]  b;
reg [15:0]  c;
reg d;         //定义1位reg类型变量(不写位宽,默认为1位)
reg [7:0]   e; //定义一个8位reg类型变量einitial  begina = 16'd10;b = 16'h20;d = 1'b1;e = 8'b1111_000;c = a + b;$display ("Hello FPGA!!");$display ("a = %d,b = %x,c  = %x,d = %b,e = %b,TIME = %x,NAME = %s,WEIGHT = %f",a,b,c,d,e,TIME,NAME,WEIGHT);
endendmodule

3. timescale

`timescale 1ns/1ps
时间单位和时间精度由值1、10、100以及单位s、ms、us、ns、ps和fs组成
时间单位:定义仿真过程中所有与时间单位相关的单位。仿真中使用"#数字"表示延时相应时间单位的时间,例如#10表示延时10个单位的时间,即10ns
时间精度,精度一旦超过了精度,就会四舍五入:决定时间相关量的精度及仿真显示的最小刻度#10 :延时10 * 1ns = 10ns
#10.001 :延时 10 * 1ns + 1ps
#10.0027 :延时 10 * 1ns + 3ps
#10.0023 :延时 10 * 1ns + 2ps
//2.测试timescale作用`timescale 1ns/1ps
module tb_led();reg a;reg b;reg c;reg d;initial begina = 1;#10; //延时10nsa = 0;endinitial beginb = 1;#10.005; //延时10ns + 5psb = 0;endinitial beginc = 1;#10.0036; //延时10ns + 4psc = 0;endinitial begind = 1;#10.0034; //延时10ns + 3psd = 0;endendmodule

参考链接:
https://blog.csdn.net/yanchuan23/article/details/122920088

4.initial、always语句块

initial语句只执行一次,一个模块中可以有多个initial块,它们都是并行的,initial语句最常见用于测试文件里面初始化语句,用来产生测试环境和设置信号记录。这个初始化过程不需要任何仿真时间,即在0ns时间内,便可以完成存储器的初始化工作
always语句在仿真过程中不断运行着直到仿真结束,一个模块中可以有多个always块,他们都是并行执行的,语句由于不断活动的特性,只有和一定的时序控制逻辑结合在一起才有用//相当于初始化变量
initial 语句格式:
initial begin //在begin-end串行语句块中,一条非阻塞过程语句的执行不会阻塞下一条语句的执行,也就是在本条非阻塞型过程赋值语句对应的赋值操作执行完之前,下一条语句也可以开始执行语句1;语句2;语句3;
end//相当于while循环
always <时序控制>语句
//3.测试initial 和 always关键字
`timescale 1ns/1psmodule tb_led();reg a;reg b;reg c;reg d;reg e;//在一个module模块中可以有多个initial和always语句,相互都是独立的,并行进行的/*在begin-end串行语句块中,一条非阻塞过程语句的执行不会阻塞下一条语句的执行,也就是说在本条非阻塞型过程赋值语句对应的赋值操作执行完之前,下一条语句也可以开始执行*/initial begin //有多个语句时,用begin end 括起来,相当于{}a = 1;b = 0;#10; //延时10ns后,赋值1给b,前10ns 一直为0b = 1;endalways beginc = 0;#10;c = 1;#10;endinitial d = 1;always #10 d = $random % 2; //10ns产生一个随机数initial e = 0;always #10 e = ~e; //10ns翻转一次,产生一个时钟endmodule

参考链接:
https://blog.csdn.net/woshiyuzhoushizhe/article/details/95448348

5.非阻塞赋值与阻塞赋值

赋值语句的赋值方式有两种,分别为"<="(非阻塞赋值)和"="(阻塞赋值)1.以赋值操作符"<="来标识的赋值操作称为非阻塞过程赋值,具有如下特点:a.在begin-end串行语句块中,一条非阻塞过程语句的执行不会阻塞下一条语句的执行,也就是说在本条非阻塞过程赋值语句对应的赋值操作执行完之前,一下条语句也可以开始执行b.仿真过程在遇到非阻塞过程赋值语句后首先计算其右端赋值表达式的值,然后等到仿真时间结束时再将该计算结果赋值变量,也就是说,这种情况的赋值操作是在同一仿真时刻上的其他操作结束后才得以执行2.以 赋 值 操 作 符 “ = ” 来 标 识 的 赋 值 操 作 称 为 “ 阻 塞 型 过 程 赋 值,具有如下特点:a.在 begin-end 串行语句块中的各条阻塞型过程赋值语句将以它们在顺序块后排列次序依次得到执行b.阻塞型过程赋值语句的执行过程是:首先计算右端赋值表达式的值,然后立即将计算结果赋值给“=”左端的被赋值变量阻塞型过程赋值语句的这两个特点表明:仿真进程在遇到阻塞型过程赋值语句时将计算表达式的值并立即将其结果赋给等式左边的被赋值变量;在串行语句块中,下一条语句的执行会被本条阻塞型过程赋值语句所阻塞,只有在当前这条阻塞型过程赋值语句所对应的赋值操作执行完后下一条语句才能开始执行

//  4.测试非阻塞赋值和阻塞赋值`timescale 1ns/1ps
module tb_led();reg clk;reg a;reg b;reg c;reg d;reg e;reg f;reg g;reg h;reg i;reg x;reg z;initial clk = 0;initial begin //以下赋值会并行进行,因为都为非阻塞赋值a <= 0;b <= 1;c <= 0;d <= 1;endalways #10 clk = ~clk; //产生一个20ns的时钟always@(posedge clk) begina <= b; //非阻塞赋值,两条会同时进行b <= a; endalways@(posedge clk) beginc = d; //阻塞赋值,只有执行完该语句后,才能往下继续执行d = c;endinitial begine <= 1;f <= 0;endalways@(posedge clk) begin //下面的语句开执行的条件是:在clk的上升沿e <= f;  //先执行,e 为 0#10; //延时10ns后执行以下赋值语句f <= e; //f 为 0;endinitial g <= 1;always@(negedge clk) begin //在clk下降沿开始执行下面的语句g = ~g;endinitial beginh <= 0;i <= 1;x <= 0;z <= 1;endalways@(posedge clk) beginh <= i;i <= h;#40x <= z;z <= x;#15h <= 0;i <= 1;end
endmodule

参考链接:
https://blog.csdn.net/sxy121835/article/details/124235500

6.赋值语句

 赋值语句的赋值方式有两种,分别为"<="(非阻塞赋值)和"="(阻塞赋值)1.以赋值操作符"<="来标识的赋值操作称为非阻塞过程赋值,具有如下特点:a.在begin-end串行语句块中,一条非阻塞过程语句的执行不会阻塞下一条语句的执行,也就是说在本条非阻塞过程赋值语句对应的赋值操作执行完之前,一下条语句也可以开始执行b.仿真过程在遇到非阻塞过程赋值语句后首先计算其右端赋值表达式的值,然后等到仿真时间结束时再将该计算结果赋值变量,也就是说,这种情况的赋值操作是在同一仿真时刻上的其他操作结束后才得以执行2.以 赋 值 操 作 符 “ = ” 来 标 识 的 赋 值 操 作 称 为 “ 阻 塞 型 过 程 赋 值,具有如下特点:a.在 begin-end 串行语句块中的各条阻塞型过程赋值语句将以它们在顺序块后排列次序依次得到执行b.阻塞型过程赋值语句的执行过程是:首先计算右端赋值表达式的值,然后立即将计算结果赋值给“=”左端的被赋值变量阻塞型过程赋值语句的这两个特点表明:仿真进程在遇到阻塞型过程赋值语句时将计算表达式的值并立即将其结果赋给等式左边的被赋值变量;在串行语句块中,下一条语句的执行会被本条阻塞型过程赋值语句所阻塞,只有在当前这条阻塞型过程赋值语句所对应的赋值操作执行完后下一条语句才能开始执行3.assign和always语句assign语句是连续赋值语句,一般是将一个变量的值不间断地赋值给另外一个变量,两个变量之间就类似于被导线连接到了一起,习惯上当作连线使用,assign语句地基本格式是:assign a = b (逻辑运算符) c …;assign语句地功能属于组合逻辑地范畴,应用范围可以概括为以下几点:(1)持续赋值(2)连线(3)对wire型变量地赋值,wire是线网,相当于实际地连接线,如果要用assign直接连接,就用wire变量,wire型变量随时发生变化(4)多条assign连续赋值语句之间相互独立,并行执行always语句是条件循环语句,执行机制是通过对一个称为敏感变量表地事件驱动来实现地,always语句的基本格式是:always @(敏感事件)begin程序语句endalways是"一直、总是"的意思,@后面跟着事件,整个always的意思是:当敏感事件的条件满足时,就执行一次"程序语句"。always @(a or b or d)beginif(sel == 0)c = a + b;elsec = a + d;end这段程序的意思是:当信号 a 或者信号 b 或者信号 d 发生变化时,就执行一次下面语句。在执行该段语句时,首先判断信号 sel 是否为 0,如果为 0,则执行第 3 行代码。 如果 sel 不为 0,则执行第 5 行代码。需要强调的是, a、 b、 c 任意一个发生变化一次, 2 行至 5 行也只执行一次,不会执行第二次。此处需要注意,仅仅 sel 这个信号发生变化是不会执行第 2 行到 5 行代码的, 通常这并不符合设计者的想法。例如,一般设计者的想法是: 当 sel 为 0 时 c 的结果是 a+b;当 sel 不为 0 时 c 的结果是 a+d。但如果触发条件没有发生改变, 虽然 sel 由 0 变 1, 但此时 c 的结果仍是 a+b当敏感信号非常多时很容易会把敏感信号遗漏,为避免这种情况可以用*代替,这个*是指程序语句中所有的条件信号,即a、b、d、sel(不包括c)always @(*)beginif(sel == 0)c = a + b;elsec = a + d;end敏感列表是**“ posedge clk”,其中 posedge 表示上升沿**。也就是说, 当 clk 由 0 变成1 的瞬间执行一次程序代码,即第 2 至 5 行, 其他时刻 c 的值保持不变。要特别强调的是: 如果 clk没有由 0 变成 1,那么即使 a、 b、 d、 sel 发生变化, c 的值也是不变的always @(posedge clk)beginif(sel == 0)c <= a + b;elsec <= a + d;end敏感列表是“ posedge clk or negedge rst_n”,也就是说,当 clk 由 0 变成 1 的瞬间,或者 rst_n 由 1 变化 0 的瞬间,执行一次程序代码,即第 2 至 8 行, 其他时刻 c 的值保持不变。这种信号边沿触发,即信号上升沿或者下降沿才变化的 always, 被称为“时序逻辑”, 此时信号 clk 是时钟。注意: 识别信号是不是时钟不是看名称,而是看这个信号放在哪里,只有放在敏感列表并且是边沿触发的才是时钟。而信号 rst_n 是复位信号, 同样也不是看名字来判断,而是放在敏感列表中且同样边沿触发,更关键的是“程序语句”首先判断了 rst_n 的值, 这表示 rst_n 优先级最高,一般都是用于复位always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)c <= 0;else if(sel == 0)c <= a + b;elsec <= a + d;end
/*5.测试assign
*/
module tb_led();reg in;wire out;reg[1:0] o;reg[31:0] count;initial in <= 0;always #10 in = ~in;assign out = (in == 1) ? 1 : 0;//assign out <= (in == 1) ? 0 : 1; //这种赋值"<="是错误的,使用assign时要使用=进行赋值,而不能使用<=进行赋值initial o = 0;initial count = 0;always@(posedge in) beginif(in == 1)o <= 3;count <= count + 1;
//      else
//          o <= 2;endendmodule

参考链接:
https://blog.csdn.net/Royalic/article/details/121196365
https://blog.csdn.net/Lily_9/article/details/83993254

7.verilog中系统函数

/*6.verilog中系统函数
*/module tb_led();reg[15:0] a;initial $display ("Hello FPGA!"); //display用于显示输出initial a <= 0;initial $monitor("a = %d",a); //初始化一次,monitor持续监测变量always begina = a + 1;$display ("time = %d,random = %d",$time(),$random()); //time为时间函数,返回64位当前仿真时间,random用于产生随机函数,返回随机数#10;//$stop; //暂停仿真,在窗口输入命令可以让程序继续执行//$finish; //结束仿真endendmodule

verilog基础语法相关推荐

  1. 【Verilog】二、Verilog基础语法

    文章目录 前言 一.简单的Verilog知识 1.1.Verilog端口定义 1.2.Verilog的标识符 1.3.Verilog的逻辑值 1.4.Verilog的数字进制 1.5.Verilog的 ...

  2. 4.Verilog 基础语法

    FPGA教程目录 MATLAB教程目录 -------------------------------------------------------------------------------- ...

  3. 1. verilog 基础语法

    1 模块结构     端口: module 模块名(端口1, 端口2, 端口3)     内容:         I/O说明:             input 端口名;             o ...

  4. Verilog基础语法--运算符【常用的几种】

    概述 主要复习常用的一些运算符 逻辑运算符 逻辑与:&&[双目运算符] 逻辑或:|| [双目运算符] 逻辑非:! [单目运算符] 其中,!的优先级要大于&& 和 || ...

  5. Verilog 基础语法01—逻辑值

    逻辑值 逻辑 0:表示低电平,也就对应我们电路 GND: 逻辑 1:表示高电平,也就是对应我们电路的 VCC: 逻辑 X:表示未知,有可能是高电平,也有可能是低电平: 逻辑 Z:表示高阻态,外部没有激 ...

  6. 07 verilog基础语法-条件语句

    虚拟机:VMware-workstation-full-14.0.0.24051 环 境:ubuntu 18.04.1 文章目录 一.学习内容 二.条件语句 (1)if-else语句 (2)case语 ...

  7. FPGA(2)基础语法 -- 按键控制led(alway@语句)

    目录 1.module 文件名(端口) 2.声明关键字 3.always@语句 代码 1.module 文件名(端口)  注:这里最好养成习惯,只在文件名后面的括号中声明引脚变量,输入输出.关键字类型 ...

  8. FPGA笔记之verilog语言(基础语法篇)

    文章目录 FPGA笔记之verilog语言(基础语法篇) 1. verilog 的基础结构 1.1 verilog设计的基本单元--module 1.2 module的使用 1.3 I/O的说明 1. ...

  9. 三、1【Verilog HDL】基础语法快速入门(FPGA开发)

    参考资料: 参考野火FPGA开发视频的基础语法:[野火]FPGA系列Xilinx Artix7教学视频,真正的手把手教学,"波形图"教学法,现场画波形图写代码,硬件基于野火FPGA ...

  10. Verilog语言基础语法

    Verilog基础知识 数字进制格式 标识符 数据类型 寄存器类型 线网类型 参数类型 运算符 运算优先级 数字进制格式 Verilog数字进制格式包括二进制,八进制,十进制,十六进制.常用为二进制, ...

最新文章

  1. 芯讯通1月28号晚上八点直播-C-V2X产业链生态思考,关注易贸智慧互联公众号免费收听...
  2. java map 排序_java集合框架面试题大集合
  3. 虚拟局域网Vlan划分
  4. 百度商业大规模微服务分布式监控系统-凤睛
  5. 【转】C#获取当前路径7种方法
  6. 跳转控制语句之break
  7. 【一遍过!!!】1014 Waiting in Line (30 分)(题意+分析)
  8. java json 易用_Java中 Json的使用
  9. 区分IE6,IE7,firefox三种浏览器的CSS HACK
  10. c语言不定参数的使用,C语言中不定参数的实现
  11. gcc编译器参数使用及解决
  12. .Net WebApi接口之Swagger集成详解
  13. flutter 里面读取和复制内容到手机剪切板
  14. 如何做好应用架构分层和模块化?
  15. ​​insecure-configuration --复现
  16. Java中Scanner的进阶---求和与求平均数
  17. 公司用的非标普通自动化用单片机还是plc_自动化专业现在吃香吗?
  18. 新手站长做网站优化需要避免的四个误区
  19. H.324M 3G-324M
  20. 无线组网方式比较-WIFI、Mesh、Zigbee

热门文章

  1. Gif 录制工具:Screen2Gif
  2. PFC离散元软件快捷操作方式
  3. AXI总线的一些知识
  4. github java 性能,JavaGuide/手把手教你定位常见Java性能问题.md at master · Github-Programer/JavaGuide · GitHub...
  5. srt字幕转ass字幕在线工具分享
  6. 大数据第三季--flume(day2)-徐培成-专题视频课程
  7. 计算机信息安全专业代码0839,全国网络空间安全学科专业分布
  8. 首都师范 博弈论 5 3 1合作博弈与数学表达
  9. 数值运算pythonmopn_python – 计算每列的Pandas DataFrame的自相关性
  10. Qt界面开发(一)(各种控件以及图表)