请选择 进入手机版 | 继续访问电脑版

明德扬论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信扫一扫,快捷登录!

查看: 4678|回复: 0

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

[复制链接]
发表于 2020-3-6 21:01:40 | 显示全部楼层 |阅读模式

马上注册,看完整文章,学更多FPGA知识。

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

x

私人总结版Verilog语法笔记

作者:轩工


本文为明德扬原创及录用文章,转载请注明出处
1.1 概述



1.png


1.2 模块Module



2.png


1.3数据类型1.3.1 wire/reg线网
wirereg都是线类型,工程上没区别;只是always/initial模块中输出定义需要为reg型;

注意:不要将reg类型与D触发器混淆,reg理解为因为代码所产生的。例如:


3.png


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

1.3.2 常量


类型
格式
说明
parameter
parameter数据名= 表达式
parameterMSB = 7
//定义参数MSB为常量7;推荐大写;
常量
<位宽><进制><数字>
二进制:Bb
十进制:Dd
八进制:Oo
十六进制:Hh
8b1010_1100 (b表示二进制)
下画线“_,提高阅读性。
<数字>
默认十进制;
4值逻辑
0Logic Low
低电平;
1Logic High
高电平;
xUnknow
不确定;
zHigh 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(连续赋值)


1.1.1 always(过程块)赋值



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


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成对使用;



case语句



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



代码&硬件



4.png


1.5.3 模块例化作用



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

5.png
常见的典型错误如下所示:
6.png

1.5.4 全加器


8.png


描述方式



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


1.6 测试语句

1.6.1 结构



9.png


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 时序逻辑电路计数器模板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:数多少个脉冲

计数器模板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:数多少个脉冲


模板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
根据转态设计输出:
1always 设计1个输出信号;




1.7.3 Testbench框架



条目
内容
模块名
`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


复位

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

仿真时钟

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


激励信号

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


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



FPGA视频课程  培训班 FPGA学习资料
吴老师 18022857217(微信同号) Q1241003385
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|MDYBBS ( 粤ICP备16061416号 )

GMT+8, 2024-3-29 15:56 , Processed in 0.088211 second(s), 25 queries .

Powered by Discuz! X3.4

本论坛由广州健飞通信有限公司所有

© 2001-2019 Comsenz Inc.

快速回复 返回顶部 返回列表