目录

  • 数字信号实际波形
  • Verilog语法规则(在之前的基础上补充)
    • 间隔符
    • 标识符
    • 常量表示规则
    • 字符串
    • 寄存器类型
    • 缩位运算符
    • 门级原件
    • 逻辑功能描述
    • 嵌套case语句语法及casez/casex
    • 数组
    • 字符串中的转义字符
    • 循环语句
      • while循环
      • for循环
      • repeat循环
      • forever循环
    • 块语句
      • 顺序块
      • 并行块
      • 命名块
      • 生成块
        • 循环生成语句
        • 条件生成语句
        • case生成语句

通过学习数字电子技术(康华光 华中科技大学)总结
大概是第1、2、4节有关Verilog的部分

数字信号实际波形

Verilog语法规则(在之前的基础上补充)

衔接之前的:FPGA学习笔记(二)Verilog初步入门

间隔符

不在字符串中的空格(\b)、TAB(\t)、换行符(\n)、换页符被忽略,所以写程序时可以跨越多行书写。

标识符

起名字可以用英文字母、下划线(这两个能开头)、数字、$组成的标识符

常量表示规则

+/- 位宽 基数符号 数值
分别对应正负、常量对应二进制数的宽度、定义后面数值的表示形式、数值左边为最高位,右边最低位。
+号一般省略
例子:3‘d2
代表数值范围:0~2的三次方即 0 ~ 8。此时数值为2(十进制)。

字符串

字符串是“ ”中间的字符序列,不允许多行书写,在表达式和赋值语句中,要转换成无符号整数,用8位的ASCII表示
例如:“ab”等价为 16’h5758,一个字符是8位,所以n个字符就定义为n*8位

这里使用串口助手要注意:

参考:ASCII码对照表

寄存器类型

除了我们常见的reg类型,还有其他三种

  • integer:32位带符号的整数型变量
  • real:64位带符号的实数型变量,默认值为0
  • time:64位无符号的时间型变量
    这三种是纯数学的表述,不会生成电路。reg一般是无符号的数来处理的。
    例子:
integer counter;
initialcounter=-1;

类似c语言,如果把实数类型(real)传递给integer时,只能保留整部部分,实数的小数部分会被舍弃。

  • 实数型常量的表达方式也可以用科学计数法表示
    例:
    23.51e2–>2351.0
    3.6E-1 —> 0.36

  • time型变量通常用来存储仿真时间
    例:

time current_time;
initial current_time=$time;  //利用系统函数获取当前仿真时间

缩位运算符

缩位运算符是单目运算符有:&、~&、|、 ~|、^、 ~ ^或者 ^ ~
分别是与、与非、或、或非、异或、同或
主要计算过程:第一步先将操作数的第一位与第二位进行或与非运算,第二步将运算结果与第三位进行或与非运算,依次类推,直至最后一位。
例:
A=4b‘1010
~^A=1
过程:(~1)^0=0,
(~0)^1=0,
(~0)^0=1,

门级原件


调用方法:

  • 多输入门:

A1是名字,可以省略。括号第一个参数必须是输出变量。
例子:

  • 多输出门:

    允许有多个输出,但只有一个输入,还是那个名字可以省略。
    例子:
  • 三态门:
    有一个输出、一个数据输入和一个输入控制。如果输入控制信号无效,则三态门的输出为高阻态z。 (l类似之前verilog入门文章里面的inout),调用名还可以省略。

例子:bufif1 B1(out,in,ctrl);

逻辑功能描述

!!!!!
主要是三种:利用基础门级电路、assign(连续赋值语句,也叫数据流描述方法)、initial/always(过程块语句结构,也叫行为描述方法)

例如:

第一种:

module mux2to1(D0, D1, S, Y );input D0, D1, S;  //定义输入信号output Y;    //定义输出信号wire Snot, A, B ; //定义内部节点信号数据类型
//下面对电路的逻辑功能进行描述not U1(Snot, Sl); and U2(A, D0, Snot);and U3(B, D1, S);or U4(Y, A, B);
endmodule

第二种:assign只能这种数据表达形式,不想always中,有语句可以用

