FPGA的设计艺术(24)强大的编译预处理指令
前言
在提高模块通用性的设计中,也叫可重用性,有好多种方式,例如:
FPGA的设计艺术(13)使用generate语句构建可重用的逻辑设计
FPGA的设计艺术(12)使用parameter构建可重用的逻辑设计
这些对技能的灵活应用,会让你的设计更加的游刃有余,当然,本篇想补充一个,编译预处理语句。
这是HDL中的一个不可或缺的分支,地位很高,无论是在仿真还是在设计中,灵活运行能极大方便你的设计与验证。
下面一起来看看。
编译预处理语句
编译预处理语句在大中型设计中比较常见,且今后也会进场遇到,它的应用能提高逻辑模块的可重用性,增强代码的可读性,它的特征是以符号:
`
开头。
例如最常见的:
`define CNT_LENGTH
`include"pipelined_multiplier.v"
`ifdef `else `endif
等等。
下面我们具体谈谈,结合例子,理解并实践。
条件编译
所谓的条件编译,就是上面的:
有如下几种形式:
(1)`ifdef 宏名(标识符)
程序段1
`else
程序段2
`endif
(2)`ifdef宏名(标识符)
程序段1
`endif
这种语句十分好用,很多时候比generate if更好用,例如我们的设计有很多功能模块,我们固然要将这些功能模块组合到一起,像搭积木一样,实现一个大型设计。
这势必导致综合,实现等过程时间过程,如果我们仅仅需要关注某一些模块,或者让某一些模块参与编译,那么我们就可以使用条件编译语句。
屏蔽了某些不必要的模块,做成的版本叫做小版本,这在调试的时候很重要,FPGA的开发,大型设计的编译需要十多个甚至更多时间,那么我们的调试版本制作就可以根据需要取舍一些模块,调试完成后,可以恢复,这就可以利用条件编译完成。
条件编译的实现,首先定义一个条件编译标志:
`define TX
`define RX
`define SUM
//...
在代码的主题部分,我们可以这样使用:
`ifdef TX
//定义变量
//例化模块
//或编写此功能块的逻辑
`endif
`ifdef RX
//定义变量
//例化模块
//或编写此功能块的逻辑
`endif
`ifdef SUM
//定义变量
//例化模块
//或编写此功能块的逻辑
`endif
当然,也可以利用它在仿真中发挥作用:
`ifdef SIMULINK_EN
integer cur_state_sw;
always@(*) begin
case(cur_state)
IDLE : cur_state_sw = "IDLE";
INIT: cur_state_sw = "INIT";
TRIG: cur_state_sw = "TRIG";
default: cur_state_sw = "IDLE";
endcase
end
`endif
这个例子想说明的是,当预定义了
`define SIMULINK_EN
后,你就可以定义一些,专门用于仿真的东西,例如上例中的状态值,当运行仿真的时候,我们可以在仿真波形中以字母的形式现实状态机,这样就不用盯着当前状态是某个值,1.,2,3,...,一点也不直观。
//或者
`ifdef SIM
parameter BEAM_LENGTH = 256;
parameter CNT_COUNT = 128;
//....
`else
parameter BEAM_LENGTH = 256565;
parameter CNT_COUNT = 128125;
`endif
这个例子说明的是,当我们的实际参数值比较大时,仿真会浪费时间,且不易观察,我们可以使用小的数值来仿真,观察趋势等等。
而又不想改数字,该数字之后,后面容易遗忘,而使用:define定义一个宏,是最省事的,也是很专业的一种做法。
还有一些有趣的例子:
例如模块需不需要某些变量的,例如复位等:
module my_design (input clk, d,
`ifdef INCLUDE_RSTN
input rstn,
`endif
output reg q);
always @ (posedge clk) begin
`ifdef INCLUDE_RSTN
if (!rstn) begin
q <= 0;
end else
`endif
begin
q <= d;
end
end
endmodule
对于条件编译也有一些变体,用法相反而已:
module tb;
initial begin
`ifndef MACRO1
$display ("This is MACRO1");
`elsif MACRO2
$display ("This is MACRO2");
`endif
end
endmodule
意思是如果你没定义某个宏,该语句就会参与编译。
文件包含
文件包含编译预处理指令也十分常用,特别在大型仿真平台搭建中,使用文件包含指令可以十分轻松调用其他模块的内容,而不需要让一个模块看起来十分臃肿。
在包含语句的使用中,不一定非要包含一个模块,还可以或常常包含一个文件,这个文件中定义了一些参数或者任意或函数等,供当前文件使用。
其等效关系如下:
上图使用了
`include "file2.v"
那么a就和c等价。
`include "versatile_counter_defines.v"
`define LFSR_LENGTH `CNT_LENGTH
`include "lfsr_polynom.v"
后面大家可以在实践中去尝试,相信有一定代码量之后,也会常常看到这种设计。
- 分享
- 举报
-
浏览量:7609次2021-02-07 00:59:28
-
浏览量:5021次2021-03-14 01:58:15
-
浏览量:5750次2021-02-14 01:58:16
-
浏览量:5623次2021-04-27 00:06:35
-
浏览量:4122次2021-03-12 23:39:20
-
浏览量:8945次2021-02-20 17:50:13
-
浏览量:4884次2021-05-15 23:39:10
-
浏览量:4397次2021-06-20 20:10:03
-
浏览量:4015次2021-03-13 01:55:14
-
浏览量:4995次2021-05-23 23:50:14
-
浏览量:6521次2021-03-14 02:34:44
-
浏览量:5270次2021-03-14 01:12:39
-
浏览量:6848次2021-03-15 23:18:36
-
浏览量:7309次2021-04-10 01:44:48
-
浏览量:8910次2021-03-21 22:58:26
-
浏览量:11463次2021-05-23 01:13:25
-
浏览量:4565次2021-05-17 23:44:33
-
浏览量:4766次2021-03-18 22:57:24
-
浏览量:5351次2021-03-17 23:24:53
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
李锐博恩
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明