基礎項目(7)generate語句塊的講解


寫在前面的話

在設計中很多情況下我們需要編寫很多結構相同參數不同的賦值語句或邏輯語句塊當參數量很大的情況下原始的列舉就會變得很笨拙甚至是不可行的C語言處理這種問題通常情況下會使用如for循環語句來完成多次的相同操作。而verilog 語言呢?同樣的為我們提供了generate語句塊來幫助我們完成這些過程。接下來,夢翼師兄將和大家一起開始generate語句的學習

基本概念

generate的主要功能就是對modulenetregparameterassignalwaystaskfunction進行復制,genvargenerate語句中的一種變量類型,用以在 generate-for 語句中聲明一個正整數的索引變量 (如果將“X”或“Z”或者“負值”賦給genvar 變量將會出錯)。genvar 變量可以聲明在 generate 語句內,也可以聲明在 generate 語句外。

generate 語句有 generate-forgenerate-if generate-case 三種語句,下面夢翼師兄和大家一起來學習這三種語句。

 

 genrate-for

 

使用generate_for的時候,必須要注意以下幾點要求:

 

a) 必須使用genvar申明一個正整數變量,用作for的判斷變量;

 

b) for里面的內嵌語句,必須寫在begin_end里面,哪怕只有一句

 

c) begin_end需要一個名字。

 

 

 

1:利用generate_for來復制assign語句

 

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ             :   761664056

 *   E_mail        :   zxopenwjf@126.com

 *   The module function : generate_for_assign模塊

*****************************************************/

01  module for_test(indata, t0, t1, t2, t3);

02

03  input [7:0] indata;            //輸入8位位寬indata

04  output [1:0] t0, t1, t2, t3; //輸出2位位寬t0,t1,t2,t3;

05                               

06  wire [1:0] temp [3:0];        //定義位寬為2,深度為4temp

07  genvar i;                  

08                               

09  generate for(i=0; i<4; i=i+) //generate for模塊復制

10      begin : gfor_block    

11          assign temp[i] = indata[2*i+1:2*i];

12      end                      

13  endgenerate                 

14                                

15  assign t0 = temp[0];            //t0等於temp[0]

16  assign t1 = temp[1];            //t1等於temp[1]   

17  assign t2 = temp[2];            //t2等於temp[2]

18  assign t3 = temp[3];            //t3等於temp[3]

19

20  endmodule

 

 編寫的測試代碼如下:

 

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ            :   761664056

 *   The module function :for_test的測試模塊

*****************************************************/

01  `timescale 1ns/1ps

02  module tb;

03

04  reg [7:0] indata;          //輸入8位位寬indata

05  wire [1:0] t0, t1, t2, t3; //輸出2位位寬t0,t1,t2,t3;

06  

07//----------寫入2組數據------------

08  initial

09      begin

10          indata = 8'b1011_1011;

11          #100 indata = 8'b0101_1010;

12      end

13      

14 //---------模塊例化--------------

15  for_test for_test(

16   .indata(indata),

17   .t0(t0),

18   .t1(t1),

19   .t2(t2),

20   .t3(t3)

21   );

22

23  endmodule 

 

仿真波形如下:

觀察波形可以得到:

temp[0] = indata[1:0];

temp[1] = indata[3:2];

temp[2] = indata[5:4];

temp[3] = indata[7:6];

由此得出for_test模塊9~13行可以這樣展開:

assign temp[0] = indata[1:0];

assign temp[1] = indata[3:2];

assign temp[2] = indata[5:4];

assign temp[3] = indata[7:6];

我們發現,這段代碼是通過i增加來重復執行temp[i] = indata[2*i+1:2*i] 這條語句的所以generate_for可以復制assign語句。

 2:利用generate_for來復制always語句

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ             :   761664056

 *   The module function : generate_for_always模塊

*****************************************************/

01  module for_test1(indata, t0, t1, t2, t3);

02

03  input [7:0] indata;          //輸入8位位寬indata

04  output [1:0] t0, t1, t2, t3; //輸出2位位寬t0,t1,t2,t3;

05                               

06  reg [1:0] temp [3:0];        //定義位寬為2,深度為4temp

07  genvar i;                    

08                               

09  generate for(i=0; i<4; i=i+)//generate for模塊復制

10      begin : gfor_block       

11          always @ (*)         

12              temp[i] = indata [2*i+1:2*i]

13      end                      

14  endgenerate                  

15                               

16  assign t0 = temp[0];            //t0等於temp[0]

17  assign t1 = temp[1];            //t1等於temp[1]   

18  assign t2 = temp[2];            //t2等於temp[2]

19  assign t3 = temp[3];            //t3等於temp[3]

20

21  endmodule

 編寫的測試代碼如下:

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ             :   761664056 *   The module function :for_test1的測試模塊

*****************************************************/

01  `timescale 1ns/1ps

