在使用xilinx官方例程《XAPP585》實(shí)現(xiàn)CameraLink接口發(fā)送或者接收數(shù)據(jù)時(shí),有個(gè)程序還是值得學(xué)習(xí)的,下面把這段程序截出來(lái):
genvari; genvarj; generate for(i=0;i<=?(N-1)?;?i?=?i+1) begin?:?loop0 serdes_7_to_1_diff_sdr?#( ???????.D???(D), ???????.DATA_FORMAT??(DATA_FORMAT)) dataout?( ?.dataout_p????(dataout_p[D*(i+1)-1:D*i]), ?.dataout_n????(dataout_n[D*(i+1)-1:D*i]), ?.clkout_p????(clkout_p[i]), ?.clkout_n????(clkout_n[i]), ?.txclk??????(txclk), ?.pixel_clk??????(pixel_clk), ?.reset?????(reset), ?.clk_pattern????(clk_pattern), ?.datain????(datain[(D*(i+1)*7)-1:D*i*7]));?? end endgenerate?
主要是generate的用法,整個(gè)文件的功能是實(shí)現(xiàn)可選多通道數(shù)據(jù)發(fā)送,我們知道Cameralink中對(duì)于多通道傳輸時(shí)有一部分功能代碼時(shí)相同的,只不過(guò)需要多通道復(fù)用,我們知道generate有一個(gè)功能就是重復(fù)操作多個(gè)模塊的實(shí)例引用,當(dāng)然就適合本例程。
下面我們先講一講generate的用法再結(jié)合代碼簡(jiǎn)單講解一下,對(duì)于generate其實(shí)很好理解,只不過(guò)寫出來(lái)比較難。
generate用法
關(guān)鍵字generate和endgenerate(和begin / end類似)作為使用語(yǔ)法的起點(diǎn),有三種衍生結(jié)構(gòu),分別為:
generate - for 語(yǔ)句結(jié)構(gòu)
generate - if 語(yǔ)句結(jié)構(gòu)
generate - case 語(yǔ)句結(jié)構(gòu)
使用generate的情況主要如下:
使用 for 循環(huán)對(duì)模塊進(jìn)行多次相似實(shí)例化
使用參數(shù)更改模塊的結(jié)構(gòu)或設(shè)計(jì)
使用帶有斷言語(yǔ)句進(jìn)行功能和形式驗(yàn)證
在這里我們思考一下,generate是在運(yùn)行中構(gòu)造重復(fù)模塊嗎??
答案是否定的,generate語(yǔ)句不是運(yùn)行時(shí)構(gòu)造。如果你想一想,這個(gè)generate結(jié)構(gòu)實(shí)際上是在創(chuàng)建一個(gè)重復(fù)電路,我們不能即時(shí)添加或刪除硬件電路,所以generate在綜合過(guò)程中其實(shí)是重復(fù)構(gòu)造相似電路,而不是在運(yùn)行時(shí)構(gòu)造。
下面先按照generate結(jié)構(gòu)分別舉例,然后舉例幾個(gè)常用案例。
generate - for語(yǔ)句結(jié)構(gòu)
在使用generate - for語(yǔ)句之前,我們需要先聲明一個(gè)變量genvar,用于for循環(huán)語(yǔ)句進(jìn)行判斷。
下面舉兩個(gè)不同應(yīng)用的例子:
上面兩個(gè)模塊功能一樣,第一個(gè)是對(duì)always 塊進(jìn)行了循環(huán);第二個(gè)則是對(duì)實(shí)例化時(shí)的模塊進(jìn)行了循環(huán)。xorLoop 是 generate 語(yǔ)句模塊名,目的是通過(guò)它對(duì)循環(huán)語(yǔ)句進(jìn)行層次化引用,所以在上面栗子中的 xorLoop 模塊相對(duì)層次名為 xorLoop[0].u_xor(后面會(huì)舉例說(shuō)明)
這里在對(duì)比兩個(gè)常見(jiàn)的例子:
上面的例子功能也一樣,一個(gè)使用generate...for語(yǔ)句一個(gè)使用for語(yǔ)句,關(guān)于這兩者區(qū)別我會(huì)在文章最后總結(jié)里說(shuō)明,大家可以自己先思考。
generate - if語(yǔ)句結(jié)構(gòu)
generate -if 語(yǔ)句結(jié)構(gòu)比較寬松,即不需要對(duì)不需要對(duì)generate語(yǔ)句進(jìn)行命名(generate...for主要是對(duì)循環(huán)語(yǔ)句進(jìn)行層次化引用) ,也不需要變量genvar。由于 generate - if 語(yǔ)句結(jié)構(gòu)是通過(guò)判斷語(yǔ)句執(zhí)行代碼塊,這就決定了每次最多執(zhí)行一個(gè)代碼塊,這種情況下,可以對(duì)各個(gè)代碼塊使用相同命名是合法的,且有助于保持對(duì)代碼的層次化引用。
需要注意的一點(diǎn)是,在 generate 塊中的判斷條件必須是常量!
generate - case
generate - case 語(yǔ)句和 generate - if 語(yǔ)句核心思想都是進(jìn)行條件判斷,用法基本一致。
和 generate - if 語(yǔ)句一樣,case 判斷條件必須是常量。
下面按照應(yīng)用場(chǎng)景舉例:
循環(huán)生成構(gòu)造
循環(huán)生成構(gòu)造提供了一種簡(jiǎn)單而簡(jiǎn)潔的方法來(lái)創(chuàng)建模塊項(xiàng)的多個(gè)實(shí)例,例如模塊實(shí)例、分配語(yǔ)句、斷言、接口實(shí)例等。你可以把它想象成一臺(tái)“克隆機(jī)”。
本質(zhì)上,它是一種特殊類型的for循環(huán),其循環(huán)索引變量為 datatype genvar。這是一個(gè)有趣的事實(shí)- genvar它是一個(gè)整數(shù)數(shù)據(jù)類型,僅在綜合時(shí)存在并在運(yùn)行時(shí)消失。
我們看到的《XAPP585》的例程就是這種運(yùn)行結(jié)構(gòu),下面再舉例看下該語(yǔ)句的特點(diǎn):
/**Example1*/ /** *16inputmux * *ExampleofhowtouseLoopGenerateConstruct */ modulemux_16( inputlogic[0:15][127:0]mux_in, inputlogic[3:0]select, outputlogic[127:0]mux_out ); logic[0:15][127:0]temp; //Thefor-loopcreates16assignstatements genvari; generate for(i=0;i16;?i++)?begin ????????????assign?temp[i]?=?(select?==?i)???mux_in[i]?:?0; ????????end ????endgenerate ????assign?mux_out?=?temp[0]?|?temp[1]?|?temp[2]?|?temp[3]?| ?????????????????????temp[4]?|?temp[5]?|?temp[6]?|?temp[7]?| ?????????????????????temp[8]?|?temp[9]?|?temp[10]?|?temp[11]?| ?????????????????????temp[12]?|?temp[13]?|?temp[14]?|?temp[15]; endmodule:?mux_16
仿真文件如下:
`timescale1ns/1ps /** *Testbenchtoexercisethemux_16module. *Hereweinstantiatethemux4times.Eachinstanceis *fedadifferentinputwithdifferentinput`select`and *theoutputisobserved. */ moduletb_mux_16; logicclk; logic[0:15][127:0]test_in[4]; logic[3:0]test_select[4]; logic[127:0]test_out[4]; inti,j,k; initialbegin clk=0; forever#1nsclk=~clk; end initialbegin //Setinputs for(i=0;i4;?i++)?begin ????????for?(j=0;?j?16;?j++)?begin ????????????test_in[i][j]?=?127'habcd_0000?+?(i?<8)?+?j; ????????end ????????test_select[i]?=?i; ????end ????#2ns; ????//?Print?outputs ????for(k=0;?k?4;?k++)?begin ????????$display("test_out[%0d]?=?0x%x",?k,?test_out[k]); ????end ????#2ns; ????//?Change?input?select? ????for?(i=0;?i?4;?i++)?begin ????????test_select[i]?=?10?+?i; ????end ????#2ns; ????//?Print?outputs?again ????for(k=0;?k?4;?k++)?begin ????????$display("test_out[%0d]?=?0x%x",?k,?test_out[k]); ????end ????#10ns; ????$finish; end genvar?m; generate ????for?(m=0;?m?4;?m++)?begin:?MUX ???????mux_16?imux_16?( ???????????.mux_in(test_in[m]), ???????????.select(test_select[m]), ???????????.mux_out(test_out[m]) ???????);? ????end endgenerate endmodule:?tb_mux_16
我們還可以嵌套generate...for 循環(huán)。只需確保genvars將外部循環(huán)和內(nèi)部循環(huán)分開(kāi)使用,并在嵌套的 for 循環(huán)中引用這些變量時(shí)要小心,這是一個(gè)經(jīng)常犯錯(cuò)誤的地方。
條件生成構(gòu)造
條件生成構(gòu)造允許根據(jù)在模塊實(shí)例化期間傳遞的參數(shù)值更改設(shè)計(jì)結(jié)構(gòu)。這在為設(shè)計(jì)創(chuàng)建參數(shù)化通用 RTL 模塊時(shí)非常有用。
一個(gè)簡(jiǎn)單的例子:
/**Example2.1*/ /** *Asimplegenerateexample.ThisparamerterOPERATION_TYPE, *passedwhenthismoduleisinstantiated,isusedtoselect *theoperationbetweeninputs`a`and`b`. */ moduleconditional_generate #(parameterOPERATION_TYPE=0) ( inputlogic[31:0]a, inputlogic[31:0]b, outputlogic[63:0]z ); //Thegenerate-endgeneratekeywordsareoptional. //Itistheactofdoingaconditionaloperation //onaparameterthatmakesthisagenerateblock. generate if(OPERATION_TYPE==0)begin assignz=a+b; end elseif(OPERATION_TYPE==1)begin assignz=a-b; end elseif(OPERATION_TYPE==2)begin assignz=(a<1)?+?b;?//?2a+b ????????end ????????else?begin ????????????assign?z?=?b?-?a; ????????end ????endgenerate endmodule:?conditional_generate
另一個(gè)例子 - 我們需要?jiǎng)?chuàng)建一個(gè)通用 CRC 生成器的任務(wù)。團(tuán)隊(duì)中的其他設(shè)計(jì)人員應(yīng)該能夠在 3 個(gè)多項(xiàng)式中選擇 1 個(gè)進(jìn)行 CRC 計(jì)算。
這是一種方法 - 提供一個(gè)名為 CRC_SEL 的參數(shù),該參數(shù)在此模塊實(shí)例化時(shí)使用,此CRC_SEL參數(shù)用來(lái)選擇在模塊中生成哪個(gè) CRC 函數(shù)。通過(guò)使用generate而不是簡(jiǎn)單的多路復(fù)用器,可以節(jié)省一堆門電路和觸發(fā)器,因?yàn)椴恍枰?CRC 函數(shù)不會(huì)被實(shí)例化。
完整代碼如下:
/** *CRCgeneratormodule.Selectthedesiredpolynomial *usingtheCRC_SELparameter. * *Defaultpolynomial:x^16+x^15+x^2+1 *CRC_SEL=0:x^16+x^1+1 *CRC_SEL=1:x^16+x^12+x^5+1 * *USAGE: *+Strobe`start`whendrivingthefirstvalidbyte *+Strobe`done`oneclkafterdrivingthelastvalidbyte *+ThefinalCRCisavailable1clkafterthelastvalidbyte *isdriven.Thisisthesamecycleyou'lldrive`done`. * */ modulecrc_gen #(parameterCRC_SEL=0) ( inputlogicclk, inputlogicrst, inputlogicstart, inputlogicdone, inputlogic[7:0]data_in, inputlogic[15:0]crc_in, outputlogic[15:0]crc_out ); logic[7:0]data_in_d; logic[15:0]crc_in_d; assigncrc_in_d=(start|done)?16'd0:crc_in; assigndata_in_d=(done)?8'd0:data_in; always_ff@(posedgeclk)begin if(rst)begin crc_out<=?'d0; ????????end ????????else?begin ????????????//?Generate?blocks?are?always?assigned?a?name.?If ????????????//?you?don't?name?the?generate?block,?it?will?be ????????????//?given?a?default?auto?generated?name. ????????????// ????????????//?To?invoke?a?function?within?a?generate?block, ????????????//?hierarchically?call?it? ????????????//?. crc_out<=?crc_poly.nextCRC16_D8(data_in_d,?crc_in_d); ????????end ????end ????//?Once?again?the?generate-endgenerate?keywords?are?optional ????//?It?is?the?act?of?using?a?parameter,?CRC_SEL,?in?the?case ????//?statement?that?makes?it?a?generate?block ????// ????//?Also?notice?how?all?the?generate?blocks?are?given?the?same ????//?name?`crc_poly`?and?all?the?function?names?are?the?same ????//?`nextCRC16_D8`.?This?is?correct?because?only?one?of?the ????//?function?declarations?is?compiled?in?during?elaboration ????//?phase. ????generate ????case?(CRC_SEL) ????????0:? ????????begin:?crc_poly ????????????//?polynomial:?x^16?+?x^1?+?1 ????????????//?data?width:?8 ????????????//?convention:?the?first?serial?bit?is?D[7] ????????????function?automatic?[15:0]?nextCRC16_D8; ???????????? ????????????????input?[7:0]?Data; ????????????????input?[15:0]?crc; ????????????????reg?[7:0]?d; ????????????????reg?[15:0]?c; ????????????????reg?[15:0]?newcrc; ????????????????d?=?Data; ????????????????c?=?crc; ???????????????? ????????????????newcrc[0]?=?d[0]?^?c[8]; ????????????????newcrc[1]?=?d[1]?^?d[0]?^?c[8]?^?c[9]; ????????????????newcrc[2]?=?d[2]?^?d[1]?^?c[9]?^?c[10]; ????????????????newcrc[3]?=?d[3]?^?d[2]?^?c[10]?^?c[11]; ????????????????newcrc[4]?=?d[4]?^?d[3]?^?c[11]?^?c[12]; ????????????????newcrc[5]?=?d[5]?^?d[4]?^?c[12]?^?c[13]; ????????????????newcrc[6]?=?d[6]?^?d[5]?^?c[13]?^?c[14]; ????????????????newcrc[7]?=?d[7]?^?d[6]?^?c[14]?^?c[15]; ????????????????newcrc[8]?=?d[7]?^?c[0]?^?c[15]; ????????????????newcrc[9]?=?c[1]; ????????????????newcrc[10]?=?c[2]; ????????????????newcrc[11]?=?c[3]; ????????????????newcrc[12]?=?c[4]; ????????????????newcrc[13]?=?c[5]; ????????????????newcrc[14]?=?c[6]; ????????????????newcrc[15]?=?c[7]; ????????????????nextCRC16_D8?=?newcrc; ????????????endfunction ????????end ????????1: ????????begin:?crc_poly ????????????//?polynomial:?x^16?+?x^12?+?x^5?+?1 ????????????//?data?width:?8 ????????????//?convention:?the?first?serial?bit?is?D[7] ????????????function?automatic?[15:0]?nextCRC16_D8; ???????????? ????????????????input?[7:0]?Data; ????????????????input?[15:0]?crc; ????????????????reg?[7:0]?d; ????????????????reg?[15:0]?c; ????????????????reg?[15:0]?newcrc; ????????????????d?=?Data; ????????????????c?=?crc; ???????????????? ????????????????newcrc[0]?=?d[4]?^?d[0]?^?c[8]?^?c[12]; ????????????????newcrc[1]?=?d[5]?^?d[1]?^?c[9]?^?c[13]; ????????????????newcrc[2]?=?d[6]?^?d[2]?^?c[10]?^?c[14]; ????????????????newcrc[3]?=?d[7]?^?d[3]?^?c[11]?^?c[15]; ????????????????newcrc[4]?=?d[4]?^?c[12]; ????????????????newcrc[5]?=?d[5]?^?d[4]?^?d[0]?^?c[8]?^?c[12]?^?c[13]; ????????????????newcrc[6]?=?d[6]?^?d[5]?^?d[1]?^?c[9]?^?c[13]?^?c[14]; ????????????????newcrc[7]?=?d[7]?^?d[6]?^?d[2]?^?c[10]?^?c[14]?^?c[15]; ????????????????newcrc[8]?=?d[7]?^?d[3]?^?c[0]?^?c[11]?^?c[15]; ????????????????newcrc[9]?=?d[4]?^?c[1]?^?c[12]; ????????????????newcrc[10]?=?d[5]?^?c[2]?^?c[13]; ????????????????newcrc[11]?=?d[6]?^?c[3]?^?c[14]; ????????????????newcrc[12]?=?d[7]?^?d[4]?^?d[0]?^?c[4]?^?c[8]?^?c[12]?^?c[15]; ????????????????newcrc[13]?=?d[5]?^?d[1]?^?c[5]?^?c[9]?^?c[13]; ????????????????newcrc[14]?=?d[6]?^?d[2]?^?c[6]?^?c[10]?^?c[14]; ????????????????newcrc[15]?=?d[7]?^?d[3]?^?c[7]?^?c[11]?^?c[15]; ????????????????nextCRC16_D8?=?newcrc; ????????????endfunction ????????end ????????default:? ????????????begin:?crc_poly ????????????//?polynomial:?x^16?+?x^15?+?x^2?+?1 ????????????//?data?width:?8 ????????????//?convention:?the?first?serial?bit?is?D[7] ????????????function?automatic?[15:0]?nextCRC16_D8; ???????????? ????????????????input?[7:0]?Data; ????????????????input?[15:0]?crc; ????????????????reg?[7:0]?d; ????????????????reg?[15:0]?c; ????????????????reg?[15:0]?newcrc; ????????????????d?=?Data; ????????????????c?=?crc; ???????????????? ????????????????newcrc[0]?=?d[7]?^?d[6]?^?d[5]?^?d[4]?^?d[3]?^?d[2]?^?d[1]?^?d[0]?^?c[8]?^?c[9]?^?c[10]?^?c[11]?^?c[12]?^?c[13]?^?c[14]?^?c[15]; ????????????????newcrc[1]?=?d[7]?^?d[6]?^?d[5]?^?d[4]?^?d[3]?^?d[2]?^?d[1]?^?c[9]?^?c[10]?^?c[11]?^?c[12]?^?c[13]?^?c[14]?^?c[15]; ????????????????newcrc[2]?=?d[1]?^?d[0]?^?c[8]?^?c[9]; ????????????????newcrc[3]?=?d[2]?^?d[1]?^?c[9]?^?c[10]; ????????????????newcrc[4]?=?d[3]?^?d[2]?^?c[10]?^?c[11]; ????????????????newcrc[5]?=?d[4]?^?d[3]?^?c[11]?^?c[12]; ????????????????newcrc[6]?=?d[5]?^?d[4]?^?c[12]?^?c[13]; ????????????????newcrc[7]?=?d[6]?^?d[5]?^?c[13]?^?c[14]; ????????????????newcrc[8]?=?d[7]?^?d[6]?^?c[0]?^?c[14]?^?c[15]; ????????????????newcrc[9]?=?d[7]?^?c[1]?^?c[15]; ????????????????newcrc[10]?=?c[2]; ????????????????newcrc[11]?=?c[3]; ????????????????newcrc[12]?=?c[4]; ????????????????newcrc[13]?=?c[5]; ????????????????newcrc[14]?=?c[6]; ????????????????newcrc[15]?=?d[7]?^?d[6]?^?d[5]?^?d[4]?^?d[3]?^?d[2]?^?d[1]?^?d[0]?^?c[7]?^?c[8]?^?c[9]?^?c[10]?^?c[11]?^?c[12]?^?c[13]?^?c[14]?^?c[15]; ????????????????nextCRC16_D8?=?newcrc; ????????????endfunction ????????end ????endcase ????endgenerate endmodule:?crc_gen
下面是仿真文件及結(jié)果:
`timescale1ns/1ps /** *Testbenchtoexercisethemux_16module. *Hereweinstantiatethemux4times.Eachinstanceis *fedadifferentinputwithdifferentinput`select`and *theoutputisobserved. */ moduletb_mux_16; logicclk; logic[0:15][127:0]test_in[4]; logic[3:0]test_select[4]; logic[127:0]test_out[4]; inti,j,k; initialbegin clk=0; forever#1nsclk=~clk; end initialbegin //Setinputs for(i=0;i4;?i++)?begin ????????for?(j=0;?j?16;?j++)?begin ????????????test_in[i][j]?=?127'habcd_0000?+?(i?<8)?+?j; ????????end ????????test_select[i]?=?i; ????end ????#2ns; ????//?Print?outputs ????for(k=0;?k?4;?k++)?begin ????????$display("test_out[%0d]?=?0x%x",?k,?test_out[k]); ????end ????#2ns; ????//?Change?input?select? ????for?(i=0;?i?4;?i++)?begin ????????test_select[i]?=?10?+?i; ????end ????#2ns; ????//?Print?outputs?again ????for(k=0;?k?4;?k++)?begin ????????$display("test_out[%0d]?=?0x%x",?k,?test_out[k]); ????end ????#10ns; ????$finish; end genvar?m; generate ????for?(m=0;?m?4;?m++)?begin:?MUX ???????mux_16?imux_16?( ???????????.mux_in(test_in[m]), ???????????.select(test_select[m]), ???????????.mux_out(test_out[m]) ???????);? ????end endgenerate endmodule:?tb_mux_16 Footer ?2022?GitHub,?Inc. Footer?navigation Terms Privacy Security Status Docs Cont
斷言和形式驗(yàn)證
generate - case 語(yǔ)句結(jié)構(gòu)在編寫斷言時(shí)也非常有用,這反過(guò)來(lái)有助于形式驗(yàn)證。
如果對(duì)形式驗(yàn)證有任何經(jīng)驗(yàn),那么就會(huì)知道形式工具在嘗試證明屬性時(shí)很快就會(huì)遇到計(jì)算界限。因此,重要的是要保持屬性簡(jiǎn)短而簡(jiǎn)單。
例如,如果有一個(gè)具有 8 個(gè) REQquest 輸入和 8 個(gè) ACK 輸出的仲裁器塊,那么與其編寫單個(gè)斷言來(lái)覆蓋所有 8 個(gè) REQ/ACK 對(duì),不如將其分解為具有 1 個(gè) REQ/ACK 的 8 個(gè)單獨(dú)的斷言對(duì)。
/**Example3.1*/ genvark; generate for(k=0;k8;?k++)?begin ????????req_a:?assert?property?(req[k]?|=>ack[k]); end endgenerate
分層訪問(wèn)生成塊
絆倒人們的一件事是如何訪問(wèn)位于生成塊內(nèi)的模塊項(xiàng)。
生成塊有一個(gè)名字。如果不為其命名,編譯器將自動(dòng)分配一個(gè)通用名稱,例如genblk01,genblk02通常必須轉(zhuǎn)儲(chǔ) wave 并查看Visualizer工具以查看分配了哪些名稱。
要訪問(wèn)生成塊中的模塊項(xiàng),必須分層訪問(wèn)它
這是來(lái)自 SystemVerilog LRM 1800-2012 的一個(gè)很好的示例(示例 4 第 27.5 節(jié))。查看如何訪問(wèn)塊中定義的任務(wù)和模塊實(shí)例。
分層實(shí)例名稱為:
memory.word16[3].p,memory.word16[2].p, memory.word16[1].p,memory.word16[0].p,
/**Example4*/ moduledimm(addr,ba,rasx,casx,csx,wex,cke,clk,dqm,data,dev_id); parameter[31:0]MEM_WIDTH=16,MEM_SIZE=8; ... genvari; case({MEM_SIZE,MEM_WIDTH}) {32'd8,32'd16}://8Megx16bitswide begin:memory for(i=0;i<4;?i=i+1)?begin:word16 ????????????????sms_08b216t0?p(.clk(clk),?.csb(csx),?.cke(cke),.ba(ba), ????????????????????.addr(addr),?.rasb(rasx),?.casb(casx), ????????????????????.web(wex),?.udqm(dqm[2*i+1]),?.ldqm(dqm[2*i]), ????????????????????.dqi(data[15+16*i:16*i]),?.dev_id(dev_id)); ????????????????//?The?hierarchical?instance?names?are: ????????????????//?memory.word16[3].p,?memory.word16[2].p, ????????????????//?memory.word16[1].p,?memory.word16[0].p, ????????????????//?and?the?task?memory.read_mem ????????????end ????????????task?read_mem; ????????????????input?[31:0]?address; ????????????????output?[63:0]?data; ????????????????begin?//?call?read_mem?in?sms?module ????????????????????word[3].p.read_mem(address,?data[63:48]); ????????????????????word[2].p.read_mem(address,?data[47:32]); ????????????????????word[1].p.read_mem(address,?data[31:16]); ????????????????????word[0].p.read_mem(address,?data[15:?0]); ????????????????end ????????????endtask? ????????end ????... ????endcase endmodule
總結(jié)
這篇文章是在閱讀《XAPP585》代碼時(shí)候看著generate語(yǔ)法極其方便,所以引出了該篇文章,下面說(shuō)下generate...for和for的區(qū)別:
首先第二個(gè)代碼時(shí)錯(cuò)誤的!
只有當(dāng) for 循環(huán)在 generate 中時(shí),才能將 always 放在 for 循環(huán)中!
generate for 循環(huán)和常規(guī) for 循環(huán)之間的主要區(qū)別在于 generate for 循環(huán)是為每次迭代生成一個(gè)實(shí)例。這意味著在示例中將有 3 個(gè) always 塊(與常規(guī)循環(huán)情況下的 1 個(gè)塊相反)。
一個(gè)更好的例子是:
moduleA(); .. endmodule; moduleB(); parameterNUM_OF_A_MODULES=2;//shouldbeoverridenfromhigherhierarchy genvari; for(i=0i
在此示例中,常規(guī) for 無(wú)法完成創(chuàng)建 NUM_OF_A_MODULES 實(shí)例的工作。
審核編輯:彭靜
-
接口
+關(guān)注
關(guān)注
33文章
8447瀏覽量
150723 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6808瀏覽量
88743 -
代碼
+關(guān)注
關(guān)注
30文章
4722瀏覽量
68234
原文標(biāo)題:【Verilog我思我用】-generate
文章出處:【微信號(hào):Open_FPGA,微信公眾號(hào):OpenFPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論