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

fpga论坛|fpga设计论坛

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 42|回复: 3

Verilog HDL模块

[复制链接]
fpga_feixiang 发表于 2018-10-10 15:54:52 | 显示全部楼层 |阅读模式
一个复杂电路系统的完整Verilog HDL模型是由若干个Verilog HDL模块构成的,每一个模块又可以由若干个子模块构成。其中有些模块需要综合成具体电路,而有些模块只是与用户所设计的模块有交互联系的现存电路或激励信号源。利用Verilog HDL语言结构所提供的这种功能就可以构造一个模块间的清晰层次结构来描述极其复杂的大型设计,并对所作设计的逻辑电路进行严格的验证。


Verilog HDL行为描述语言作为一种结构化和过程性的语言,其语法结构非常适合于算法级和RTL级的模型设计。这种行为描述语言具有以下功能:

(1)、可描述顺序执行或并行执行的程序结构。

(2)、用延迟表达式或事件表达式来明确地控制过程的启动时间。

(3)、通过命名的事件来触发其它过程里的激活行为或停止行为。

(4)、提供了条件、if-else、case、循环程序结构。

(5)、提供了可带参数且非零延续时间的任务(task)程序结构。

(6)、提供了可定义新的操作符的函数结构(function)。

(7)、提供了用于建立表达式的算术运算符、逻辑运算符、位运算符。


Verilog HDL作为一种高级的硬件描述编程语言,与C语言的风格有许多类似之处。其中有许多语句如:if语句、case语句等和C语言中的对应语句十分相似。如果读者已经掌握C语言编程的基础,那么学习Verilog HDL并不困难。我们只要对Verilog HDL某些语句的特殊方面着重理解,并加强上机练习就能很好地掌握它,就能利用它的强大功能来设计复杂的数字逻辑电路系统。


2.1.简单的Verilog HDL模块

2.1.1. Verilog 语法简介


下面先介绍一个个简单的Verilog HDL程序,从中了解Verilog模块的特性。

module test_project_top( //模块名

input clk, // 时钟输入

input resetn, // 复位

input[7:0] a, //信号输入,信号a 位宽为8 bit

input[7:0] b, //信号输入,信号b 位宽为8 bit

input en, // 信号是能输入 信号en 位宽为1 bit

output reg [8:0] c, // 寄存器类型定义,信号输出 c为9bit

output reg [15:0] d // 寄存器类型定义,信号输出 d 为16bit


);

/*........*/ //.........表示注释部分,注释只是为了方便程序员理解程序,对编译是不起作用的。


/*一个 .v文件中主要由 一个或多个 module ... endmodule块组成

每个module块内包括:模块名,输入端口,输出端口,以及多个时序电路,组合电路等组成


*/

// 简单的时序电路组成

always@(posedge clk or negedge resetn)

begin

if(~resetn) // 或者 if(!resetn) 取 resetn 反

begin

d<=16'h0;

end

else

begin

if(en) // if en ==1 那么 d等于a*b+a/b;否则d<=0

d<=a*b+a/b; // + , - ,* ,/ 加减乘除

else

d<=0;

end

end

// 简单的组合电路

always@(a or b) // 只要其中a或b一个变化就执行always块内语句

begin

if(en) // verilog 语法 if ... else ...,在组合电路中一个if对应一个else,不能缺else,防止产生锁存器

c<=a*b+a/b;

else

c<=0;

end



wire[8:0] sum; // 常见变量定义类型:wire-线网型,reg-寄存器

assign sum =a+b; // 组合电路赋值,关键字 assign

wire[15:0] multy;

assign multy = (en ) ? a*b :0;// 如果 en ==1,那么 multy =a*b,否则multy =0;


wire e;

assign e =&a; // & 按位与

wire f;

assign f =|b;// | 按位或


wire [8:0] c_sum;

// 实例化模块

my_add u_add_top( // my_add 模块名 ,u_add_top 实例化名

.clk(clk), //端口连接输入

.resetn(resetn),//端口连接输入

.a(a),//端口连接输入

.b(b),//端口连接输入

.c(c_sum)//端口连接输出

);

endmodule


这个小程序表述了一个.v文件包含了常用的verilog语法,变量的定义类型包括:wire,reg等,常见的运算符号跟C语言中相同,理解较容易。在这个例子中存在着两个模块。模块test_project_top引用由模块my_add定义的实例部件u_add_top。模块test_project_top是顶层模块。模块my_add则被称为子模块。在实例部件u_add_top中,带 “.”的表示被引用模块的端口,名称必须与被引用模块my_add的端口定义一致,小括号中表示在本模块中与之连接的线路。


2.1.2、Verilog用于模块的测试


Verilog 还可以用来描述变化的测试信号。描述测试信号的变化和测试过程的模块也叫做测试平台(Testbench 或Testfixture),它可以对上面介绍的电路模块(无论是行为的或结构的)进行动态的全面测试。通过观测被测试模块的输出信号是否符合要求,可以调试和验证逻辑系统的设计和结构正确与否,发现问题及时修改。


下面我们来看一个Verilog的测试模块,


// 测试激励产生

`timescale 1ns / 1ps

module test_project_top_tb; // 测试文件模块名


// 信号测试激励,输入变量声明

reg clk ;

reg reset;


reg [7:0] a;

reg [7:0] b;

reg en;

// 输出变量声明


wire[8:0] c;

wire [15:0] d;


// 信号变量初始化 ,关键字 initial

initial

begin

clk =0;

reset =0;

a =0;

b =0;

en =0;

#1000; // 在1000 ns后 reset拉高

reset =1;

end


// 时钟生成

always #5 clk =~clk; //时钟周期 10ns ,每隔5ns 取反一次


always @(posedge clk)

begin // {$random} 为系统任务,它会产生一个随机数

#1 a= {$random}%256; // 产生随机的位信号流a和b ,%256为做模256运算

#3 b = {$random}%256; // 分别延迟1和3个时间单位后产生随机的位信号流a 和b

end


always #10000 en = !en; //产生周期为10000个单位时间的选通信号变化



// 实例化 被测试模块

test_project_top u_top(

.clk(clk), // 时钟输入

.resetn(reset), // 复位

.a(a), //信号输入,信号a 位宽为8 bit

.b(b), //信号输入,信号b 位宽为8 bit

.en(en), // 信号是能输入 信号en 位宽为1 bit

.c(c), // 寄存器类型定义,信号输出 c为9bit

.d(d) // 寄存器类型定义,信号输出 d 为16bit


);

endmodule
Sunlife 发表于 2018-10-10 17:47:07 | 显示全部楼层
                        
zhangyukun 发表于 2018-10-11 09:07:52 | 显示全部楼层
Verilog HDL模块
晓灰灰 发表于 2018-10-11 10:49:09 | 显示全部楼层
Verilog HDL模块
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

QQ|小黑屋|手机版|Archiver|FPGA论坛 ( 京ICP备10035964号  

GMT+8, 2018-10-19 16:36 , Processed in 0.168729 second(s), 22 queries .

至芯科技 Powered by Discuz X3.2

© 2001-2014 Comsenz Inc.

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