FPGA的设计艺术(24)强大的编译预处理指令

李锐博恩 2021-04-27 00:05:09 4508

前言

在提高模块通用性的设计中,也叫可重用性,有好多种方式,例如:

FPGA的设计艺术(13)使用generate语句构建可重用的逻辑设计

FPGA的设计艺术(14)使用函数和任务提升逻辑的可重用性

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"

后面大家可以在实践中去尝试,相信有一定代码量之后,也会常常看到这种设计。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 89 8 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
李锐博恩
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区