一通废话

首先得承认,我并不是主动拥抱顶层文件这套思路的,原因很简单,能用就行干嘛费劲搞那么多东西。起初知识点亮一个LED灯,整一个半加器的简单模拟,也确实根本用不上。后边工程有一定的负责度,例如设计数字时钟,LCD1602驱动设计等等,这个时候我就发现了层次化设计的一个便捷之处,在于他们方便复用,只需要定义好一个功能Module,可以在仿真 – 下板之间无缝衔接,增加了自己开发的效率,减少不必要的注释,感兴趣可以接着往下看。

另外自己上述两个工程博客连接:

为什么需要层次化设计

一图胜千言,引用野火开发板他们家的资料(文末备注)里说明复用的思想在哪个地方。举个例子,比如我现在定义了一个橙色的模块,我现在第一层(绿色)的需求是设计一个数字时钟,那么第二层拆分开就是定时1秒(蓝色),定时1分钟(橙色)、定时1小时(红色)。接着蓝色的定时1秒,我再通过其他小模块继续拆分。那么大家有没有想过一个问题,都是同样的计数/计时,秒钟/分钟/时钟不都是一样的吗,只不过一个是定时1秒,一个是60秒,一个是3600秒。是的,我们完全可以统一写一个定时模块(比如第三层蓝色功能模块1_1),改变定时的值(1/6/3600)即可。

也就是说,层次化的设计思想,其实就是拆分需求,减少重复代码统一集成一个公用的模块,这就达到了Module复用的功能。说起来非常高端,我们通过一个简单例子来说明下如何使用吧,时间才是检验真理的唯一标准。

怎么使用

首先要申明一点,目前入门FPGA的阶段属于非常非常,所有工程代码、工程逻辑都可能存在错误,希望各位同学老师能够指出,同时也参考了大量的互联网上优质内容,在这里一并感谢,基于这个原因也决定将核心逻辑进行共享。请勿做一切商业用途。接下来会以我在数字时钟那篇的博客,讲一讲大概的逻辑,具体实操大家可以移步数字时钟的那篇博客。

这里是引用

带大家看三个文件,第一个是功能模块长什么样;第二个是理解顶层文件Top.v长什么样,到底是怎么复用的;第三个是了解testbench文件是如何设计的,和顶层文件有什么区别。

clock1.v文件:

//数字时钟模块

module clock1(

sec,

min,

hour,

rst,

sys_clk_p,

sys_clk_n,

clk_out1,

led_out1,

led_out2

);

input rst;

input sys_clk_p; // Differential input clock 200Mhz

input sys_clk_n; // Differential input clock 200Mhz

output clk_out1;

output [7:0] sec,min;

output [7:0] hour;

output led_out1;

output led_out2;

reg [7:0] sec=0;

reg [7:0] min=0;

reg [7:0] hour=0;

reg [32:0] cnt;

reg clk_div;

reg led_out1;

reg led_out2;

//分频部分 50MHz - 1Hz

always @ ( posedge clk_out1 or posedge rst)begin

篇幅原因略去代码

end

// 秒钟部分

always @ ( posedge clk_div or posedge rst)begin

篇幅原因略去代码

end

//分钟部分

always @ ( posedge clk_div or posedge rst)begin

篇幅原因略去代码

end

// 时钟部分

always @ ( posedge clk_div or posedge rst)

篇幅原因略去代码

end

endmodule

这个模块该有的功能全都有,篇幅原因省去的代码其实都基本一个样。需要关注到的是这个module里边详细定义了sec、min、hour这三个变量,并且都是output类型。因为我们是对顶层设计的举例子,代码详细功能不在这里讲解。接下来一并看剩下两个文件。

Top.v文件

module TOP(

input rst,

input sys_clk_p,

input sys_clk_n,

output clk_out1,

output led_out1,

output led_out2

);

//***********差分时钟50MHz *****************************************

wire sys_clk_p;

wire sys_clk_n;

wire rst;

wire clk_out1;

//***********数字时钟****************************************

wire led_out1;

wire led_out2;

//时钟模块初始化

clock1 clock(

.led_out1(led_out1),

.led_out2(led_out2),

.rst(rst),

.sys_clk_p(sys_clk_p ),

.sys_clk_n(sys_clk_n ),

.clk_out1(clk_out1 )

);

//PLL分频的代码

endmodule

Testbench文件

`timescale 1ns / 1ns

module clock1_tb();

//***********??????*****************************************

reg sys_clk_p;

wire sys_clk_n;

reg rst;

wire clk_out1;

//***********??????*****************************************

wire [7:0] sec;

wire [7:0] min;

wire [7:0] hour;

wire led_out1;

wire led_out2;

//初始化系统时钟

initial begin

sys_clk_p = 1'b0;

略去代码

end

//数字时钟初始化

clock1 clock(

.led_out1(led_out1),

.led_out2(led_out2),

.sec(sec),

.min(min),

.hour(hour),

.rst(rst),

.sys_clk_p(sys_clk_p ),

.sys_clk_n(sys_clk_n ),

.clk_out1(clk_out1 )

);

//PLL时钟分频

endmodule

可以看两个文件夹,代码基本都是一模一样的,定义好端口(input/output/wire/reg等),初始化clock模块如何结束。

区别1:Top.v顶层文件没有申明sec/min/hour这几个端口,但testbench文件申明了;区别2:testbench文件需要初始化相关的值、时钟等,但Top.v文件不需要;

这里重点关注第一点,我们这里并不需要把sec、min、hour这三个寄存器变量输出(需要制定引脚),所以我们在Top.v文件里边不声明他的输入输出类型,但实际下板却并不影响clock功能的实现,因为模块的功能实现与否,和你是否声明并无关系。你申明了,他就展示出来,不声明他就不展示出来,但功能一直都在实现。

这样写的一个好处就是,我们只需要写好一个module文件,在仿真测试,以及下板验证的时候都能够很快、很简单地实现,而不用大量复制代码,在两头切换。

补充

在testbench文件我们对他进行声明了,当然了,因为我们仿真的时候需要这个变量来看看,初步确认他的功能是好的,实际下板我们并不需要把秒、分、时都输出出来(设想一个寄存器变量占8位,3个就是24位,并没有这么多引脚给你占用)。当然如果你有意为之,你也可以如下设置这三个变量,那么你便需要设置相关引脚并进行下一步。

此时的Top.v文件

module TOP(

output sec,

output min,

output hour,

…………

同上

);

wire [7:0] sec;

wire [7:0] min;

wire [7:0] hour;

//***********差分时钟50MHz *****************************************

同上

//***********数字时钟****************************************

同上

//时钟模块初始化

同上

//PLL分频的代码

同上

endmodule

不声明,但功能实现时候,引脚的截图:

不声明,功能也实现时候,引脚的截图:

总结

本文稍微介绍了下什么是层次化设计,举了个数字时钟的例子以数字时钟为例,讲了如何在顶层文件Top.v复用定义好的module(Testbench也可以理解为一种顶层文件);顶层文件选择性地不声明相关引脚,减少引脚使用;仿真申明引脚以便查看功能完整性和正确性;

参考

FPGA Verilog 开发实战指南 – 基于 Xilinx Artix7,野火(非常推荐这本书和他们家的白嫖资料);基于FPGA的数字时钟(使用vivado)基于FPGA的简易时钟(含verilog源码)

以上。

如果你觉得这篇文章对你有帮助,请为我点个赞谢谢 如果有遇到其他问题,也请在评论区留言

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: