在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1715|回复: 3

[原创] 【原创】​你必须要掌握的 Verilog语法知识点 | Verilog语法笔记私人总结版

[复制链接]
发表于 2020-3-4 17:24:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本文为明德扬原创及录用文章,转载请注明出处!
作者:轩工
1.1 概述

条目
说明
分类
1>>        面向设计的语句;        //        可综合。
2>>        面向测试的语句;        //testbench        ,不可综合。
特点
设计语句        assign        ,        always        ,模块例化,都对应实际电路,并行执行。
构造
640?wx_fmt=png.jpg

1.2 模块 Module

条目
说明
模块名(端口列表)
整个电路的外特性,抽象为黑盒子;
端口方向
input        ,        output        ;        inout        ;
端口类型
wire        ,        reg        ;
端口类型是        wire        时可以省略。
例:        input a        ;        //        端口方向为输入,类型默认为        wire;
640?wx_fmt=png.jpg


1.3 数据类型

      1.3.1 wire/reg        线网

wire        和        reg        都是线类型,工程上没区别;只是        always/initial        模块中输出定义需要为        reg        型;
注意:不要将        reg        类型与        D        触发器混淆,        reg        理解为因为代码所产生的。

例如:

wire [7:0] a; //        定义了        8        位的        wire        型数据
wireb; //        定义了        1        位的        wire        型数据
reg [3:0]sum        ;        //        定义了一个        4        位的        reg        型数据

1.3.2 常量

类型
格式
说明
parameter
parameter        数据名        =        表达式
parameterMSB = 7        ;       
//        定义参数        MSB        为常量        7        ;推荐大写;
常量
<        位宽        ><        进制        ><        数字>
二进制:        B        或        b        ;
十进制:        D        或        d        ;
八进制:        O        或        o        ;       
十六进制:        H        或        h        ;
8’b1010_1100 (‘b        表示二进制)       
下画线“        _”,        提高阅读性。
<        数字        >
默认十进制;
4        值逻辑
0        :        Logic Low
低电平;
1        :        Logic High
高电平;
x        :        Unknow        ;
不确定;
z        :        High Impedance        ;
高阻态;        //        三态门

1.4 运算符

     1.4.1 概述

运算符
说明
算术运算符
+        (        加        )        ,        -        (减),        *        (乘),        /        (除),        %        (取模);
每个运算符在电路中都是个模块,如加法器,减法器;
!注意:除法,除        2^n        ,是移位运算,
浮点运算就复杂了,因此浮点运算要专用除法器;
关系运算符
>, <, >=, <=        ,        ==        (相等), !        =        (不相等);
逻辑运算符
&&        (逻辑与)        . ||        (逻辑或)        , !        (逻辑非);
条件判断语句中,为避免歧义,逻辑运算符二边推荐为        1bit;
位运算符
&        (与),        |        (或),        ~        (非)        , ^        (异或)        ; ~^        (同或);
移位运算符
<<        (左移),        >>        (右移);
归约操作
&        ,        ~&        ,        |        ,        ~|        ,        ^, ~^;//unary reduction        ;
条件运算符
?:
拼接运算符
{}
//{3{a[0]}}:        代表        3        根同样的        a[0]        线,        {a[0],a[0],a[0]}

1.5 设计语句

    1.5.1 assign        (连续赋值)

实例
说明
assigny = ~ b        ;
assign out = a==1 && c==1        ;
assign f = sel        ?        a        :b        ;
>>        实现可以用布尔函数描述的组合逻辑电路;
>>“=”        后面可以是任何布尔函数;
>>        并行执行;
典型错误        1        :
assigna = b + a;
避免出现反馈电路:变为了不可知时序逻辑电路;
640?wx_fmt=png.jpg


1.5.2  always        (过程块)

a、赋值