02  module tb;

03

04  reg [7:0] indata;          //輸入8位位寬indata

05  wire [1:0] t0, t1, t2, t3; //輸出2位位寬t0,t1,t2,t3;

06  

07//----------寫入2組數據------------

08  initial

09      begin

10          indata = 8'b1011_1011;

11          #100 indata = 8'b0101_1010;

12      end

13      

14 //---------模塊例化---------------

15  for_test1 for_test1(

16   .indata(indata),

17   .t0(t0),

18   .t1(t1),

19   .t2(t2),

20   .t3(t3)

21   );

22

23  endmodule 

仿真波形如下:

 

觀察波形可以得到:

temp[0] = indata[1:0];

temp[1] = indata[3:2];

temp[2] = indata[5:4];

temp[3] = indata[7:6];

由此得到for_test1模塊第9~14行我們可以這樣展開

always @ (*)

temp[0] = indata[1:0];

always @ (*)

temp[1] = indata[3:2];

always @ (*)

temp[2] = indata[5:4];

always @ (*)

temp[3] = indata[7:6];

我們發現,這段代碼是通過i增加來重復執行

always @ (*)

temp[i] = indata[2*i+1:2*i]

這條語句的所以generate_for可以復制always語句。

 3:利用多個generate_for來實現模塊復制

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ            :   761664056

 *   The module function : generate_for_多個模塊

*****************************************************/

01  module for_test2(indata, t0, t1, t2, t3);

02  

03  input [7:0] indata;               //輸入8位位寬indata

04  output [1:0] t0, t1, t2, t3;    //輸出2位位寬t0,t1,t2,t3;

05  

06  wire [1:0] temp [3:0];          //定義位寬為2,深度為4temp

07  genvar i, j;

08  

09  generate for(i=0; i<4; i=i+1)   //generate for模塊復制

10      begin : gfor_block_a        

11          for(j=0; j<2; j=j+1)    

12              begin : gfor_block_b

13                  assign temp[i][j] = indata[2*i+j];

14              end

15      end

16  endgenerate

17  

18  assign t0 = temp[0];            //t0等於temp[0]

19  assign t1 = temp[1];            //t1等於temp[1]   

20  assign t2 = temp[2];            //t2等於temp[2]

21  assign t3 = temp[3];            //t3等於temp[3]

22  endmodule

 編寫的測試代碼如下:

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ             :   761664056

 *   The module function :for_test2的測試模塊

*****************************************************/

