本文是針對(duì)在寫項(xiàng)目中遇到的Verilog代碼寫法錯(cuò)誤,多對(duì)一和一對(duì)多賦值問題,從邏輯賦值的角度理解為何會(huì)編譯出錯(cuò)。并在后續(xù)討論了if-else和case的電路結(jié)構(gòu)和區(qū)別。在此處列出來供大家一起交流學(xué)習(xí)。
2.對(duì)Verilog代碼的理解
2.1 一對(duì)多賦值、多對(duì)一賦值行為的區(qū)別
2.1.1多對(duì)一賦值的Verilog代碼:
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
REG1 <= 'd0;
REG2 <= 'd0;
end
else begin
if(write) begin
case(paddr)
'h54321 : REG1 <= ?pwdata; ? //在32'h54321寫入pwdata
'h12345 : REG2 <= ?pwdata; ? //在32'h12345寫入pwdata
default begin
REG1 <= REG1 ;
REG2 <= REG2 ;
end
endcase
//另一種寫法
//REG1 <= (paddr == 'h54321) ? pwdata : REG1; //在32'h54321寫入pwdata
//REG2 <= (paddr == 'h12345) ? pwdata : REG2; ?//在32'h12345寫入pwdata
end
else begin
REG1 <= REG1;
REG2 <= REG2;
end
end
end
·如果將一個(gè)信號(hào)(如pwdata)對(duì)多個(gè)信號(hào)進(jìn)行賦值(如REG1、REG2),應(yīng)該使用譯碼器形式的電路結(jié)構(gòu)。也就是pwdata根據(jù)paddr進(jìn)行譯碼,從而將值賦給REG1/REG2。如下圖所示
#FormatImgID_0#
·譯碼器一般用多個(gè)輸入信號(hào),根據(jù)padder判斷取值的不同,將輸入信號(hào)pwdata賦值給相應(yīng)的輸出信號(hào)。代碼中給出了兩種寫法都可以。
2.1.2一對(duì)多賦值的Verilog代碼:
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
prdata <= 'd0;
end
else begin
if(read) begin
case(paddr)
'h54321 : prdata <= REG1; //在32'h54321讀出prdata = REG1 ?
'h12345 : prdata <= REG2; //在32'h12345讀出prdata = REG2
default : prdata <= prdata;
endcase
//注意下面這種寫法是錯(cuò)誤的(2.1.3中會(huì)分析)
//prdata <= (paddr == 'h54321) ? REG1 : prdata;
//prdata <= (paddr == 'h54321) ? REG2 : prdata;
end
else begin
prdata <= prdata;
end
end
end
·如果將多個(gè)信號(hào)(如REG1、REG2)對(duì)一個(gè)信號(hào)進(jìn)行賦值(如prdata),應(yīng)該使用多路選擇器形式的電路結(jié)構(gòu)。也就是REG1/REG2根據(jù)paddr進(jìn)行判斷,從而將值賦給prdata。如下圖所示
#FormatImgID_1#
·多路選擇器的寫法一般是利用case語句進(jìn)行實(shí)現(xiàn),根據(jù)case的條件不同,選擇不同的輸入信號(hào)對(duì)輸出信號(hào)進(jìn)行賦值。
2.1.3 為什么多對(duì)一賦值不能用三目運(yùn)算符呢?
即寫成:
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
prdata <= 'd0;
end
else begin
if(read) begin
//注意多對(duì)一中,下面這種寫法是錯(cuò)誤的
prdata <= (paddr == 'h54321) ? REG1 : prdata;
prdata <= (paddr == 'h54321) ? REG2 : prdata;
end
else begin
prdata <= prdata;
end
end
end
分析:這時(shí)候編譯就會(huì)報(bào)錯(cuò),prdata同時(shí)被兩個(gè)常量賦值。假如說paddr選中了'h54321,此時(shí) prdata<= REG1成立;但是請(qǐng)注意在第二條語句中,由于paddr≠'h54321,prdata <= prdata。
由此我們可以知道三目運(yùn)算符和case并不等價(jià),如果改寫成if-else多層嵌套語句,編譯沒有出錯(cuò)誤。
always @(posedge clk or negedge rstn)begin
if(!rstn)begin
prdata <= 'd0;
end
else begin
if(read) begin
if(paddr == 'h54321)begin
prdata <= REG1;
end
else begin
if(paddr == 'h54321)begin
prdata <= REG2;
end
else begin
prdata <= prdata; ? ?
end
end
end
else begin
prdata <= prdata;
end
end
end
下面進(jìn)一步分析if-else和case語句的區(qū)別來分析。
2.2 if—else語句與case語句的區(qū)別
2.2.1 if-else語句的電路結(jié)構(gòu)
每個(gè)if-else就是一個(gè)2選1mux器。當(dāng)信號(hào)有明顯優(yōu)先級(jí)時(shí),首先要考慮if-else,但是if嵌套過多也會(huì)導(dǎo)致速度變慢;if語句結(jié)構(gòu)較慢,但占用面積小。
嵌套的if語句如果使用不當(dāng),就會(huì)導(dǎo)致設(shè)計(jì)的更大延時(shí),為了避免較大的路徑延遲,最好不要使用特別長(zhǎng)的嵌套if結(jié)構(gòu)。如想利用if語句來實(shí)現(xiàn)那些對(duì)延時(shí)要求苛刻的路徑時(shí),應(yīng)將最高優(yōu)先級(jí)給最遲到達(dá)的關(guān)鍵信號(hào)。
2.2.2 case語句的電路結(jié)構(gòu)
case語句綜合為 n選1的mux電路。適用于無明顯優(yōu)先級(jí)的邏輯判斷,即這些邏輯條件都處于同一個(gè)優(yōu)先級(jí)且互斥;case結(jié)構(gòu)電路速度較快,但占用面積較大。
2.2.3 if語句和case語句中的latch問題
if-else:組合邏輯和時(shí)序邏輯中的always語句塊中實(shí)現(xiàn)是不同的。
組合邏輯中:if缺少else 時(shí),會(huì)有l(wèi)atch;
時(shí)序邏輯中:盡管缺少else,依舊是D觸發(fā)器,不存在latch。
case語句:case列舉不全并且還沒寫default語句,則會(huì)綜合出鎖存器。所以一定寫default,無論是組合還是時(shí)序邏輯。
總結(jié):保證if-else對(duì)應(yīng)齊全;case必寫default。
2.2.4 if-else語句和case語句的區(qū)別
對(duì)于這個(gè)的討論,本人認(rèn)為是以前由于綜合工具落后,導(dǎo)致有區(qū)別,但是隨著綜合工具的更新,他們之間的區(qū)別越來越小,甚至有人可以用if-else綜合出無優(yōu)先級(jí)的多路選擇器,用case綜合出有優(yōu)先級(jí)的多路選擇器。
“if-else的邏輯判別是有優(yōu)先級(jí)的,而case的邏輯判斷條件是并列的。
舉個(gè)例子,如果你用IF實(shí)現(xiàn)譯碼器,綜合出的是有優(yōu)先級(jí)的譯碼器。如果用CASE,綜合出的就是一個(gè)無優(yōu)先級(jí)的譯碼器。也就是說IF是有優(yōu)先級(jí)的,執(zhí)行的次序有先后。而CASE執(zhí)行的時(shí)候是沒有先后順序的?!?/p>
“隨著綜合工具的進(jìn)步,已經(jīng)不需要討論if-else 和case的區(qū)別了,兩者可以等同 ”
“Verilog 2001標(biāo)準(zhǔn)(IEEE 1364-2001)第132頁:
The case item expressions shall be evaluated and compared in the exact order in which they are given.
指出了case是串行有優(yōu)先級(jí)。又:
Apart from syntax, the case statement differs from the multiway if-else-if construct in two important ways:
a) The conditional expressions in the if-else-if construct are more general than comparing one expression with several others, as in the case statement.
b) The case statement provides a definitive result when there are x and z values in an expression.
a)是廢話。b)指出了case是四態(tài)對(duì)比。除此之外和if-else沒有差別。”
審核編輯:黃飛
-
Verilog
+關(guān)注
關(guān)注
28文章
1333瀏覽量
109713 -
D觸發(fā)器
+關(guān)注
關(guān)注
3文章
164瀏覽量
47737 -
代碼
+關(guān)注
關(guān)注
30文章
4670瀏覽量
67764 -
Case
+關(guān)注
關(guān)注
0文章
27瀏覽量
13340 -
多路選擇器
+關(guān)注
關(guān)注
1文章
22瀏覽量
6487
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論