module mux2to1_dataflow(D0, D1, S, Y );input D0, D1, S;  output Y;wire Y ;
//下面是逻辑功能描述assign Y = (~S & D0) | (S & D1); //表达式左边Y必须是wire型
endmodule

第三种:相当与把电路化出了最简单的状态,更高效了

module mux2to1_bh(D0, D1, S, Y );input D0, D1, S;  output Y;reg Y ;
//逻辑功能描述always @(S or D0 or D1) //任何输入信号的变化都会进入,括号里面的也叫敏感变量,也可以用*代替if (S == 1)  Y = D1;  //也可以写成 if (S)  Y = D1;else  Y = D0;   //注意表达式左边的Y必须是reg型
endmodule

不过现在都用别的方法定义模块了
例子:

module top_seg_led
(//global clockinput            sys_clk  ,       // 全局时钟信号input            sys_rst_n,       // 复位信号(低有效)output           led,        //1个LED灯//seg_led interfaceoutput    [5:0]  seg_sel  ,       // 数码管位选信号output    [7:0]  seg_led ,         // 数码管段选信号input              key         //按键信号
);

这里面的有位宽定义的一般不能去掉前面的output/input。如下:

module top_seg_led
(//global clockinput            sys_clk  ,       // 全局时钟信号sys_rst_n,       // 复位信号(低有效)key         //按键信号output           led,        //1个LED灯//seg_led interfaceoutput    [5:0]  seg_sel  ,       // 数码管位选信号output    [7:0]  seg_led ,         // 数码管段选信号);

2022.10.18更新

嵌套case语句语法及casez/casex

嵌套case语句:

case(A)1'b1:case(B)2'b0:begin x1=1'b1;x2=1'b0;end2'b01:begin x3=1'b1;x4=1'b0;end                  default:.........endcasedefault:.....
endcase

一个case语句不需要加begin end,像1‘b1里的。但是在具体的分支里面,多个语句还是要有begin end

casex/casez:
casez将比较双方表达式(分支表达式和case_expr控制表达式)中出现的z的位当作不用关心的位处理,在分支表达式中所有为z的位也可以用?代替。
casex则认为表达式中所有的z和x都是无关项

casex(I)8'b1xxx_xxxx:  //只要I的最高位i等于1就执行,相当if(I[7])y=3'd7;8'b01xx_xxxx: y=3'd6;8'b001x_xxxx: y=3'd5;8'b0001_xxxx: y=3'd4;8'b0000_1xxx: y=3'd3;      ...............8'b0000_0001:y=3'd0;default:.......

2022.10.22更新

数组

在 Verilog 中允许声明reg,integer,time,real,realtime及其向量类型的数组,对数组的维数没有限制。线网数组也可用于连接实例的端口,数组中的每个元素都可以作为一个标量或向量。

integer count [0: 7] ; //由8个计数变量组成的数组
reg bool[31:0] ;   // 由32个1位的布尔( boolean)寄存器变量组成的数组
reg [4:0] port_id[0:7]; //由8个端口标识变量组成的数组,端口变量的位宽为5
integer matrix [4:0][0:255] ; //二维的整数型数组
reg [63:0] array_4d [15:0][7:0][7:0][255:0] ;//四维64位寄存器型数组
wire [7:0] w_array2 [5:0] ;//声明8位向量的数组

下面有一些赋值例子:

matrix[1] [0] = 33559;//把数组中第1行第0列的整数型单元(32位)置为33559
array_4d[0] [0][0][0][15:0] = 0;//把四维数组中索引号为[0][0][0][0]的寄存器型单元的0~15位都置为0
matrix = 0 ; //非法,企图写整个数组
matrix [1] = 0;//非法,企图写数组的整个第2行,即从matrix[1] [0]直到matrix[1][255]

字符串中的转义字符

就是字符串中的%要写成%%才行


2022.10.23更新

循环语句

while循环

在while语句中可以使用各种操作符,并且可以用这些操作符构成任意的逻辑表达式。如果循环中有多条语句,则须使用begin和end。

while((i < 16) && continue ) //用操作符的多个条件构成while表达式
beginif (flag[i])begin$display ("Encountered a TRUE bit at element number %d",i);continue = 'FALSE;endi = i + 1;
end

for循环

初始条件和完成自加操作的过程赋值语句都包括在 for循环中。

for ( count=0; count < 128; count = count + 1)

repeat循环

repeat循环的功能是执行固定次数的循环,它不能根据一个逻辑表达式来确定循环是否继续进行。repeat循环的次数必须是一个常量、一个变量或者一个信号。如果循环重复次数是变量或者信号,循环次数是循环开始执行时变量或者信号的值,而不是循环执行期间的值。

//说明:从О增加到127计数并显示integer count;
initial
begincount = 0 ;repeat (128)begin$display ( "Count = %d",count) ;count = count + 1 ;end
end

forever循环

关键字forever用来表示永久循环。直到遇到系统任务$finish为止。如果需要从forever循环中退出,可以使用disable 语句。
通常情况下forever循环是和时序控制结构结合使用的。如果没有时序控制结构,那么仿真器将无限次地执行这条语句 ,并且仿真时间不再向前推进,使得其余部分的代码无法执行。

//例1:时钟发生器
//用forever循环,不用always块
reg clock;
initialbeginclock = 1'b0 ;forever #10 clock = ~clock; //时钟周期为20个单位时间end
//例2:在每个时钟正跳变沿处使两个寄存器的值一致reg clock;
reg x, y;
initialforever @(posedge clock) x = y;

块语句

顺序块

即begin end语句
一条一条语句顺序执行的,这里指的是阻塞赋值的情况下
在写仿真的时候,如果语句包括了延时控制,那么延时下一条语句要在前面这条延时处理完才能执行

//说明2:带延迟的顺序块reg x, y;
reg [1:0] Z, w;
initial
beginx= l'b0; //在仿真时刻o完成#5 y = l'b1;//在仿真时刻5完成#10 z = {x,y}; //在仿真时刻15完成#20 w = {y,x}; //在仿真时刻35完成
end

并行块

关键字fork和join声明,语句是并行执行的,但是要注意如果两条语句在同一时刻对同一变量进行操作,可能引起隐含的竞争,因为目前的仿真器无法正确的处理竞争,所以要避免这一写法。
例子:应用在仿真里面

//例1:带延迟的并行块reg x,y;
reg [1:0] z, w;
initial
forkx= 1 'b0; //在仿真时刻О完成#5 y = 1'b1; //在仿真时刻5完成#10 z = {x, y}; //在仿真时刻10完成#20 w = {y, x}; //在仿真时刻20完成
join

顺序块和并行块可以互相嵌套

命名块

和上面看两个并不是并列关系,但是同等重要。
命名块主要指给前面两种块起个名字,而且命名后的块里面的变量可以通过名字引用访问,也可以被禁用,停止执行。

//命名块
module top;initial
begin: block1 //名字为block1的顺序命名块
integer i; //整型变量i是block1命名块的静态本地变量
//可以通过层次名top.block1.i被其他模块访问
…
endinitial
fork : block2 //名字为block2的并行命名块
reg i; //寄存器变量i是block2命名块的静态本地变量
//可以通过层次名top.block2.i被其他模块访问
...
join

具体语法就是在之前的额块语句begin/fork后面加一个:,之后后面再跟上起的名字

Verilog通过关键字disable提供了一种终止命名块执行的方法。使用disable则可以禁用设计中的任意一个命名块。

//在(向量)标志寄存器的各个位中从低有效位开始查找第一个值为1的位1/从向量标志寄存器的低有效位开始查找第一个值为1的位
reg [15:0] flag;
integer i; //用于计数的整数initial
beginflag = 16'b 0010_0000_0000_0000;i = 0;begin: block1 // while循环声明中的主模块是命名块block1while(i < 16)beginif(flag[i])begin$display( "Encountered a TRUE bit at element number %d",i) ;disable block1; //在标志寄存器中找到了值为真的位,禁用block1endi = i + 1;endendend
end

生成块

当对向量中的多个位进行重复操作时,或者当进行多个模块的实例引用的重复操作时,或者在根据参数的定义来确定程序中是否应该包括某段Verilog 代码的时候使用生成块

循环生成语句

例如:对两个N位总线变量进行按位异或

//本模块生成两条N位总线变量的按位异或
module bitwise_xor (out, i0,i1);//参数声明语句。参数可以重新定义
parameter N = 32; //默认的总线位宽为32位
//端口声明语句
output [N-1:o] out;
input [N-1:0]i0,il;
//声明一个临时循环变量,该变量只用于生成块的循环计算。verilog仿真时该变量在设计中并不存在
genvar j;
//用一个单循环生成按位异或的异或门( xor)
generate for (j=0; j<N; j=j+1)begin: xor_loop
xor gl (out [j], i0[j], i1[j]);
end //在生成块内部结束循环
endgenerate //结束生成块//另外一种编写形式
//异或门可以用always块来替代// reg [N-1:0] out;
//generate for (j=0; j<N; j=j+1) begin: bit
//always (i0[j] or i1[j]) out [j] = i0[j] ^ i1[j];
// end
//endgenerate
endmodule

在仿真开始之前,仿真器会对生成块中的代码进行确立(展平),将生成块转换为展开的代码,然后对展开的代码进行仿真。
关键词genvar用于声明生成变量,生成变量只能用在生成块中;在确立后的仿真代码中,生成变量是不存在的;
生成变量的值只能由循环生成语句来改变;
循环生成语句可以嵌套使用。但是使用同一个生成变量作为索引的循环生成语句不能相互嵌套;
xor_loop是赋予循环生成语句的名字,目的在于通过它对循环生成语句中的变量进行层次化引用。因此,循环生成语句中各个异或门的相对层次名分别为: xor_loop[0].g1,xor_loop[1].g1,…,xor_loop[31].g1。

条件生成语句

利用if else来选择执行的模块

//有条件地调用(实例引用)不同类型的乘法器
//根据参数ao_width和al_width的值,在调用时引用相对应的乘法器实例
generate
if (a0_width <8)||(a1_width < 8)cla_multiplier # (ao_width,a1_width) mo (product,a0,ai);
elsetree_multiplier #(ao_width, 'a1_width)mo · (product,a0,al);
endgenerate //生成块的结束

case生成语句

//根据总线的位宽、调用(实例引用)相应的加法器
//参数卫在调用(实例引用)时可以重新定义
//调用(实例引用)不同位宽的加法器是根据不同的N来决定的generate
case (N)
//当N=1或2时分别选用位宽为1位或2位的加法器
l: adder_1bit adder1(co,sum,a0,al, ci) ; // 1位的加法器
2: adder_2bit adder2(co,sum,a0, a1,ci) ; //2位的加法器
//默认的情况下选用位宽为N位的超前进位加法器
default: adder_cla #(N) adder3(co,sum,a0,a1,ci);
endcase
endgenerate //生成块的结束

FPGA数字电子技术复习笔记(一)verilog语法规则补充(语法篇2)相关推荐

  1. 《数字电子技术》笔记

    <数字电子技术>笔记 绪论 第一章 信息和编码 第二章 逻辑代数 第三章 门电路 第四章 组合电路的逻辑与分析 第五章 触发器 第七章 可编程逻辑器件 绪论 什么是电子技术?是研究电子器件 ...

  2. 数字电子技术复习第一章

    1.1数字电路概述 1.1.1模拟与数字电路 模拟信号和数字信号 电子电路中的电信号可分为两类:一类是时间.数值上都连续变化的信号,任意时刻都有一个相对的值,称为模拟信号:另一类是时间和幅度都是离散( ...

  3. 数字电子技术复习第二章

    目录 2.1逻辑代数基础 2.1.1逻辑代数的基本运算 2.1.2逻辑代数的公式和运算法则 2.2逻辑函数表示方式 2.1逻辑代数基础 2.1.1逻辑代数的基本运算 逻辑代数中的变量称为逻辑变量,逻辑 ...

  4. 数字电子技术基础第三版杨志忠_阎石数字电子技术基础第6版笔记和课后习题详解...

    阎石<数字电子技术基础>(第6版)笔记和课后习题(含考研真题)详解 第1章 数制和码制 1.1 复习笔记 本章作为<数字电子技术基础>的开篇章节,是数字电路学习的基础.本章介绍 ...

  5. 数字电子技术——Verilog

    数字电子技术--Verilog Verilog 概述 基础概述 Verilog基本结构 Verilog基本的语法规则 词法规定 逻辑值集合 常量及表示 变量的数据类型 Verilog 运算符 门级建模 ...

  6. 《数字电子技术课程设计》课程笔记(二)————multisim仿真模拟

    仿真源文件:链接:百度网盘 请输入提取码 提取码:1234 一.前言 对于一个完整的设计过程而言,仿真是一个必不可少的过程,因为仿真给了你一个重要的数据参考,信心来源,在之后的硬件设计过程中,心中的引 ...

  7. 《数字电子技术基础》6.4 时序逻辑电路——设计方法(FSM)有限状态机

    前言 <数字电子技术基础>第6.4节学习笔记,本人在编写Verilog时序逻辑代码时,关于这一部分的状态图需要好好学一下. 6.4.1 同步时序逻辑电路的设计方法 一般步骤 一.逻辑抽象, ...

  8. 数字电子技术实验作业(1)西科大

    数字电子技术实验作业(1) 1.(单选题)预习 视频我们"电子技术实验课"的特色有几个? 4个. 2.(单选题)"AATEt"的中文含义是什么? 自动化辅助教学 ...

  9. 【知识点总结】数字电子技术(数电)

    数字电子技术 总结内容: 内容包括: 本逻辑门(与.或.与非.或非.异或门).三态门.OD门(OC门).传输门 .组合逻辑电路的分析方法和设计方法.编码器.译码器.数据选择器.数值比较器.加法器.锁存 ...

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

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

最新文章

  1. 大前端晋级系列之-策略模式
  2. codeforces229 D. Towers(dp+贪心)
  3. [react] 说说react diff的原理是什么
  4. Java IO ---学习笔记(数据流)
  5. 可以自定义公式的计算器_Excel万能个税计算器,税率对比显示,自定义增税点自动计算结果...
  6. WCF入门学习3-配置文件与部署iis
  7. html 360 浏览器图片自适应,360浏览器看图模式 一键保存高清套图
  8. 一维和二维傅里叶变换的图片直观理解
  9. 通过AT指令将air202 接入阿里云
  10. 百度年龄计算机在线使用,百度年龄计算器app
  11. vue 百度地图获取经纬度地址
  12. 最新哔哩哔哩视频弹幕播放器源码+带后台/亲测无错误
  13. 笔记:PoseCNN:A Convolutional Neural Network for 6D Object Pose Estimation in Cluttered Scenes
  14. cpp mysql_使用MYSQLCPPCONN连接MYSQL数据库与读写BLOB字段
  15. 【C Primer Plus】温度转换器
  16. XMind软件非试用版本下载(亲测有效)
  17. 引起短波通讯服务器终端,短波通信终端设备
  18. c语言摄氏度变为温度用int,C语言打印华氏-摄氏温度对照表的方法
  19. 轻松搞定java高薪
  20. 开源堡垒机jumpserver及麒麟堡垒机安装

热门文章

  1. [讨论] 1.虚拟设备驱动程序初步
  2. SEO人员,不要见风是雨
  3. easy2game使用教程_Easy2game什么用
  4. 【C++游戏引擎Easy2D】基于基础类型学习使用核心Game+Window+Input详解
  5. hp服务器修改风扇转速,如何改变惠普笔记本风扇转速
  6. 以撒的结合:胎衣+(启示录Revelations MOD)不起作用失效(道具可以捡但是没作用失效等)
  7. Visual Studio 2015 专业版安装方法
  8. 基于java的图书管理系统(英文)
  9. 小米随身wifi没有网络显示无服务器,小米随身wifi创建失败如何解决_小米随身wifi网络创建失败的解决教程...
  10. 【官方】下载最新adb及安装驱动的方法