verilog HDL(3)

2019-03-10 23:28

【例2-5】 一个使用多种数据类型的程序片断。 integer M; reg[3:0]A; reg[7:0]B; initial begin

M=-1; //M为32位整数,采用补码形式存放,补码形式为32个1 A=M; //A为4位无符号数,截取M的低4位赋给A:1111 B=A; //B为8位无符号数,将A零扩展后送给B:00001111 B=A+14; //B为29:11101

A=A+14; //A+14为29,截取低4位送给A:1101 end

【例2-6】 存储器建模。 module rom(clk,rst,rd,data,addr); input clk,rst,rd; //rd为读使能信号

input[2:0] addr; //建立的存储器有8个地址空间 output reg[7:0] data; //数据是8位的

reg[7:0] memory[0:7]; //8× 8位数据的存储器 always @(posedge clk,posedge rst) if(rst) begin: init //该顺序块用于初始化ROM值 memory[0] = 8'b0000_0001; memory[1] = 8'b0000_0010; memory[2] = 8'b0000_0100; memory[3] = 8'b0000_1000; memory[4] = 8'b0001_0000; memory[5] = 8'b0010_0000; memory[6] = 8'b0100_0000; memory[7] = 8'b1000_0000; end else

begin: read //该顺序块用于读取ROM值 if(rd) data=memory[addr]; end endmodule

【例3-8】 表示组合逻辑的UDP举例:一位全加器。 全加器进位实现部分:

primitive U_ADD_C(CO, A, B, CI); output CO; input A, B, CI;

table // A B CI : CO 1 1 ? : 1; 1 ? 1 : 1; ? 1 1 : 1;

0 0 ? : 0; 0 ? 0 : 0; ? 0 0 : 0; endtable endprimitive

全加器求和实现部分:

primitive U_ADD_S(S, A, B,CI); output S;

input A, B, CI;

table // A B CI : S

0 0 0 : 0; 0 0 1 : 1; 0 1 0 : 1; 0 1 1 : 0; 1 0 0 : 1; 1 0 1 : 0; 1 1 0 : 0; 1 1 1 : 1; endtable endprimitive

调用上述两个UDP的全加器模块: module U_ADD(SUM,CO,a, b,ci); input a, b,ci; output SUM,CO;

U_ADD_S U1(SUM, a, b,ci); U_ADD_C U2(CO,a, b,ci); endmodule

3.2 结构化形式建模

在Verilog HDL中可使用如下方式描述结构: (1) 开关级原语(在晶体管级)——开关级建模。 (2) 内置门原语(在门级)——门级建模。 (3) 用户定义的原语。

(4) 模块实例(创建层次结构)。 3.2.1 门级建模

简单的逻辑电路可以使用逻辑门来设计实现。

基本的逻辑门分为两类:与/或门类、缓冲/非门类。 1. 与/或门类

与/或门类包括与门(and)、或门(or)、与非门(nand)、或非门(nor)、异或门(xor)、同或门(xnor)。与/或门类都具有一个标量输出端和多个标量输入端,门的端口列表中的第一个端口必定是输出端口,其他均为输入端口。当任意一个输入端口的值发生变化时,输出端的值立即重新计算。

3.3 数据流级建模

在电路规模较小的情况下,由于包含的门数比较少,因此使用门级建模进行设计不仅直观,而且方便。但是,如果电路的功能比较复杂,则通常该电路包含的逻辑门的个数会很多,这时使用门级建模不仅繁琐而且很容易出错。在这种情况下,如果从更高抽象层次入手,将设计重点放在功能实现上,则不仅能避免繁琐的细节,还可以大大提高设计的效率。

本节介绍更高抽象层次的建模方法:数据流建模。 3.3.1 连续赋值语句

以关键词assign开始的语句为连续赋值语句,连续赋值语句是Verilog数据流建模的基本语句,用于对线网进行赋值。

【例3-10】 使用数据流建模,实现一位半加器。 解题指引:半加器实现的是不带进位的两个数的相加,若半加器的输入为ain和bin,输出为sum和co,其中sum为和,co为进位,则半加器的真值表如表3-3所示。

Verilog HDL实现代码如下:

module adder_half(ain,bin,sum,co); input ain,bin; output sum,co;

assign {co,sum}= ain+bin; endmodule 程序说明: (1) assign {co,sum}= ain+bin; 是一条连续赋值语句,它将ain和bin的和存放在{co,sum}中。该语句中,“{ }”为位拼接符,其功能是将co和sum拼接成一个两位的数。

(2) 连续赋值语句的左边必须是一个标量或向量线网,或者是标量或向量线网的拼接,而不能是任何形式的寄存器。例如下面的形式是非法的:

reg sum;

assign {co,sum}= ain+bin; //非法,sum不能为寄存器类型 对连续赋值语句的进一步说明:

(1) 连续赋值语句的基本元素是表达式、运算符和操作数。其功能是计算右侧表达式的值,然后赋给左边变量。表达式由运算符和操作数构成,根据运算符界定的功能对操作数进行运算后得出结果。数据流的强大建模能力体现在多种运算符类型上。下一节我们将详细介绍运算符类型。

(2) 连续赋值语句总是处于激活状态。只要任意一个操作数发生变化,表达式就会被立即重新计算,并且将结果赋给等号左边的线网。