01  `timescale 1ns/1ps

02  module tb;

03

04  reg [7:0] indata;          //輸入8位位寬indata

05  wire [1:0] t0, t1, t2, t3; //輸出2位位寬t0,t1,t2,t3;

06  

07//----------寫入2組數據------------

08  initial

09      begin

10          indata = 8'b1011_1011;

11          #100 indata = 8'b0101_1010;

12      end

13      

14 //---------模塊例化---------------

15  for_test2 for_test2(

16   .indata(indata),

17   .t0(t0),

18   .t1(t1),

19   .t2(t2),

20   .t3(t3)

21   );

22

23  endmodule 

仿真波形如下:

 

 

觀察波形可以得到:

temp[0] [0] = indata[0];

temp[0] [1] = indata[1];

temp[1] [0] = indata[2];

temp[1] [0] = indata[3];

temp[2] [0] = indata[4];

temp[2] [1] = indata[5];

temp[3] [0] = indata[6];

temp[3] [1] = indata[7];

由此得到for_test2模塊第9~16行可以這樣展開

assign temp[0] [0] = indata[0];

assign temp[0] [1] = indata[1];

assign temp[1] [0] = indata[2];

assign temp[1] [0] = indata[3];

assign temp[2] [0] = indata[4];

assign temp[2] [1] = indata[5];

assign temp[3] [0] = indata[6];

assign temp[3] [1] = indata[7];

我們發現,這段代碼是通過ij的增加來重復執行

temp[i][j] = indata[2*i+j]

這條語句的所以generate_for可以實現模塊的復制

genrate-if

generate_for是用於復制模塊,而generate_if則是根據模塊的參數(必須是常量)作為條件判斷,來產生滿足條件的電路。如

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ             :   761664056

 *   The module function : generate_if模塊

*****************************************************/

01  module if_test(a,  b,  c,  d);

02

03  input a, b, c;         //輸入信號abc

04  output d;               //輸出信號d

05

06  localparam WIDE = 8;    //參數模塊,用於選擇產生的電路

07

08  generate

09      if(WIDE <10)        //WIDE小於10d等於abc相或

10          assign  d   =   a | b | c;

11      else                //WIDE大於等於10d等於abc相與

12          assign  d   =   a & b & c;

13  endgenerate

14

15  endmodule

該代碼生成的RTL電路圖如下:

 

 

當把WIDE改成等於12的時候,代碼如下:

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ            :   761664056

 *   The module function : generate_if模塊

*****************************************************/

01  module if_test(a,  b,  c,  d);

02

03  input a, b, c;         //輸入信號abc

04  output d;               //輸出信號d

05

06  localparam WIDE = 12;    //參數模塊,用於選擇生產的電路

07

08  generate

09      if(WIDE <10)        //WIDE小於10d等於abc相或

10          assign  d   =   a | b | c;

11      else                //WIDE大於等於10d等於abc相與

12          assign  d   =   a & b & c;

13  endgenerate

14

15  endmodule

 

該代碼生成的RTL電路圖如下:

 

 

從上面2個不同的WIDE值得出的RTL圖可知,generate_if是根據模塊的參數來作為判斷條件,來產生滿足條件的電路,當WIDE等於8時d等於abc相或,對應於我們代碼的第9~10行;當WIDE等於12時d等於abc相與,對應於我們代碼的第11~12行。

generate-case

generate_case其實跟generate_if一樣的,都是根據模塊的參數(必須是常量)作為條件判斷,來生成滿足條件的電路,不同的地方僅僅是改成使用case 的語法而已。如:

/****************************************************          

 *   Engineer      :   夢翼師兄

 *   QQ             :   761664056

 *   The module function : generate_case模塊

*****************************************************/

01  module case_test(a,  b, c,  d);

02

03  input a, b, c;             //輸入信號abc

04  output d;                   //輸出信號d

05  

06  localparam WIDE = 12;    //參數模塊,用於選擇生產的電路

07  

08  generate

09      case(WIDE)      

10      0   :                       //WIDE等於0d等於abc相或

11              assign  d   =   a | b | c;

12          

13      1   :                       //WIDE等於1d等於abc相與

14              assign  d   =   a & b & c;

15              

16      default :                   //WIDE不等於10d等於abc

17              assign  d   =   a & b | c;

18              

19      endcase

20  endgenerate

21      

22  endmodule

代碼生成的RTL電路圖如下:

 

我們將參數WIDE設置位0,生成的RTL電路圖如下:

 

 

 

參數WIDE設置位1,生成的RTL電路圖如下:

從上面3個不同的WIDE值得出的RTL圖可知,generate_case也是根據模塊的參數來作為條件判斷,來產生滿足條件的電路,當WIDE等於12時d等於a與b或c,對應於我們代碼的第16~17行;當WIDE等於0時d等於abc相或,對應於我們代碼的第10~11行;當WIDE等於1時d等於abc相與,對應於我們代碼的第13~14行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM