【Verilog】条件编译指令

1. 条件编译指令介绍

 一般情况下,C语言中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译(conditional compile)。条件编译允许只编译源文件中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销,并提高程序的效率,可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。

Verilog的编译和C语言的编译二者自然不可同日而语,具体到FPGA的开发,其条件编译可以通俗的理解为,根据条件选择性地将指定部分综合为电路,而未被指定部分则不综合成电路,这可以有效地减少电路面积和提高代码的复用性和灵活性。

2. 条件编译指令实例

现在老板让我开发一个模块,功能是要能实现两个4bit输入的与、或、异或运算,但这三种运算不需要同时满足,也就是说在该模块的某次使用中或被调用中可能是使用或运算,也可能是使用与运算,具体是什么说不清楚,得看老板心情。

这还不简单?针对与、或、异或运算写三条语句,再给它加个选择器就完事了,就像这样:

module op_test(
    input        [3:0]    in1,
    input        [3:0]    in2,
    input        [1:0]    sel,
    output    reg    [3:0]    out
);
 
wire    [3:0] out_and;
wire    [3:0] out_or;
wire    [3:0] out_xor;
 
assign out_and = in1 & in2;
assign out_or  = in1 | in2;
assign out_xor = in1 ^ in2;
 
always@(*)begin
    case(sel)
        2'd0:    out = out_and;
        2'd1:    out = out_or;
        2'd2:    out = out_xor;
        default:out = out_and;
    endcase
end
 
endmodule

用vivado分析出来的电路是这样的:

嗯,完美满足老板要求。嘻嘻。

不料老板看了代码后,对着我劈头盖脸就是一顿臭骂:说了一次只会做一种运算,你给我弄3个运算模块干嘛?做或运算的时候,异或运算和与运算模块就站着看戏?节约资源懂不懂伐?性价比懂不懂伐?钞票懂不懂伐? 

虽然我内心立马条件反射般地对老板竖了个中指,但是仔细想想老板说的话也确实有道理,所以只好再找找其他办法。

找了半天还真给我找着了(不愧是我),这就是Verilog语法中的条件编译指令`ifdef, `ifndef,`else, `elsif, `endif。

3. 条件编译指令

条件编译指令可以根据指定条件来生成对应的电路,这可以减少电路面积并提高代码的复用性。

2.1  `ifdef 的使用

`ifdef 需要搭配 `endif 使用,其使用方法为:

`ifdef <define_name>
   <statements>;
`endif

  比如上面的例子(采用与运算时):

`define    OP_AND            //指定条件为与运算,标识符建议使用大写
//`define    OP_OR            //指定条件为或运算,标识符建议使用大写
//`define    OP_XOR            //指定条件为异或运算,标识符建议使用大写
 
module op_test(
    input        [3:0]    in1,
    input        [3:0]    in2,
    output        [3:0]    out
);
 
`ifdef OP_AND
    assign out = in1 & in2;    
`endif
 
`ifdef OP_OR
    assign out = in1 | in2;    
`endif
 
`ifdef OP_XOR
    assign out = in1 ^ in2;    
`endif
 
endmodule

用vivado分析出来的电路是这样的: 

可以看到,在希望进行与运算时,综合出来的电路已经只有与运算模块了,异或运算模块、或预算模块和选择器模块都没有被综合出来,这有效地减少了电路面积。

下一次,如果需要进行或运算,则只需要把  `define    OP_AND    这一句注释掉,再把这一句  `define    OP_OR  给有效化,此时就会综合出这样的电路(仅有或运算模块):

异或运算模块的使用则不赘述。

2.2、 `else 与 `elsif 的使用

在2.1节为了实现3个模块的条件编译,使用了三个`ifdef···`endif 块,这使得代码看起来很臃肿。就像你通常会使用 else if 和 else 来搭配 if 语句使用一样,你也可以使用  `else 与 `elsif 来搭配 `ifdef 使用。

`else 与 `elsif 的使用方法:

`ifdef <define_name>
   <statements>;
`elsif <define_name>
   <statements>;
`else
   <statements>;
`endif

所以,上面的例子可以改成这样的形式(采用与运算时):

`define    OP_AND            //指定条件为与运算,标识符建议使用大写
//`define    OP_OR            //指定条件为或运算,标识符建议使用大写
//`define    OP_XOR            //指定条件为异或运算,标识符建议使用大写
 
module op_test(
    input        [3:0]    in1,
    input        [3:0]    in2,
    output        [3:0]    out
);
 
`ifdef OP_AND
    assign out = in1 & in2;    
`elsif OP_OR
    assign out = in1 | in2;    
`else 
    assign out = in1 ^ in2;        
`endif
 
endmodule

2.3、 `ifndef 的使用

`ifndef 的作用与 `ifdef 是相反的----当其后的标识符未被定义时,则编译后续的代码段,Verilog语法:

`ifndef <define_name>
   <statements>;
`endif

举个例子,通过标识符 OP_OR 实现功能:如果OP_OR 未被定义,则实现两个输入的或运算;如果 OP_OR被定义,则实现两个输入的与运算。

       

不实现或运算(即实现与预算)情况的代码如下:

`define    OP_OR            //指定条件为或运算,标识符建议使用大写
 
module op_test(
    input        [3:0]    in1,
    input        [3:0]    in2,
    output        [3:0]    out
);
 
`ifndef OP_OR
    assign out = in1 | in2;    
`else 
    assign out = in1 & in2;        
`endif
 
endmodule

此时,定义了  OP_OR ,所以会执行第二句:assign out = in1 & in2;   

此时综合出来的电路:

 稍微修改一下,实现或运算情况的代码如下(仅注释掉了 `define    OP_OR):

//`define    OP_OR            //指定条件为或运算,标识符建议使用大写
 
module op_test(
    input        [3:0]    in1,
    input        [3:0]    in2,
    output        [3:0]    out
);
 
`ifndef OP_OR
    assign out = in1 | in2;    
`else 
    assign out = in1 & in2;        
`endif
 
endmodule

此时,未定义  OP_OR ,所以会执行第一句:assign out = in1 | in2;   

综合出来的电路:

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值