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

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仿真结果

在这里插入图片描述

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

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值