Verilog-2005中有3個(gè)generate 語(yǔ)句可以用來(lái)很方便地實(shí)現(xiàn)重復(fù)賦值和例化(generate for)或根據(jù)條件選擇性地進(jìn)行編譯(generate if和generate case)等功能。接下來(lái)就一起看下這3個(gè)語(yǔ)句的應(yīng)用場(chǎng)景和應(yīng)用方法吧。
PART ONE
generate for
假設(shè)我希望把2個(gè)輸入a[4:0]和b[4:0]做一個(gè)異或操作,但是順序要顛倒,也就是這樣:
module xor_test(
input[4:0]a,
input[4:0]b,
output[4:0]out);
assignout[4] = a[4] ^ b[0];
assignout[3] = a[3] ^ b[1];
assignout[2] = a[2] ^ b[2];
assignout[1] = a[1] ^ b[3];
assignout[0] = a[0] ^ b[4];
endmodule
在vivado中分析出來(lái)是這樣的:很簡(jiǎn)單就是兩個(gè)輸出的不同為做一個(gè)異或運(yùn)算。
vivado綜合出來(lái)是這樣的:用了幾個(gè)LUT來(lái)實(shí)現(xiàn)異或功能。
1應(yīng)用場(chǎng)景
上面的例子限于篇幅我只假設(shè)了輸入為5bit的位寬,所以這樣寫并不會(huì)讓人覺(jué)得有多麻煩,但是假想一下如果位寬變成10、20、100呢?那我手不寫斷去?
當(dāng)你需要進(jìn)行一些重復(fù)性的工作時(shí),比如多次例化同一模塊、同一語(yǔ)句等,可以使用generate for語(yǔ)句來(lái)解放雙手,節(jié)省工作量。當(dāng)然你用腳本語(yǔ)言來(lái)生成或者直接用某些編輯器也能很快地實(shí)現(xiàn)這個(gè)功能,不過(guò)在這里我們就不提了。
上面的例子用generate for語(yǔ)句寫是這樣的:
module xor_test(
input[4:0]a,
input[4:0]b,
output[4:0]out
);
genvar i;//定義常量作為重復(fù)判斷條件
generate
for (i = 0; i < 8; i = i + 1)//重復(fù)條件
begin: XOR_INST//begin要起個(gè)名字
assignout[i] = a[i] ^ b[4-i];//需要重復(fù)的語(yǔ)句
end
endgenerate
endmodule
在vivado中分析出來(lái)是這樣的:(與上面的方式一致)
vivado綜合出來(lái)是這樣的:(仍然與上面的方式一致)
這樣看, generate for是個(gè)不錯(cuò)的提高效率的方案。當(dāng)然,該語(yǔ)句不光可以對(duì)assign進(jìn)行重復(fù)賦值,還適用以下場(chǎng)景:
(1)模塊module;(2)用戶定義原語(yǔ)UDP;(3)門級(jí)語(yǔ)句;(4)連續(xù)賦值語(yǔ)句assign;(5)initial和always塊。
2格式
generate for語(yǔ)句的一般用法:
// Declare the loop variable
genvar;
// Code for the
generate
for (;;) begin
// Code to execute
end
endgenerate
如果你是一個(gè)基于xilinx的開(kāi)發(fā)者,可以使用vivado自帶的語(yǔ)法模板:
(1)打開(kāi)語(yǔ)法模板:
(2)搜索generate:
(3)把上圖右側(cè)的語(yǔ)句復(fù)制到你自己的代碼里邊。
關(guān)于generate for語(yǔ)句的使用需要注意:
generate for 語(yǔ)句必須使用genvar關(guān)鍵字定義for循環(huán)變量
generate for 循環(huán)必須加 begin…end, 哪怕只有一句
不要使用 i++這種C語(yǔ)言式的自增語(yǔ)句(Verilog沒(méi)有i++這個(gè)語(yǔ)法),而是使用 i = i + 1
generate后不加begin,里面的語(yǔ)法:for循環(huán)、if…else…、case語(yǔ)句 后面的begin后面一定要加名字,且名字唯一,否則會(huì)導(dǎo)致無(wú)法比對(duì)通過(guò)的問(wèn)題
過(guò)多的generate會(huì)導(dǎo)致收集覆蓋率緩慢,要注意使用
PART TWO
generate if
generate if的使用場(chǎng)景和條件編譯語(yǔ)句類似,比如你的代碼中包含了一個(gè)加法模塊和一個(gè)減法模塊,對(duì)于2個(gè)輸入a和b,希望使用POL來(lái)進(jìn)行控制:如POL=1則進(jìn)行加法,反之亦然----POL=1----out = a + b;POL=0----out = a - b。
代碼是這樣寫的:
module xor_test(
input[4:0]a,
input[4:0]b,
output[4:0]out
);
localparamintegerPOL = 1;//根據(jù)POL的值來(lái)生成對(duì)應(yīng)的電路
generate
if (POL == 1) begin: POL1
assignout = a + b;
end else begin: POL0
assignout = a - b;
end
endgenerate
endmodule
定義成POL = 1時(shí)會(huì)由vivado綜合成一個(gè)加法器:
定義成POL = 0時(shí)則會(huì)由vivado綜合成一個(gè)減法器:
假如不使用generate if語(yǔ)法,則代碼是這樣的:
module xor_test(
input[4:0]a,
input[4:0]b,
inputPOL,
outputreg[4:0]out
);
always@(*)begin
if(POL == 1)
out = a + b;
else
out = a - b;
end
endmodule
這樣綜合出來(lái)的就是加法電路和減法電路一起:
使用generate if可以根據(jù)需要來(lái)靈活地生成對(duì)應(yīng)電路,不會(huì)浪費(fèi)資源,適用于某些根據(jù)特定需求來(lái)實(shí)現(xiàn)電路的場(chǎng)景。而不使用該語(yǔ)句則會(huì)把所有潛在的電路均綜合出來(lái),會(huì)使電路面積增大,但是靈活性卻較高。
這是vivado自帶的語(yǔ)法模板:
generate
if () begin:
;
end else if () begin:
;
end else begin:
;
end
endgenerate
PART TWO
generate case
generate case和generate if作用上是差不多的,都是用于選擇性綜合電路,區(qū)別就是if語(yǔ)句和case語(yǔ)句的區(qū)別,如果你會(huì)用其中一個(gè),那另一個(gè)也很簡(jiǎn)單,模板如下:
generate
case ()
: begin:
end
: begin:
end
default: begin:
end
endcase
endgenerate
上面的例子照著改就是這樣了:
module xor_test(
input[4:0]a,
input[4:0]b,
output[4:0]out
);
localparamintegerPOL = 1;//根據(jù)POL的值來(lái)生成對(duì)應(yīng)的電路
generate
case(POL)
1'b1: begin: POL1
assignout = a + b;
end
1'b0: begin: POL0
assignout = a - b;
end
defaultDEFAULT end
endcase
endgenerate
endmodule
審核編輯:湯梓紅
-
Verilog
+關(guān)注
關(guān)注
28文章
1351瀏覽量
110077 -
編譯
+關(guān)注
關(guān)注
0文章
657瀏覽量
32852 -
Vivado
+關(guān)注
關(guān)注
19文章
812瀏覽量
66473
原文標(biāo)題:【科普】Verilog語(yǔ)法之generate for、generate if、generate case
文章出處:【微信號(hào):feifeijiehaha,微信公眾號(hào):電路和微電子考研】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論