【正文】
==1’b1)z = (a+b)。elsez = (c+d)。只要加法器的輸入端復(fù)用,就可以實(shí)現(xiàn)加法器的共享,使用一個(gè)加法器實(shí)現(xiàn)。(d)盡量采用公共子表達(dá)式如 :x=a+b+cy=d+a+b改為:z=a+bx=z+cy=d+z(2)算符(a)條件運(yùn)算符r1 = gate? r2 : r3。避免使用條件嵌套:r1 = (aa = 0)? ((bb == 0)? r2 : r3) : r4。 orr1 = {aa,bb} == 0? r2: {aa,bb} == 0? r3: {aa,bb} == 0? R4:r4。(b)邏輯操作符在if(),while(),()?A:B 之類的表達(dá)式中,括號中的表達(dá)式應(yīng)該是一個(gè)邏輯表達(dá)式,相應(yīng)的操作符應(yīng)該用邏輯操作符。如:wire x,A,B。 (x) ? A:B 與 (x == 139。b1) ? A:B If(Aamp。B) 與 if((Aamp。amp。B)==1’b1) While(A=B) 與 while(A==B) 操作結(jié)果相同,但顯然前者不規(guī)范。(c)乘法運(yùn)算符“*”對于一個(gè)變量data與常數(shù)constant相乘data * constant,如果常數(shù)不是2的整數(shù)次冪,建議先將其分解,如constant= 53 = 32 + 16 + 4 + 1 = 2^5 + 2^4 + 2^2 + 2^0,這樣乘積就可以表示為變量data移位結(jié)果的相加。對于乘法運(yùn)算符“*”,綜合后通常得到的是乘法器,時(shí)延較大。 賦值語句(1)不要在信號列表中進(jìn)行運(yùn)算操作如:Bad: addr(a,b,damp。e)。 Good: addr(a,b,c)。 c=damp。e。(2)BLOCK賦值和NONBLOCK賦值的使用(a)組合邏輯采用BLOCK賦值(=)如: always @(dat) i_dat = dat。(b)非組合邏輯(主要是寄存器)采用NONBLOCK賦值并加delay以保證前仿真和后仿真的一致如: always @(posedeg clk) q = `DEL d。(3)在同一塊語句中不允許同時(shí)出現(xiàn)阻塞賦值和非阻塞賦值 條件語句(1)IF語句(a)向量比較時(shí),比較的向量長度要相等,同樣向量和常量比較時(shí)長度也要求匹配,長度不同時(shí)要求進(jìn)行顯式位擴(kuò)展(verilog對位數(shù)小的向量做0擴(kuò)展以使它們的長度相匹配,該擴(kuò)展是隱式的)如: reg [7:0] abc。 reg [3:0] def。 ....... if (abc == {439。b0,def}) begin ....... if (abc == 839。h0) begin(b)不要采用if表達(dá)式的簡寫形式例如: if (variable) 等同于 if (variable != 0) if (!variable) 等同于 if (variable == 0) 但后者才合乎規(guī)范(c)每個(gè)if都應(yīng)該有一個(gè)else與之相對應(yīng),如果條件為假時(shí)不進(jìn)行任何操作,則用一條空語句else;避免產(chǎn)生latch(d)if...else if...else if...else的代碼書寫格式如下,要注意優(yōu)先級if (...) begin ......endelse begin if (...) ...... else (...) if (...) else (...)end(d)如果變量在ifelse語句中非完全賦值,則應(yīng)給變量一個(gè)缺省值如: if (a == b) begin v1 = 239。b01。 v2 = 239。b10。 //v3 is not assigned end else if (a == c) begin v2 = 239。b10。 v3 = 239。b11。 //v1 is not assigned endelse //default賦值 begin v1 = 239。b00。 v2 = 239。b00。 v3 = 239。b00。 end(2)CASE語句(a)所有的case語句都應(yīng)該有一個(gè)default語句,避免產(chǎn)生Latch(b)(建議)不要使用casex、casez語句,綜合工具不支持 循環(huán)語句(1)forever語句(2)repeat語句(3)while語句(4)for語句在可以用其它語句描述電路時(shí),建議不要采用循環(huán)語句來描述。 initial語句不要在RTL代碼中出現(xiàn)initial 塊綜合會將initial塊忽略,使前仿真和后仿真不一致initial begin......end always語句(1)在使用always生成組合邏輯時(shí),敏感表要列全,敏感表中也不能包含沒有用到的變量。Rule:Combinational sensitivity lists should include1)Any signal on right hand side of assignment2)Any signal in if or case expressionFor example:......module sense_list_ex( b, c, d )。//PARAMETER//INPUTSinput b。input c。input d。//OUTPUTS//INOUTS//SIGNAL DECLARATIONSwire b。wire c。wire d。reg a。//ASSIGN STATEMENTS//MAIN CODE always @ (b or c or d) if (b==1’b1) a = c amp。 d。 else if (c==1’b1) a = d。endmodule //SENSE_LIST_EX (2)對帶異步清零端的寄存器的定義模板always @(posedge clk_main or negedge rst_n) if (rst_n == 139。b0) //此處統(tǒng)一采用rst_n == 139。b0形式而不采用(! rst_n) begin //形式,對相關(guān)寄存器清0(采用 `u_dly= 賦值) ...... end else begin //對相關(guān)寄存器賦值(采用 `u_dly= 賦值) ...... end采用時(shí)鐘上升沿觸發(fā)。 有限狀態(tài)機(jī)(FSM)(1)組合邏輯和時(shí)序邏輯分開描述; // PART 1: COMBINATERIAL LOGIC FOR NEXT STATEalways @(cur_state or full_new_fr or full or have_space)begin: OVC_FSM_NXT_ST case (cur_state) STDBY: begin if (full_new_fr == 139。b1) nxt_state = W_BLOCK。