赋值方式
说明
=        ,阻塞赋值
always @        (        a or b or C or …        )
begin
语句块(        =        ,        if        语句,        case        语句)
end
实现:组合逻辑电路;(注意!禁止用于时序逻辑电路)
always        块内,阻塞赋值:是顺序执行(类似        C        );
敏感表:        @        (        *        )        //“*”        自动添加相关输入信号;
避免出现        Latch        (锁存器)
分支语句(        if        语句,        case        语句)条件不满时,会在电路中自动生成锁存器来保存不满足条件的值,因此要补全        if-else,和        case        的        defalut        语句;
<=        ,非阻塞赋值
always @        (        posedge clk or negedge rst_n        )
begin
语句块(        <=        ,        if        语句,        case        语句)
end
实现:时序逻辑电路;(注意!禁止用于组合逻辑电路)
always        块内,阻塞赋值:并行执行;

b、if        语句

条目
说明
格式        1
if(        条件        )begin
语句        1;
语句        2        ;
end
else begin
语句        1        ;
语句        2        ;
end
格式        2
if(        条件        )begin
语句        1;
语句        2        ;
end
else if begin
语句        1        ;
语句        2        ;
end
else begin
语句        1        ;
语句        2
end
特点
分支语句,各个分支条件不同;顺序执行判断;
注意
if-else        成对使用;

c、case        语句

条目
说明
格式
case(        表达式        )
常量表达式        1:begin
语句;
end
常量表达式        2:begin
语句;
end
常量表达式        3:begin
语句;
end
default        :
语句;
endcase
特点
分支语句,各个分支条件相同;并行执行判断;
注意
default        语句不可省略;


d、代码        &        硬件

条目
说明
映射
赋值语句        ->        逻辑函数;        //        加法器,减法器等;
边沿型条件分支        -> D        触发器;
条件分支        ->        多路选择器;
示例
640?wx_fmt=png.jpg

1.5.3 模块例化


a、作用

系统设计时,建议遵循以下设计原则:

640?wx_fmt=png.jpg

b、常见的典型错误如下所示:

640?wx_fmt=png.jpg


1.5.4 全加器

全加器顶层:        w1        ,        w2        ,        w3        :模块之间连线;
640?wx_fmt=png.jpg
半加强:        2        种描述方法,如下:
640?wx_fmt=png.jpg

描述方式
描述方式
说明
位置关联
AND u1(a, b, and_out);
名字关联
AND u1(.a(a), .b(b), .o        (        and_out        )        ); //        推荐使用


1.6 测试语句
     
     1.6.1 结构

Testbench
640?wx_fmt=png.jpg
640?wx_fmt=png.jpg


1.6.2 特殊符号

语句
说明
`<        标识符        >
表示:
编译引导语,用于指导仿真编译器在编译时采取一些特殊处理;
编译引导语句一直保持有效,直到被取消或重写;
`timescale
`timescale <        时间单位        >/<        时间精度        >
例        1        :
`timescale 1ns/1ns //        时间单位        1ns        ;时间精度        1ns        ;
#2 //        延时        2 ×1=2ns        ;
#2.1//        延时        2.1 × 1 = 2.1ns,        精确到        1ns        ,为        2ns        ;
例        2        :
`timescale 1ns/100ps //        时间单位        1ns        ;时间精度        100ps        ;
#2 //        延时        2 ×1= 2ns        ;
#2.1//        延时        2.1 × 1 = 2.1ns,        精确到        100s        ,为        2.1ns        ;
`define

