Verilog中条件编译的使用(`ifdef-`elsif-`else-`endif)

2023-10-27

Verilog中条件编译的使用(`ifdef、`elsif、`else、`endif


  在Verilog程序的编写过程中,有一个疑问:在模块内部的程序编写时,我们可以用if-else if-else的语句进行判断在哪个条件下执行哪个操作,那么,对于模块的输入输出端口,是否有办法利用某个条件控制其输出或者是不输出呢?但是,if-else语句只可在谋爱内部代码的编写使用,于是,学习了 `ifdef- `elsif- `endif的条件编译语句

一、 概念

  一般情况下,Verilog HDL程序中,所有的程序都会参与编译。但是有时我们希望对其中的部分内容只有在条件满足时才进行编译,也就是对一部分的内容指定编译的条件,这就是“条件编译”。

二、格式

  条件编译的格式与条件语句的格式大致上是一致的,其格式如下所示。

2.1条件编译格式

`ifdef 宏名(标识符)
	程序段1
`elsif
	程序段2
`else
	程序段3
`endif

2.2条件语句

if(条件1)
	程序段1
else if(条件2)
	程序段2
else
	程序段3

三、应用示例

3.1顶层代码

  假如要将Data_Number个位宽为Data_Width并行输入的数据组合成一个数值,那么在这里数值的个数Data_Number是不确定的,我们可以设置一个控制信号来控制数据输入的个数,在这里用宏定义进行控制,具体代码如下。

`define		Data_Number_8		// or `define		Data_Number_16

module data_convert
#(
	parameter	Data_Width  = 8  ,
	parameter	Data_Number = 16 
)
(	
	input						clk,
	input						rst_n,
	input						start,
	`ifdef Data_Number_8
	input	[Data_Width-1:0]	data_1  ,
	input	[Data_Width-1:0]	data_2  ,
	input	[Data_Width-1:0]	data_3  ,
	input	[Data_Width-1:0]	data_4  ,
	input	[Data_Width-1:0]	data_5  ,
	input	[Data_Width-1:0]	data_6  ,
	input	[Data_Width-1:0]	data_7  ,
	input	[Data_Width-1:0]	data_8  ,
	`elsif Data_Number_16
	input	[Data_Width-1:0]	data_1  ,
	input	[Data_Width-1:0]	data_2  ,
	input	[Data_Width-1:0]	data_3  ,
	input	[Data_Width-1:0]	data_4  ,
	input	[Data_Width-1:0]	data_5  ,
	input	[Data_Width-1:0]	data_6  ,
	input	[Data_Width-1:0]	data_7  ,
	input	[Data_Width-1:0]	data_8  ,
	input	[Data_Width-1:0]	data_9  ,
	input	[Data_Width-1:0]	data_10 ,
	input	[Data_Width-1:0]	data_11 ,
	input	[Data_Width-1:0]	data_12 ,
	input	[Data_Width-1:0]	data_13 ,
	input	[Data_Width-1:0]	data_14 ,
	input	[Data_Width-1:0]	data_15 ,
	input	[Data_Width-1:0]	data_16 ,
	`endif
	
	output	[Data_Number*Data_Width-1:0]	data_out
);

reg		[Data_Number*Data_Width-1:0]	data_out_reg;


always @(posedge clk or negedge rst_n)
	if(!rst_n)
		data_out_reg <= 0;
	else if(start)begin
		`ifdef Data_Number_8
		data_out_reg[1  *Data_Width-1-:Data_Width] <= data_1  ;
		data_out_reg[2  *Data_Width-1-:Data_Width] <= data_2  ;
		data_out_reg[3  *Data_Width-1-:Data_Width] <= data_3  ;
		data_out_reg[4  *Data_Width-1-:Data_Width] <= data_4  ;
		data_out_reg[5  *Data_Width-1-:Data_Width] <= data_5  ;
		data_out_reg[6  *Data_Width-1-:Data_Width] <= data_6  ;
		data_out_reg[7  *Data_Width-1-:Data_Width] <= data_7  ;
		data_out_reg[8  *Data_Width-1-:Data_Width] <= data_8  ;		
		
		`elsif Data_Number_16
		data_out_reg[1  *Data_Width-1-:Data_Width] <= data_1  ;
		data_out_reg[2  *Data_Width-1-:Data_Width] <= data_2  ;
		data_out_reg[3  *Data_Width-1-:Data_Width] <= data_3  ;
		data_out_reg[4  *Data_Width-1-:Data_Width] <= data_4  ;
		data_out_reg[5  *Data_Width-1-:Data_Width] <= data_5  ;
		data_out_reg[6  *Data_Width-1-:Data_Width] <= data_6  ;
		data_out_reg[7  *Data_Width-1-:Data_Width] <= data_7  ;
		data_out_reg[8  *Data_Width-1-:Data_Width] <= data_8  ;
		data_out_reg[9  *Data_Width-1-:Data_Width] <= data_9  ;
		data_out_reg[10 *Data_Width-1-:Data_Width] <= data_10 ;
		data_out_reg[11 *Data_Width-1-:Data_Width] <= data_11 ;
		data_out_reg[12 *Data_Width-1-:Data_Width] <= data_12 ;
		data_out_reg[13 *Data_Width-1-:Data_Width] <= data_13 ;
		data_out_reg[14 *Data_Width-1-:Data_Width] <= data_14 ;
		data_out_reg[15 *Data_Width-1-:Data_Width] <= data_15 ;
		data_out_reg[16 *Data_Width-1-:Data_Width] <= data_16 ;		

		`endif
	end

assign		data_out = data_out_reg;

endmodule

3.2Test Bench

`timescale 1ns/1ps
`define		Data_Number_8		// or `define		Data_Number_16

module tb_data_convert();
parameter	Data_Width  = 8  ;
parameter	Data_Number = 8 ;   // 如果要修改为16个数,则这里也需要修改
reg		clk,rst_n,start;
reg		[Data_Width-1:0]	data_1,data_2,data_3,data_4,data_5,data_6,data_7,data_8,data_9,data_10,data_11,data_12,data_13,data_14,data_15,data_16;
wire	[Data_Number*Data_Width-1:0]	data_out;

initial begin
	clk = 1;
	start <= 0;
	rst_n = 0;
	
	data_1  <= 'd1 ;
	data_2  <= 'd2 ;
	data_3  <= 'd3 ;
	data_4  <= 'd4 ;
	data_5  <= 'd5 ;
	data_6  <= 'd6 ;
	data_7  <= 'd7 ;
	data_8  <= 'd8 ;
    data_9  <= 'd9 ;
    data_10 <= 'd10;
    data_11 <= 'd11;
    data_12 <= 'd12;
    data_13 <= 'd13;
    data_14 <= 'd14;
    data_15 <= 'd15;
    data_16 <= 'd16;
	
	#20
	rst_n = 1;
	#40
	start <= 1;
	
end

always #10 clk = ~clk;

data_convert
#(
	.Data_Width (Data_Width ),
	.Data_Number(Data_Number) 
)
data_convert_inst
(	
	.clk	(clk	),
	.rst_n	(rst_n	),
	.start	(start	),
	`ifdef Data_Number_8
	.data_1  (data_1  ),
	.data_2  (data_2  ),
	.data_3  (data_3  ),
	.data_4  (data_4  ),
	.data_5  (data_5  ),
	.data_6  (data_6  ),
	.data_7  (data_7  ),
	.data_8  (data_8  ),
 	`elsif Data_Number_16
	.data_1  (data_1  ),
	.data_2  (data_2  ),
	.data_3  (data_3  ),
	.data_4  (data_4  ),
	.data_5  (data_5  ),
	.data_6  (data_6  ),
	.data_7  (data_7  ),
	.data_8  (data_8  ),
	.data_9  (data_9  ),
	.data_10 (data_10 ),
	.data_11 (data_11 ),
	.data_12 (data_12 ),
	.data_13 (data_13 ),
	.data_14 (data_14 ),
	.data_15 (data_15 ),
	.data_16 (data_16 ),
	`endif
	
	.data_out(data_out)
);

endmodule

3.3仿真结果

在这里插入图片描述

注:以上仅为个人学习笔记,如有不妥之处,欢迎评论区探讨交流,如有帮助,请给个赞吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Verilog中条件编译的使用(`ifdef-`elsif-`else-`endif) 的相关文章

  • 数字IC手撕代码-兆易创新笔试真题

    前言 本专栏旨在记录高频笔面试手撕代码题 以备数字前端秋招 本专栏所有文章提供原理分析 代码及波形 所有代码均经过本人验证 目录如下 1 数字IC手撕代码 分频器 任意偶数分频 2 数字IC手撕代码 分频器 任意奇数分频 3 数字IC手撕代
  • 8x8LED点阵

    点量这个只需要把9高电平 13低电平就可以了 共阳极点阵 行线是led的正极 列线是led的列线 左上角点亮 显示多个灯是动态扫描的 一个一个显示的 然后间隔速度要快就可以造成显示 点阵由两篇74Hc595级联在一起驱动的 只需要三个io口
  • 平头哥(T-Head )开源RISCV处理器OpenC906 RTL仿真

    在过去的几年里 阿里集团平头哥陆续推出了几款RISCV处理器 有些处理器已经在产业界得到了应用 比如在某志的D1处理器中 就嵌入了平头哥的玄铁C906内核为 芯 RISCV虽然是一个开放标准 并且网络上也不乏一些开源核的RTL实现 但是商用
  • PLL时钟约束

    方法 1 自动创建基时钟和 PLL 输出时钟 例 derive pll clocks 这一方法使您能够自动地约束 PLL 的输入和输出时钟 ALTPLL megafunction 中指定的 所有 PLL 参数都用于约束 PLL 的输入和输出
  • 用Vscode编辑verilog代码配置

    这篇教程感觉很详细了 我这里分享一下vscode和插件的安装包链接 都是官网下载的 放心食用 用VSCode编辑verilog代码 iverilog编译 自动例化 自动补全 自动格式化等常用插件 链接 https pan baidu com
  • 最详细的Vivado安装教程

    V i v a d o 安 装
  • FPGA project : water_led

    module water led parameter MAX CNT 25 d25 000 000 input wire sys clk input wire sys rst n output wire 03 00 led signal r
  • 上拉电阻和下拉电阻

    一 定义 上拉电阻 将一个不确定的信号 通过一个电阻与电源VCC相连 固定在高电平 下拉电阻 将一个不确定的信号 通过一个电阻与地GND相连 固定在低电平 二 作用 提高输出信号驱动能力 确定输入信号电平 防干扰 限流 阻抗匹配 抗回波干扰
  • Verilog之assign

    Verilog中的关键词assign主要用于如下两个地方 数据流建模 用于数据流建模的显示连续赋值语句语法格式如下
  • 关于xilinx BRAM IP的延迟以及流程

    关于RAM IP的延迟 1 选择了output registers 可以在RAM输出端口添加register 也可以在core的输出添加 在primitives添加 降低clock to out到primitive的延迟 在core添加re
  • xilinx xdma PCIe中断bug

    xilinx xdma PCIe中断存在bug bug1 此中断虽然是msi或者msx中断 但是不中断cpu bug2 此中断不是边沿中断 而是电平中断 在驱动层需要不断地轮训查询中断事件 bug3 此中断持续时间必须长 而且在收到中断应答
  • FPGA_时钟显示(时钟可调)

    1 实验说明 在数码管显示数据的基础上 让六位数码管显示数字时钟 并且通过按键可以对时间进行修改 实验目标 六位数码管分别显示时间的时分秒 且通过按键可实现加减调整时间及清零功能 key1 切换键 选择待调整的时间单位 时 分 秒 key2
  • 【Xilinx Vivado时序分析/约束系列4】FPGA开发时序分析/约束-实验工程上手实操

    目录 建立工程 添加顶层 模块1 模块2 添加约束文件 编辑时钟约束 打开布线设计 代码代表的含义 时序报告 进行时序分析 Summary 包含了汇总的信息量 Source Clock Path 这部分是表示Tclk1的延时细节 Data
  • [HDLBits] Exams/ece241 2014 q7a

    Design a 1 12 counter with the following inputs and outputs Reset Synchronous active high reset that forces the counter
  • PAJ7620U2手势识别——配置0x00寄存器(3)

    文章目录 前言 一 为啥要配置0x00寄存器 二 配置步骤 1 单个读操作步骤图 2 模块状态转移图绘制 3 模块波形图绘制 4 上板验证 5 参考代码 总结 前言 在前面的教程中 小编带领各位读者学习了如何通过I2C协议去唤醒PAJ762
  • 【FPGA】通俗理解从VGA显示到HDMI显示

    注 大部分参考内容来自 征途Pro FPGA Verilog开发实战指南 基于Altera EP4CE10 2021 7 10 上 贴个下载地址 野火FPGA Altera EP4CE10征途开发板 核心板 野火产品资料下载中心 文档 hd
  • 【FMC141】基于VITA57.4标准的4通道2.8GSPS 16位DA播放子卡(2片DAC39J84)

    FMC141是一款基于VITA57 4标准的4通道2 8GSPS 2 5GSPS 1 6GSPS采样率16位DA播放FMC子卡 该板卡为FMC 标准 符合VITA57 4与VITA57 1规范 16通道的JESD204B接口通过FMC 连接
  • 【ZYNQ学习】PL第一课

    这节课讲什么 这节课的名字本来是想写为LED 但这一课里除了LED也有按键 又想换为GPIO控制 但关于PL的GPIO控制 不应该这么草率和简单 而且这一课有很多和ZYNQ或者PL关联性不强的东西要说 所以我写了删删了写改了好几遍 终于定为
  • 无线网络管理系统与无线路由器的区别

    第5章 波形发生器软件设计 本章我们将介绍系统的软件设计 系统中控制软件占有很重要的地位 它不仅要产生波形数据 控制波形的发生 还要控制显示电路和键盘电路 因此系统软件的好坏直接决定着系统的功能和稳定 5 1软件的总体结构 在本系统中 由于
  • ESP10B 锁定连接器

    ESP10B 锁定连接器 ESP10B 电机新增内容包括双极型号标准 NEMA 尺寸 17 23 和 34 的步进电机现在包括输出扭矩范围从 61 盎司英寸到 1291 盎司英寸的双极型号 该电机配有带锁定连接器的尾缆 可轻松连接 每转可步

随机推荐