(3) 操作数可以是标量或向量线网,也可以是标量或向量寄存器。

3.4 行 为 级 建 模

Verilog HDL支持从算法的角度,即从电路外部行为的角度对其进行描述,因此行为

级建模是从一个很高的抽象层次来表示电路的。 在这个层次上进行数字系统设计类似于使用C语言编程,而且Verilog HDL行为建模的语法结构和C语言相当类似。Verilog HDL提供了许多行为级建模语法结构,为设计者提供了很大的灵活性。

3.4.1 结构化过程语句always

always语句是行为建模的基本语句,每个always语句代表一个独立的执行过程,也称为进程。与C语言不同,Verilog HDL的各个always进程是并发执行的,而不是顺序执行的。always语句包括的所有行为语句构成了一个always语句块。每个always语句块在满

足一定的条件后即执行其中的第一条语句,然后顺序执行随后的语句,直到最后一条语句执行完后,再次等待always语句块的执行条件,等条件满足后又从第一条语句开始执行,循环往复。因此,always语句通常用于对数字电路中一组反复执行的活动进行建模。

【例3-15】 使用always语句描述D触发器。 module mydff(q, clk, d); input clk, d;

output q; reg q;

always @(posedge clk) q<=d; endmodule

程序说明:(1) 本程序的功能是在时钟上升沿时刻,将数据d赋予触发器输出q,其功能同D触发器一样。

(2) always语句由于其不断重复执行的特性,只有和一定的时序控制结合在一起才有用。always @(posedge clk)语句表示只有在clk上升沿时才开始执行always语句块,否则不执行。这种时序控制是always语句最常用的。

(3) always 的时序控制除沿触发时序控制外,还可以是电平触发的,也可以是单个信号或多个信号,中间需要用关键字or 或“,”连接,如:

always @(posedge clock or posedge reset) //由两个沿触发的always块 begin ? end

always @( a or b or c ) //由多个电平触发的always块 begin ? end

沿触发的always块常用来描述时序逻辑,如果符合可综合风格要求,则可用综合工具将其自动转换为表示时序逻辑的寄存器组和门级逻辑;而电平触发的always块常用来描述一般组合逻辑和带锁存器的组合逻辑,如果符合可综合风格要求,则可转换为表示组合逻辑的门级逻辑或带锁存器的组合逻辑。一个模块中可以有多个always块,它们都是并行运行的。

3.4.2 过程赋值语句

过程赋值语句的更新对象是寄存器、整数等。这些类型的变量在被赋值后,其值将保持不变,直到被其他过程赋值语句赋予新值。

过程赋值语句与数据流建模中的连续赋值语句是不同的。首先,连续赋值语句总是处于活动状态,任意一个操作数的变化都会导致表达式的重新计算以及重新赋值,但过程赋值语句只有在执行到的时候才会起作用。其次,更新对象不同,连续赋值语句的更新对象是线网,而过程赋值语句的更新对象是寄存器、整数等。最后,从形式上看,过程赋值语句不使用assign。

但过程赋值语句与连续赋值语句又有相同之处,即两者可以使用的运算符是完全相同的。连续赋值语句中使用的运算符在过程赋值语句中同样适用,而且含义完全相同。

Verilog HDL包括两种类型的过程赋值语句:阻塞赋值语句和非阻塞赋值语句。 小结:?

门的基本类型包括与门(and)、或门(or)、与非门(nand)、或非门(nor)、异或门(xor)、同或门(xnor)、缓冲器(buf)和非门(not)等。 每种门都有逻辑符号、真值表和对应的Verilog HDL

原语。这些原语的调用方法和模块的调用方法一样,但这些原语是Verilog HDL预定义的(不需要自行编写)。门的任意一个输入发生变化以后,门的输出立即被重新计算。 ? 连续赋值语句是数据流建模的主要语法结构。连续赋值语句总是处于有效状态,即任一操作数的变化都会立即导致对表达式的重新计算。连续赋值语句的左侧必须是线网类型的变量或者拼接。任何逻辑功能都能够使用连续赋值语句来完成。

? 运算符的类型包括算术、关系、逻辑、按位、缩减、条件、移位和位拼接。单目、双目和三目运算符分别具有一个、两个和三个操作数,而拼接运算符可以具有任意多个操作数。

? 由于运算符的优先级被忽视或混淆而造成错误的情况经常发生。为了避免源于运算符优先级的运算错误,在不确定运算符优先级的情况下,建议读者使用小括号将各个表达式分开。另外,使用括号也可以提高程序的可读性,明确表达各运算符间的优先关系。

? 电路的门级描述、数据流描述、行为描述的抽象层次越来越高,但也越来越接近人的思维,方便设计者高效准确地进行系统设计。

? 利用任务和函数可以把一个很大的程序模块分解成许多较小的任务和函数,这样便于理解和调试。Veirlog HDL函数和任务在综合时被理解成具有独立运算功能的电路,每调用一次函数和任务,都相当于改变这部分电路的输入以得到相应的计算结果。学会使用task和function语句可以简化程序的结构,使程序明白易懂,是编写较大型模块的基本功。


verilog HDL(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2016年公需科目《心理健康与心理调适》考试试卷

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: