【读书笔记】《Verilog数字系统设计教程》 第3章 模块的结构、数据类型、变量和基本运算符号(附思考题答案)

本文详细介绍了Verilog数字系统设计的基础知识,包括模块的结构(I/O声明、内部信号说明和功能定义)、数据类型(如数字、参数、wire型、reg型和memory型)以及运算符和表达式。通过实例讲解了参数传递、多层次模块的使用,并阐述了wire型和reg型变量的区别。此外,还探讨了在Verilog中如何使用assign语句、实例元件和always块来描述逻辑功能。内容深入浅出,适合初学者学习。
摘要由CSDN通过智能技术生成

※书目:Verilog数字系统设计教程(第四版)夏宇闻等编著
虚拟机:VMware -14.0.0.24051
环 境:ubuntu 18.04.1
脚 本:makefile(点击直达
应用工具:vcs 和 verdi


一、模块的结构

在这里插入图片描述

  一个模块有两部分组成,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。

(1)I/O声明的格式

在这里插入图片描述

(2)内部信号说明

  在模块内用到的与端口有关的wire和reg类型变量的声明。

//如:
reg  [width-1:0] R变量1,R变量2 ...;
wire [width-1:0] W变量1,W变量2 ...;

(3)功能定义

  在模块内,最重要的部分是逻辑功能定义部分,一般有三种方法:

  1. 用“assign”声明语句,如:assign a = b & c ;
  2. 实例元件,如:and #2 u1(q , a, b);
  3. 用“always”块,如:
always @ (posedge clk or posedge clr)begin
  if(clr) q <= 0;
  else if(en) q <= d;
end

二、数据类型、常量和变量

  Verilog一共有19种数据类型,常用的有reg型、wire型、integer型、parameter型,其他类型为:
在这里插入图片描述

(1)数字

整数在verilog中,整型常数有四种进制表达形式:

  • 二进制整数(b或B)
  • 十进制整数(d或D)
  • 十六进制整数(h或H)
  • 八进制整数(o或O)

数字表达式有3种:

  • <位宽>'<进制><数字>,一般都写成这个形式多一点,如:8’b00011010;
  • '<进制><数字>,这种省略了位宽的,则采用默认位宽(这由具体的机器系统决定,但至少为32位);'b01
  • <数字>,只有数字,则默认为十进制。如:3 = 32’b11

x和z值
  在数字电路中,x代表不定态,z代表高阻态。一个x可以用来定义十六进制数的4位二进制数的状态,八进制数的3位,二进制数的1位。z的表示方式和x类似,z还有一种表达方式,写作“?”,常用在case语句中。
在这里插入图片描述 负数
  一个数字可以被定义为负数,只需要在位宽表达式前加负号即可

在这里插入图片描述 下划线(underscore)
  下划线可以用来分隔开数的表达以提高程序可读性,但它不能用于位宽和进制之间。

在这里插入图片描述  当常量不说明位数时,默认值为32位,每个字母用8位ASCII值表示
在这里插入图片描述

(2)参数(parameter)型

  在verilog中,用parameter定义常量,被称为符号常量,可以提高代码的可读性和可维护性。在这里插入图片描述
在定义符号常量时,表达式只能包含数字或先前已经定义过的参数。
在这里插入图片描述

【例 3.1】参数传递

module Decode(A,F);
  parameter Width = 1,Polarity = 1;
  ...
endmodule

module Top;
  wire [3:0] A4;
  wire [4:0] A5;
  wire [15:0] F16;
  wire [31:0] F32;

  Decode #(4,0) D1(A4,F16);
  Decode #(5)   D2(A5,F32);
endmodule

  原来的Width和Polarity都是1,在Top模块实例化时,通过#(4,0),D1实际引用的参数分别为4和0;通过#(5),D2实际引用的参数为Width为5,Polarity保持不变,为1。


【例 3.2】多层次模块

在这里插入图片描述

`include "Top.v"
`include "Block.v"
`include "Annotate.v"
module Test;
  wire  W;
  Tpp T();
endmodule

module Top;
  wire W;
  Block B1();
  Block B2();
endmodule

module Block;
  parameter P = 0;
endmodule

module Annotate;
  defparam
    Test.T.B1.P = 2;
    Test.T.B2.P = 3;
endmodule

  在一个模块中改变另外一个模块的参数时,需要使用defparam命令,在做布线后仿真是,就是利用这种方法把布线延迟通过布线工具生成的延迟参数文件反标注(Back-annotate)到门级Verilog网表上。


(3)wire型

  在端口变量声明时,如果没指定类型,则默认为wire型。wire型信号可以做任何方程式的输入,也可以做“assign”语句或实例元件的输出。
在这里插入图片描述在这里插入图片描述

(4)reg型

  寄存器数数据存储单元的抽象,寄存器数据类型的关键字数reg,通过赋值语句可以改变存储器的值,其作用与改变触发器存储的值相当。reg型数据通常表示“always”模块内指定信号,常代表触发器。在“always”内,被赋值的每一个信号都必须定义为reg型。
在这里插入图片描述在这里插入图片描述
  对于reg型数据,器默认的初始值为不定值x,其赋值语句的作用就如同改变一组触发器的存储单元的值。reg型数据可以赋值正值,也可以赋值负值,但当一个reg型数据是一个表达式中的操作数时,它的值被当做无符号正值,例如当一个4bit的寄存器做表达式的操作数时,如果开始寄存器被赋值-1时,其实际值会被认为是-1的补码,即+15。

(5)memory型

  Verilog HDL通过对reg型变量建立数组对存储器建模,可以描述RAM型存储器、ROM存储器和reg文件。数组中的每一个单元通过一个数组索引进行寻址。在Verilog语言中,不存在类似于C语言中的对维数组。memory型数据是通过扩展reg型数据的地址范围来生成的。格式如下:
在这里插入图片描述在这里插入图片描述
  上面例子,使用了前面讲到的parameter,实际上这里表示256个16位的寄存器。
在这里插入图片描述
  在对memory赋值时,需要指定地址,比如:
在这里插入图片描述在这里插入图片描述


三、运算符及表达式

在这里插入图片描述

  • 单目运算符(unary operator):可以带一个操作数,操作数放在运算符的右边。
  • 双目运算符(binary operator):可以带两个操作数,操作数放在运算符的两边。
  • 三目运算符(ternary operator):可以带三个操作数,这三个操作数用三目运算符分隔开
    在这里插入图片描述

(1)基本算术运算符

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

(2)位运算符

在这里插入图片描述
  各个位运算符的真值表如下,其中,不同长度的数据进制位运算时,系统会自动将两者按右端对齐,位数少的操作数会在相应的高位用0填满
在这里插入图片描述

四、思考题

在这里插入图片描述

  1. 模块由几个部分组成?
    由描述接口和描述逻辑功能两部分组成。
  2. 端口分为几种?
    三种:输出口,输入口,输入/输出口。
  3. 为什么端口要说明信号的位宽?
    因为如果不说明信号的位宽可能会在信号发生改变时发生错误,不容易看出接收到的信号的数据宽度,就很难进行数据的处理。
  4. 能否说模块相当于电路图中的功能模块,端口相当于功能模块的引脚?
    可以那样说,每个模块都有特定的功能,而功能的实现就必须依靠具体的电路得以实现,端口是信号传递的通道,可以说是功能模块的引脚。
  5. 模块中的功能描述可以由哪几类语句或语句块组成?它们出现的顺序会不会影响功能的描述?
    用assign语句声明,用实例元件,用always块。它们出现的顺序不会影响到功能的描述。

  1. 这几类描述中的哪一种直接与电路结构有关?
    用实例元件直接与电路结构有关。
  2. 最基本的Verilog变量有哪几种类型?
    wire型、reg型、memory型。
  3. reg型和wire型变量的差别是什么?
    reg型变量是寄存器变量,wire型变量是连线型变量。两者根本性的差别在于reg型变量有个寄存器来存放变量,这个值只有变量发生改变时才会改变,否则保证原来的值不变,wire型变量的值不是确定的值。
  4. 由连续赋值语句(assign)赋值的变量是否能是reg类型的?
    可以是reg类型的变量。
  5. 在always模块中被赋值的变量能否是wire类型的?如果不能是wire类型的,那么必须是什么类型的?它们表示的一定是实际的寄存器吗?
    不能。必须是reg类型的变量,它们表示的不一定是实际的寄存器。

  1. 参数类型的变量有什么用处?
    参数类型的变量的好处是可以提高程序的可读性和可维护性。
  2. Verilog语法规定的参数传递和重新定义功能有什么直接的应用价值?
    可以用于定义延迟时间和变量宽度。
  3. 逻辑比较运算符小于等于“<=”和非阻塞赋值大于等于“<=”的表示是完全一样的,为什么Verilog在语句解释和编译时不会搞错?
    因为逻辑比较时“<=”两边是两个操作数,此时“<=”是双目运算符,而在非阻塞赋值时“<=”的右边是操作数,此时“<=”是单目运算符。
  4. 是否可以说实例引用的描述实际就是严格意义上的电路结构描述?
    不能实例引用的描述是在门级电路上加以描述的,和严格意义上的电路结构描述还是有点差距的。

作者:xlinxdu
版权:本文是作者读书整理的笔记,部分图片来源于参考教材,侵权联系删。
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xlinxdu

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值