Verilog中的生成語句主要使用generate語法關鍵字,按照形式主要分為循環生成與條件生成,主要作用就是提高我們的代碼的簡潔度以及可讀性。
一、循環生成
語法如下:
1 genvar i; 2 generate 3 for (i=0; i< ??; i=i+1) 4 begin:循環的段名 5 6 內容 7 end 8 endgenerate
關於以上語法有四點注意:
1、循環生成中for語句使用的變量必須用genvar關鍵字定義,genvar關鍵字可以寫在generate語句外面,也可以寫在generate語句里面,只要先於for語句聲明即可;
2、必須給循環段起一個名字。這是一個強制規定,並且也是利用循環生成語句生成多個實例的時候分配名字所必須的;
3、for語句的內容必須加begin-end,即使只有一條語句也不能省略。這也是一個強制規定,而且給循環起名字也離不開begin關鍵字;
4、可以是實例化語句也可以是連續賦值語句。
循環生成語句允許使用者對下面的模塊或模塊項進行多次的實例引用;
1)變量聲明; 2)模塊; 3)用戶定義原語、門級原語; 4)連續賦值語句; 5)initial 和 always 塊。
舉例:
1 input [3:0] a,b; 2 output [3:0] c,d; 3 generate 4 genvar i; 5 6 for (i=0; i < 4; i=i+1) 7 begin : genExample 8 myAnd insAnd (.a(a[i]), .b(b[i]), .c(c[i])); 9 assign d[i] = a[i]; 10 end 11 endgenerate
注意:利用循環生成語句生成的實例名稱不能像數組例化那樣用方括號表示,否則會報錯。那么,你可能會疑惑上例中實例的名字,其實,上述實例化展開來類似:
二、條件生成
條件生成的目的是為了左右編譯器的行為,類似於C語言中的條件選擇宏定義,根據一些初始參數來決定載入哪部分代碼來進行編譯。Verilog中共提供了兩種條件生成語句,一種是generate-if語句,一種是generate-case語句,兩者的功能幾乎相同,只是書寫形式不一樣而已,分別介紹如下:
該結構可以在設計模塊中根據經過仔細推敲並確定表達式,有條件的調用以下結構:
1)模塊; 2)用於定義的原語,門級原語; 3)連續賦值語句; 4)initial 或always 塊。
該語句的語法如下
1 generate 2 3 if (<condition>) begin: <label_1> 4 5 <code>; 6 7 end else if (<condition>) begin: <label_2> 8 9 <code>; 10 11 end else begin: <label_3> 12 13 <code>; 14 15 end 16 17 endgenerate
關於該語法有三點注意:
1、必須是常量比較,例如一些參數,這樣編譯器才可以在編譯前確定需要使用的代碼;
2、if語句的內容中,begin-end只有在 < code > 有多條語句時才是必須的;
3、每一個條件分支的名稱是可選的,這點不像循環生成語句那么嚴格。
generate-case語句:
case生成語句可以調用以下的結構:
1)模塊; 2)用於定義的原語,門級原語; 3)連續賦值語句; 4)initial 或 always塊。
該語句的語法如下:
1 generate 2 3 case (<constant_expression>) 4 5 <value>: begin: <label_1> 6 7 <code> 8 9 end 10 11 <value>: begin: <label_2> 12 13 <code> 14 15 end 16 17 …… 18 19 default: begin: <label_N> 20 21 <code> 22 23 end 24 25 endcase 26 27 endgenerate
關於該語法也有三點注意,和generate-if類似:
1、<constant_expression>必須是常量比較,例如一些參數,這樣編譯器才可以在編譯前確定需要使用的代碼;
2、case語句的內容中,begin-end只有在< code >有多條語句時才是必須的;
3、每一個條件分支的名稱是可選的,這點不像循環生成語句那么嚴格。
三、見解與分析
(1)在generate block里面存在都是一些模塊級別的語句,和我們平常在always 塊和initial 塊中的語句不一樣,級別要高一點,就如文章的開頭一樣,是為了簡化電路的書寫。通俗一點來講,在generate中的要求和在module中很類似,因為generate就是生成一個電路,電路結構就是你在generate中表述的內容。
(2)可以獨立存在於generate塊或者module的應當是變量聲明,常量定義,assign賦值,門級語句,塊聲明,實例調用方法(I/O匹配表)可能有些遺漏,不過也差不多了,像if-else,while,for,case這類的語句都是高級語句,是不能獨立出現的,必須放在initial或always塊中。說白了,就是化繁為簡用的,是用來簡化代碼(不是簡化電路),具體實現是用於產生多個模塊,相當於復制電路。
針對循環生成語句,舉個例子:我已經有一個模塊A,可以產生1位的偽隨機碼,但我現在需要32位的偽隨機碼,我就可以用generate-for產生32個模塊從而輸出32位偽隨機碼。當然你也可以實例化32次A模塊產生32位偽隨機碼,作用是一樣的,但代碼簡潔很多。(其中模塊A,可以是initial塊,always塊,assign連續賦值語句塊,實例化塊,原語塊,門電路塊)。
針對條件生成語句:它與我們看到的高即別的(就是那些不能單獨使用必須放在always塊和initial塊中的語句)條件語句有本質區別。高級語句中if --else 會生成邏輯電路,而generate if是告訴綜合器:除非滿足某條件才將以下代碼綜合為電路。換句話說,如果generate if的條件不滿足,那么這段紙面代碼會被綜合器直接忽略。兩者有本質不同。
四、參考文獻
1、https://www.eefocus.com/cl5417/blog/17-02/403819_5c980.html
2、https://www.cnblogs.com/SYoong/p/5858996.html