`include
`include “global.v”
包含另一个文件,完整拷贝过来;
`restall
把所有设置的编译引导恢复到缺省状态;

#<num>;
#10; //        延迟        10        个时间单位

  1.6.3 语句

语句
说明
initial
块语句:只执行一次,        always        循环执行;不可综合;
作用:
产生激励信号;
检查输出波形;
赋初值;
forever
//        产生周期信号:
intial begin
clk = 0        ;
forever
#10 clk = ~clk; //        时钟信号
end

1.6.4 系统任务和函数

条目
说明
$<        标识符>
表示        Verilg        的系统任务和函数
$time
当前的仿真时间
$display
显示信号值变化:只执行一次,打印当前时刻;
$display($time, “b% %b %b”        ,        rst,clk,dout);
$monitor
监视信号值变化:所有过程时刻;
$monitor($time, “b% %b %b”        ,        rst,clk,dout);
$stop
暂停仿真
$finish
结束仿真,释放电脑资源;

1.7 代码模板

      1.7.1 组合逻辑电路

条目
说明
assign
assign add_cnt = flag==1; //        用于简单的组合逻辑电路;
always
always @(*)begin//        统一采用“        *”        为敏感列表;
(        =,if,case        )语句;        //        只能使用“        =”        赋值
end

1.7.2 时序逻辑电路

a、计数器模板        1

3        段式模板
模板        1
1
计数段
always @( posedge cllk or negedge rst_n) begin
if (!rst_n)
cnt <= 0; //        初值规定为        0
else if (add_cnt)begin//        【位置        1        】
if(end_cnt)
cnt <= 0;
else
cnt <= cnt + 1;
end
end
2
加1        条件
assingadd_cnt = d==1; //d==1        :什么时候开始数脉冲
3
结束条件
assing end_cnt = add_cnt&& cnt == X-1; // X:        数多少个脉冲

b、计数器模板        2

3        段式模板
模板        1
1
计数段
always @( posedge cllk or negedge rst_n) begin
if (!rst_n)
cnt <= 0; //        初值规定为        0
else if (add_cnt) begin//        【位置        1        】
if(end_cnt)
cnt <= 0;
else
cnt <= cnt + 1;
end
else
cnt <= 0; //        不连续,需要清        0        时,使用模板        2        ;
end
2
加1        条件
assingadd_cnt = d==1; //d==1        :什么时候开始数脉冲
3
结束条件
assing end_cnt = add_cnt&& cnt == X-1; // X:        数多少个脉冲

c、 4        段式状态机模板

段号
代码
1
//        初始化,次态赋值给现态,明确当前状态;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
state_c <= S00;//        初始状态
else
state_c <= state_n;
end
2
always @( * ) begin //        组合逻辑,描述状态转换目标
case(state_c)
S00: begin
if(s00_s20_start) //        条件名        S00->S20
state_n = S20;
else
state_n = state_c; //        方便拷贝
end
S20: begin
if(s20_s21_start)
state_n = S21;
else
state_n = state_c;
end
S21: begin
if(s21_s00_start)
state_n = S00;
else
state_n = state_c;
end
default: begin
state_n = S00;
end
endcase
end
3
//        具体的转换条件内容
assign s00_s20_start = state_c==S00&& (        条件        )        ;
assign s20_s21_start = state_c==S20&& (        条件        );
assign s21_s20_start = state_c==S21&& (        条件        );
4
根据转态设计输出:
1        个        always        设计        1        个输出信号;



1.7.3 Testbench


a、框架

条目
内容
模块名
`timescale 1 ns/1 ns
module testbench_name();
信号定义
reg clk ; //        时钟
reg rst_n; //        复位
reg[3:0] din0 ; //uut        的输入信号 ,定义为        reg        型,在        initial中
reg din1 ;
wire dout0;//uut        的输出信号, 定义为        wire        型
wire[4:0] dout1;
parameter CYCLE = 20; //        参数定义,方便修改;
parameter RST_TIME = 3 ;
待测模块例化
module_name uut( //        统一采用名字关联
.clk ( clk ),
.rst_n ( rst_n ),
.din0 ( din0 ),
.din1 ( din1 ),
.dout0 ( dout0 ),
.dout1 ( dout1 )
);
激励产生
//        复位,时钟 ,等
显示输出结果
$display //        类似        printf        ;


b、复位

复位
initial begin
rst_n = 1;
#2;
rst_n = 0;
#(CYCLE*RST_TIME);
rst_n = 1;
end

c、仿真时钟

仿真时钟
initial begin
clk = 0;
forever
#(CYCLE/2)
clk=~clk;
end


d、激励信号

激励信号
initial begin
#1;//        方便观测
din1 = 0; //        赋初值
#(10*CYCLE);
//        开始赋值
end

以上就是本人总结的        verilog        语法相关知识点,当然明德扬还有很多比较简便的模板给我们使用,感兴趣的朋友可以进入明德扬论坛进行更多        FPGA        或者语法相关讨论!

发表于 2020-3-4 20:47:28 | 显示全部楼层
thanks
发表于 2023-12-15 14:44:39 | 显示全部楼层
thanks
发表于 2024-3-20 18:10:38 | 显示全部楼层
学到了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-29 02:48 , Processed in 0.029996 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表