我是靠谱客的博主 谨慎路灯,最近开发中收集的这篇文章主要介绍Verilog HDL学习笔记一、Verilog基本语法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 一、Verilog基本语法
    • Verilog语法概述
    • 基本语法
    • 数据类型及常量,变量
        • 常量
        • 变量
        • 运算符
        • 优先级
    • 【重要】语句
        • part0 概述
        • part1 赋值条件语句详解
        • part2 循环语句详解
        • part3 结构语句详解
    • 执行顺序

一、Verilog基本语法

Verilog语法概述

  • 行为级描述、寄存器级描述(RTL)/系统级描述:把module当做黑盒,描述module的输入和输出的关系。门级实现由综合工具推断,常常可以做到最优。
  • 结构级描述/门级描述:把module作为白盒,而描述组成module的门电路(部件)
module <module_name> (in1, in2, ..., out1, out2)
    input in1, in2, ...;
    output out1, out2, ...;
    ...
endmodule

// 注释1
/* 注释2 */

基本语法

  • Verilog区分大小写
  • Verilog的关键字都是小写
  • module,endmodule定义一个基本模块,两个关键字之间的语句是对该模块的描述。定义模块方便复用
  • parameter关键字定义一个参数,增强模块的通用性
  • output,input关键字指定输入输出
  • always @(posedge/negedge clk)语句,每当clk出现上升沿/下降沿时,就执行接下来的语句块(begin,end标志着一个语句块)。这种语句构成时序逻辑,当输入与上一个时刻的值有关的时候
  • reg类变量用<=赋值,赋值左边是寄存器,右边是更新的值
  • &q语句输出q每一位相与的结果,即&q=q[1]&q[2]&q[3]&q[4]...q[N]
  • assign关键字,描述组合逻辑,输出只与当前输入有关
  • input/output没有显示说明,默认为wire类型,如果需要reg类型来储存值,需要显示声明
  • wire只是一根导线,只能用来组合逻辑,assign语句一旦等号右边发生变化,等号左侧立即得到结果;而always的值的改变只能发生在下一个时刻(有@后面的语句所描述的时刻)
  • initial begin,end语句块指明初始化语句,这部分在上电后直接执行
  • 'timescale 1ns/1ps制定测试的单位是1ns,精度是1ps
  • #100指令指明延迟,单位由之前的代码指定
  • $stop指令使仿真停止
  • 时序逻辑:<=赋值;组合逻辑:=赋值

数据类型及常量,变量

常量

语法:<位宽>'<进制><数值>

进制表示

变量

  • nets type
  • register type
  1. nets type
    net型数据
    wire
    在这里插入图片描述
    在这里插入图片描述
  2. register type
    在这里插入图片描述
    以上后面三种数据不可以综合,主要用在算法级开发

reg

在这里插入图片描述

运算符

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

优先级

在这里插入图片描述

【重要】语句

part0 概述

  1. 赋值语句
  • 连续赋值语句:assign 语句
  • 过程赋值语句:always开头,@引导的一个铭感列表
  1. 条件语句
  • if-else
  • case

条件语句必须在顺序执行块中使用。所谓顺序执行是指由initial和always语句引导的执行语句集合。除了这两种语句引导的begin-end块中可以编写条件语句外,模块中的其他地方都不可以

  1. 循环语句
  • forever
  • repeat
  • while
  • for
  1. 结果说明语句
  • initial
  • always
  • task
  • function
  1. 编译预处理语句
  • define
  • include
  • timescale

part1 赋值条件语句详解

always过程块

always @(<敏感信号表达式>)
begin
...
end
  • always语句块不能嵌套
  • 在敏感信号表达式之前加posedge/negedge关键字可以指定上升沿或下降沿触发。否则每当列表表达式的值发生变化,就会执行数据块

initial过程块

  • initial过程块模拟上电后的行为,不可综合,常用与功能模拟初始化。写在测试文件(testbench)中
  • 同一模块的initial过程块,在上电时并行执行
  • initial过程块不能嵌套

连续赋值语句assign

  • assign语句用于对wire类型变量进行赋值
  • 等式左边wire变量随右边的值进行变化

过程赋值语句

  • 常用与对reg型变量赋值
  • 阻塞赋值(=)与非阻塞赋值(<=

在这里插入图片描述

  • 一个栗子
// For e.g.
...
always @(posedge clk)
begin
    b <= a
    c <= b
end
...
// 上升沿来前,假设b=1,a=2
// 则上升沿来时,b=2,c=1,即c获得b的旧值
// 原因是非阻塞赋值下,两个赋值语句并行执行
// 若将<=全部改为=,则c=2,因为阻塞赋值是顺序执行的

case语句

case (<敏感值表达式>)
    value_1: ...;
    value_2: ...;
    ...
    default: ...; //可省略
endcase

在这里插入图片描述

  • 敏感信号表达式的位置写*,综合器会推断表达式。推断的主要依据是赋值语句的右侧值

小结

语法要点

  • always里面赋值左边必须声明为reg

  • assign表达式左边必须声明为wire

  • 阻塞赋值用=

  • 非阻塞赋值用<=

  • 边沿触发生成寄存器的时序逻辑

  • 电平触发且条件完整,生成组合逻辑

  • 电平触发但条件不完整(写了if没写else,或case不完整),生成锁存器的时序逻辑

结论:

  • 如果是边沿触发逻辑,里面一律用<=
    比如always @(posedge clk),里面一律用<=赋值
  • 如果是电平触发逻辑,一律用=
    逻辑简单用assign;逻辑复杂用always语句
    分支条件写完整,防止出现锁存器

part2 循环语句详解

for语句(可综合)

for (<变量赋初值语句>; <条件表达式>; <变量增值语句>)
    循环体;

repeat语句

repeat语句用于仿真

语法:

repeat(<循环次数表达式>)
    循环体;

part3 结构语句详解

主讲functiontask
在这里插入图片描述

function(可综合)

function常用语实现简单的函数,module里可以调用function,而function在一定意义上相当于一个module

在这里插入图片描述
栗子
在这里插入图片描述
task(不可综合)

task常用与仿真验证,语句块里可以写各种高级语句
在这里插入图片描述
例子(例子中的task的作用是等待number_of_edges个下降沿)

在这里插入图片描述
function和task的不同

在这里插入图片描述
task中可以使用的高级系统函数

在这里插入图片描述

执行顺序

  • 顺序执行块:begin - end (例外:always语句块中用begin - end和非阻塞赋值<=时,这时是并行执行)
  • 并行执行块:fork - join

栗子
在这里插入图片描述
由于fork - join语句块是并行执行的,上图中的两个语句块描述的是同一个过程:
上电(系统启动)后50ns,r='h35';再过50ns,r='hE2';再过50ns,r='h00';以此类推。

延伸该例子,将语句块改为

fork
    begin
        #50 r='h35';
        #100 r='hE2';
    end
    #150 r='h00';
    #200 r='hF7';
    #250 r='h00';
end

则依据begin - end语句块的顺序执行性,r的值在150ns时是不确定的,因为同时有两个赋值发生。

简单总结,如果想要串行执行,需要满足两个条件:

  • begin - end语句块
  • 阻塞赋值=

最后

以上就是谨慎路灯为你收集整理的Verilog HDL学习笔记一、Verilog基本语法的全部内容,希望文章能够帮你解决Verilog HDL学习笔记一、Verilog基本语法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部