Verilog语法之generate (for、 if、 case)用法


前言

对于同一功能多种不同实现方法的模块代码如何整合到一起呢?当然每种方法作为一个单独的模块使用一个.v 文件保存肯定是没有问题的,这个就不太便于后期的维护和使用。如果能将多种实现方法整合到一个模块保存在一个.v 文件,使用起来就更加的方便。方法肯定是有的,而且还不只一种。下面提供两种方式,宏定义法,和使用 generate -if 方法。

提示:以下是本篇文章正文内容,下面案例可供参考

一、宏定义

宏定义法相对比较好理解,通过不同的宏定义条件编译方式进行选择某种实现方式,实现的部分
代码如下。该种方法可通过修改模块代码的宏定义选择不同的方法,还算是比较方便的。

//`define AVERAGE //求平均法
//`define FORMULA //直接公式法
`define LUT //查找表法
module rgb2gray (
 clk,
 rst_n,
 rgb_valid,
 red_8b_i,
 green_8b_i,
 blue_8b_i,
 gray_8b_o,
 gray_valid
);
`ifdef AVERAGE //求平均法 GRAY=(R+B+G)/3=(R+B+G)*85)>>8
...//方法 1
`endif
`ifdef FORMULA //灰度转换公式 Gray = R*0.299+G*0.587+B*0.114
...//方法 2
`endif
`ifdef LUT//查找表方式
...//方法 3
`endif
endmodule

调用方法:
直接例化,使用哪个define将前面注释删除,其他define注释即可。

二、generate 方法

1. generate-if 方法

该种方式相对于宏定义条件编译来说更加方便,就是在模块被例化调用时,不管需要使用哪种方式都不需要去通过修改模块源代码方式去改变具体实现方法,直接在例化模块时就可通过重定义参数 PROC_METHOD 实现不同方法的设置。
模板如下:

   generate
      if (<condition>) begin: <label_1>
         <code>;
      end else if (<condition>) begin: <label_2>
         <code>;
      end else begin: <label_3>
         <code>;
      end
   endgenerate

代码如下(示例):

module rgb2gray
#(
 parameter PROC_METHOD = "AVERAGE" //"AVERAGE" :求平均法
 //or "FORMULA" :直接公式法
 //or "LUT" :查找表法
)
(
 clk,
 rst_n,
 rgb_valid,
 red_8b_i,
 green_8b_i,
 blue_8b_i,
 gray_8b_o,
 gray_valid
);
generate
 if (PROC_METHOD == "AVERAGE") begin: PROC_AVERAGE
//---------------------------------------------
//求平均法 GRAY = (R+B+G)/3=((R+B+G)*85)>>8
 //方法 1
//---------------------------------------------
 end
 else if (PROC_METHOD == "FORMULA") begin: PROC_FORMULA
//---------------------------------------------
//典型灰度转换公式 Gray = R*0.299+G*0.587+B*0.114=(R*77 + G*150 + B*29) >>8
 //方法 2
//---------------------------------------------
 end
 else if(PROC_METHOD == "LUT") begin: PROC_LUT
//---------------------------------------------
//查找表方式,可以省去公式法中乘法运算 Gray =(R*77 + G*150 + B*29) >>8,将 3 个分量乘以系数后的数值存储在 ROM 中
 //方法 3
//---------------------------------------------
 end
endgenerate
endmodule

调用方法:

 rgb2gray
 #(
 .PROC_METHOD("FORMULA") //"AVERAGE" :求平均法
 //or "FORMULA" :直接公式法
 //or "LUT" :查找表法
 )rgb2gray_average
 (
 .clk (clk ),
 . reset_p (reset_p ),
 .rgb_valid (rgb_valid ),
 .red_8b_i (red_8b_i ),
 .green_8b_i(green_8b_i),
 .blue_8b_i (blue_8b_i ),
 .gray_8b_o (gray_8b_o ),
 .gray_valid(gray_valid)
 );

1. generate-case方法

generate case和generate if作用上是差不多的,都是用于选择性综合电路,区别就是if语句和case语句的区别,如果你会用其中一个,那另一个也很简单,模板如下:

   generate
      case (<constant_expression>)
         <value>: begin: <label_1>
                     <code>
                  end
         <value>: begin: <label_2>
                     <code>
                  end
         default: begin: <label_3>
                     <code>
                  end
      endcase
   endgenerate

代码如下(示例):

module rgb2gray
#(
 parameter PROC_METHOD = "AVERAGE" //"AVERAGE" :求平均法
 //or "FORMULA" :直接公式法
 //or "LUT" :查找表法
)
(
 clk,
 rst_n,
 rgb_valid,
 red_8b_i,
 green_8b_i,
 blue_8b_i,
 gray_8b_o,
 gray_valid
);
generate
 case (PROC_METHOD )
    "AVERAGE": begin: PROC_AVERAGE
				//---------------------------------------------
				//求平均法 GRAY = (R+B+G)/3=((R+B+G)*85)>>8
				 //方法 1
				//---------------------------------------------
 				end
      "FORMULA"):begin: PROC_FORMULA
				//---------------------------------------------
				//典型灰度转换公式 Gray = R*0.299+G*0.587+B*0.114=(R*77 + G*150 + B*29) >>8
				 //方法 2
				//---------------------------------------------
				 end
       "LUT" :begin: PROC_LUT
				//---------------------------------------------
				//查找表方式,可以省去公式法中乘法运算 Gray =(R*77 + G*150 + B*29) >>8,将 3 个分量乘以系数后的数值存储在 ROM 中
				 //方法 3
				//---------------------------------------------
 				end
 endcase
endgenerate
endmodule

三、小知识(语法模板)

如果你是一个基于xilinx的开发者,可以使用vivado自带的语法模板:

1)打开语法模板
1
(2)搜索generate:
2

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C.V-Pupil

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值