Verilog HDL | 简介与基本语法

致谢:本笔记基于龚黎明的系列讲解视频

1 Verilog简介(Verilog语法学习者可跳过该节)

Verilog是一门类C语言


Verilog是一门类C语言,语法与C接近,但Verilog是硬件设计语言,与C实质不同。

  • Verilog代码对应硬件实体。比如在Verilog里写的a+b,最后会得到由硬件实现的加法器
  • Verilog代码到硬件的过程叫综合。综合就是将Verilog代码转化为硬件实现
  • Verilog并行执行

HDL: Hardware Description Language

Verilog HDL使硬件设计师们得以专注于逻辑,而不需要考虑硬件层面的实现。同样的代码只要经过不同的库综合,就可以在不同的硬件上运行。因此Verilog的代码具有极高的可复用性。

使用Verilog的绝大多数开发都处于寄存器传输级。

软核、固核与硬核


  • 软核(Softcore):功能经过验证的、可综合的、实现后电路结构总门数在5000门以上的Verilog HDL模型。
  • 固核:在某一种现场可编程门阵列(FPGA)器件上实现的,经验证是正确的总门数在5000以上的电路结构编码文件。
  • 硬核:在某一种专用的半导体集成工艺(ASIC)的器件上实现的,经验证是正确的总门数在5000以上的电路结构掩膜

显然,在具体实现手段和工艺技术尚未确定的逻辑设计阶段,软核具有最大的灵活性。因此,发展软核的设计和推广软核的重用技术是非常有必要的。

自顶向下(Top-Down)设计


(对上图的讲解:P2 | 2:55)

2 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[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

wire

  1. register type

上表的后面三种类型不可以综合,主要用在算法级的开发

reg

运算符


注:=====的区别在于怎么处理zx的位。一般来说用==就足够了

优先级

【重要】语句


Part 0 概述

  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语句

Part 1 赋值、条件语句详解

always过程块

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

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,因为阻塞赋值是顺序执行的

对于过程赋值语句,如果是边沿触发,我们在always语句块里用<=赋值,期望综合后生成寄存器;如果是电平触发,那么这个语句块实际上描述的是一段组合逻辑,我们使用=赋值,期望综合后不使用寄存器,而生成一个组合逻辑电路

case语句

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

执行哪一个语句块取决于敏感值表达式的值与哪一个情况(value_i)匹配,如果都不匹配,则执行default后面的语句

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

小结

语法要点:
(1) always里面赋值左边必须声明成reg(Verilog的语法规定。这一条引出了后续的很多要点)
(2) assign表达式左边必须声明成wire
(3) 阻塞赋值用=
(4) 非阻塞赋值用<=

(1) 边沿触发生成寄存器的时序逻辑
(2) 电平触发且条件完整,生成组合逻辑
(3) 电平触发但条件不完整(写了if没写else,或case不完整),生成锁存器的时序逻辑

结论:
声明成reg,不一定得到寄存器
声明成reg,也可能得到锁存器

Coding要点:

  • 如果是边沿触发的逻辑
    比如always @(posedge clk),里面一律用<=赋值

  • 如果是电平触发的逻辑,一律用=赋值
    逻辑简单用assign语句;逻辑复杂用always语句
    分支条件写完整,防治出现锁存器

Part 2 循环语句详解

for语句(可综合)

语法(和C一样):

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

repeat语句

repeat语句常用于仿真

语法:

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

Part 3 结构语句详解

主要讲解function(函数)与task(任务)

function(可综合)

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

例子

task(不可综合)

task常用于仿真验证,语句块里可以写各种高级语句

例子(例子中的task的作用是等待number_of_edges个下降沿)

function和task的不同

task中可以使用的高级系统函数

看到这里了?恭喜,你已经学会了Verilog的基本语法,你已经能够handle不少电路设计了!接下来是关于执行顺序的知识。设计一个电路,不仅要知道逻辑,也要知道执行顺序。

3 执行顺序

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

举一个例子(假设例子里的时间单位是ns),

由于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语句块
  • 阻塞赋值=

(完结撒花)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容