前言
对于同一功能多种不同实现方法的模块代码如何整合到一起呢?当然每种方法作为一个单独的模块使用一个.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)打开语法模板

(2)搜索generate: