當(dāng)前位置:首頁(yè) > EDA > 電子設(shè)計(jì)自動(dòng)化
[導(dǎo)讀] 4.5.1 always塊語(yǔ)言指導(dǎo)原則使用always塊進(jìn)行可綜合的代碼設(shè)計(jì)時(shí)需要注意以下幾個(gè)問(wèn)題。(1)每個(gè)always塊只能有一個(gè)事件控制“@(event-expression)”,而且要緊跟在always關(guān)鍵字后面。(2)always塊可以表示

 4.5.1 always塊語(yǔ)言指導(dǎo)原則

使用always塊進(jìn)行可綜合的代碼設(shè)計(jì)時(shí)需要注意以下幾個(gè)問(wèn)題。

(1)每個(gè)always塊只能有一個(gè)事件控制“@(event-expression)”,而且要緊跟在always關(guān)鍵字后面。

(2)always塊可以表示時(shí)序邏輯或者組合邏輯,也可以用always塊既表示電平敏感的透明鎖存器又同時(shí)表示組合邏輯。但是不推薦使用這種描述方法,因?yàn)檫@容易產(chǎn)生錯(cuò)誤和多余的電平敏感的透明鎖存器。

(3) 帶有posedge 或 negedge 關(guān)鍵字的事件表達(dá)式表示沿觸發(fā)的時(shí)序邏輯;沒(méi)有posedge 或negedge關(guān)鍵字的表示組合邏輯或電平敏感的鎖存器,或者兩種都表示。在表示時(shí)序和組合邏輯的事件控制表達(dá)式中如有多個(gè)沿和多個(gè)電平,其間必須用關(guān)鍵字“or” 連接 。

(4)每個(gè)表示時(shí)序邏輯的always塊只能由一個(gè)時(shí)鐘跳變沿觸發(fā),置位或復(fù)位最好也由該時(shí)鐘跳變沿觸發(fā)。

(5)每個(gè)在always塊中賦值的信號(hào)都必需定義成reg型或整型。整型變量缺省為32bit,使用Verilog操作符可對(duì)其進(jìn)行二進(jìn)制求補(bǔ)的算術(shù)運(yùn)算。綜合器還支持整型量的范圍說(shuō)明,這樣就允許產(chǎn)生不是32位的整型量,句法結(jié)構(gòu)如下:

integer[:]。

(6)always塊中應(yīng)該避免組合反饋回路。每次執(zhí)行always塊時(shí),在生成組合邏輯的always塊中賦值的所有信號(hào)必需都有明確的值;否則需要設(shè)計(jì)者在設(shè)計(jì)中加入電平敏感的鎖存器來(lái)保持賦值前的最后一個(gè)值。

只有這樣,綜合器才能正常生成電路。如果不這樣做,綜合器會(huì)發(fā)出警告,提示設(shè)計(jì)中插入了鎖存器。如果在設(shè)計(jì)中存在綜合器認(rèn)為不是電平敏感鎖存器的組合回路時(shí),綜合器會(huì)發(fā)出錯(cuò)誤信息(例如設(shè)計(jì)中有異步狀態(tài)機(jī)時(shí))。

用always塊設(shè)計(jì)純組合邏輯電路時(shí),在生成組合邏輯的always塊中,參與賦值的所有信號(hào)都必須有明確的值,即在賦值表達(dá)式右端參與賦值的信號(hào)都必需在always @(敏感電平列表)中列出。

如果在賦值表達(dá)式右端引用了敏感電平列表中沒(méi)有列出的信號(hào),那么在綜合時(shí),將會(huì)為該信號(hào)產(chǎn)生一個(gè)隱含的透明鎖存器。這是因?yàn)樵撔盘?hào)的變化不會(huì)立刻引起所賦值的變化,而必須等到敏感電平列表中某一個(gè)信號(hào)變化時(shí),它的作用才顯現(xiàn)出來(lái)。

也就是相當(dāng)于存在著一個(gè)透明鎖存器把該信號(hào)的變化暫存起來(lái),待敏感電平列表中某一個(gè)信號(hào)變化時(shí)再起作用,純組合邏輯電路不可能做到這一點(diǎn)。這樣,綜合后所得電路已經(jīng)不是純組合邏輯電路了。這時(shí)綜合器會(huì)發(fā)出警告提示設(shè)計(jì)中插入了鎖存器,如下所示:

input a,b,c;
reg e,d;
always @(a or b or c) begin
      e = d & a & b;       //因?yàn)閐沒(méi)有在敏感電平列表中,所以d變化時(shí),e不能立刻變化,
                              //要等到a或b或c變化時(shí)才體現(xiàn)出來(lái)。這就是說(shuō)實(shí)際上相當(dāng)于存在
                              //一個(gè)電平敏感的透明鎖存器在起作用, 把d信號(hào)的變化鎖存其中
      d = e | c;
end

(7)對(duì)一個(gè)寄存器型(reg)或整型(integer)變量的賦值只允許在一個(gè)always塊內(nèi)進(jìn)行,如果在另一always塊也對(duì)其賦值,這是非法的。
(8)把某一信號(hào)值賦為'bx,綜合器就把它解釋成無(wú)關(guān)狀態(tài),因而綜合器為其生成的硬件電路最簡(jiǎn)潔。


4.5.2  可綜合風(fēng)格的Verilog HDL模塊實(shí)例
1.組合邏輯電路設(shè)計(jì)實(shí)例


例4.6:8位帶進(jìn)位端的加法器的設(shè)計(jì)實(shí)例(利用簡(jiǎn)單的算法描述)。

module adder_8(cout,sum,a,b,cin);               //模塊聲明
      output cout;
      output [7:0] sum;
      input cin;
      input[7:0] a,b;                             //端口聲明
      assign {cout,sum} = a + b + cin;          //加法器算法
endmodule

 

例4.7:指令譯碼電路的設(shè)計(jì)實(shí)例(利用電平敏感的always塊來(lái)設(shè)計(jì)組合邏輯)。

'define plus     3'd0                         //操作碼的宏定義
'define minus    3'd1
'define band     3'd2
'define bor      3'd3'
'define unegate  3'd4

module alu(out,opcode,a,b);                 //模塊聲明
      output [7:0] out;
      input [2:0] opcode;
      input [7:0] a,b;                       //端口聲明
      reg   [7:0] out;                      //寄存器聲明

      always @(opcode or a or b) begin       //用電平敏感的always塊描述組合邏輯
            case(opcode)
                  'plus: out = a + b;         //算術(shù)運(yùn)算
                  'minus: out = a - b;
                  'band: out = a & b;          //位運(yùn)算
                  'bor:  out = a | b;
                  'unegate: out = ~a;        //單目運(yùn)算
                   default: out = 8'hx;
      endcase
      end
endmodule

 

例4.8:比較后重組信號(hào)的組合邏輯(利用task和電平敏感的always塊設(shè)計(jì))。

module sort4(ra,rb,rc,rd,a,b,c,d);         //模塊聲明
      output [t:0] ra, rb, rc, rd;
      input [t:0] a, b, c, d;               //端口聲明
      reg [t:0] ra, rb, rc, rd;
      reg [t:0] va, vb, vc, vd;             //寄存器聲明
      parameter t=3;                            //參數(shù)聲明

      always @(a or b or c or d) begin       //用電平敏感的always塊描述組合邏輯
           {va,vb,vc,vd}={a,b,c,d};
           sort2(va,vc);                        //信號(hào)重組
           sort2(vb,vd);
           sort2(va,vb);
           sort2(vc,vd);
           sort2(vb,vc);
           {ra,rb,rc,rd}={va,vb,vc,vd};
      end

      task sort2;                             //x與y互換任務(wù)
            inout [t:0] x,y;
            reg [t:0] tmp;
            if(x > y) begin
                 tmp = x;               //使用臨時(shí)變量tmp保存x的值
                 x = y;
                 y = tmp;
      end
      endtask
endmodule

 

例4.9:比較器的設(shè)計(jì)實(shí)例(利用賦值語(yǔ)句設(shè)計(jì)組合邏輯)。

module compare(equal,a,b);              //模塊聲明
      output equal;
      input [size-1:0] a,b;            //端口聲明
      parameter size=1;                  //參數(shù)聲明
      assign  equal =(a==b)? 1 : 0;  //比較器
endmodule

 

例4.10:3-8譯碼器設(shè)計(jì)實(shí)例(利用賦值語(yǔ)句設(shè)計(jì)組合邏輯)。

module decoder(out,in);             //模塊聲明
      output [7:0] out;
      input [2:0] in;                 //端口聲明
      assign  out = 1'b1<<in;       //把最低位的1左移 in(根據(jù)從in口輸入的值)位
                                          //將移位結(jié)果賦予out
endmodule

 

例4.11:3-8編碼器的設(shè)計(jì)實(shí)例。
編碼器設(shè)計(jì)方案一。

module encoder1(none_on,out,in);            //模塊聲明
      output none_on;
      output [2:0] out;
      input [7:0] in;                         //端口聲明
      reg [2:0] out;
      reg none_on;                              //寄存器聲明
      always @(in) begin: local                //in有變化時(shí),觸發(fā)
            integer  i;                           //變量聲明
            out = 0;
            none_on = 1;                         //初始化
            for( i=0; i<8; i=i+1 ) begin      //for循環(huán)語(yǔ)句
                 if( in[i] ) begin         //將in中值為1的位編碼
                      out = i;
                      none_on = 0;
                 end
            end
      end
endmodule

 

編碼器設(shè)計(jì)方案二。

module encoder2 ( none_on,out2,out1,out0,h,g,f,e,d,c,b,a);     //模塊聲明
      input h,g,f,e,d,c,b,a;
      output none_on,out2,out1,out0;         //端口聲明
      wire [3:0] outvec;                      //向量聲明
      assign outvec =                           //使用assign語(yǔ)句實(shí)現(xiàn)輸出向量賦值
            h ? 4'b0111 : g ? 4'b0110 : f ? 4'b0101:
            e ? 4'b0100 : d ? 4'b0011 : c ? 4'b0010 :
            b ? 4'b0001 : a ? 4'b0000 : 4'b1000;
      assign none_on = outvec[3];            //使用assign語(yǔ)句進(jìn)行編碼
      assign    out2 = outvec[2];
      assign    out1 = outvec[1];
      assign    out0 = outvec[0];
endmodule

 

編碼器設(shè)計(jì)方案三。

module encoder3 ( none_on,out2,out1,out0,h,g,f,e,d,c,b,a);     //模塊聲明
      input h,g,f,e,d,c,b,a;
      output none_on,out2,out1,out0;      //端口聲明
      wire [3:0] outvec;                    //向量聲明
      assign {none_on,out2,out1,out0} = outvec;   //與上例的編碼方式一致
      always @( a or b or c or d or e or f or g or h) begin
            if(h)       outvec=4'b0111;     //使用if_else語(yǔ)句實(shí)現(xiàn)向量賦值
            else if(g) outvec=4'b0110; //共9個(gè)分支,其中向量的低3位有8種編碼方式
            else if(f) outvec=4'b0101;
            else if(e) outvec=4'b0100;
            else if(d) outvec=4'b0011;
            else if(c) outvec=4'b0010;
            else if(b) outvec=4'b0001;
            else if(a) outvec=4'b0000;
            else         outvec=4'b1000;
      end
endmodule

例4.12:多路器的設(shè)計(jì)實(shí)例。


使用assign賦值語(yǔ)句、case語(yǔ)句或if-else語(yǔ)句可以生成多路器電路。如果條件語(yǔ)句(case或if-else)中分支條件是互斥的話,綜合器能自動(dòng)地生成并行的多路器。
多路器設(shè)計(jì)方案一。

modul emux1(out,a,b,sel);                //模塊聲明
     output out;
     input a,b,sel;                         //端口聲明
                                               //使用assign語(yǔ)句檢查輸入信號(hào)sel的值
     assign out = sel ? a : b;            //當(dāng)sel為1時(shí),out為a;否則為b
endmodule

 

多路器設(shè)計(jì)方案二。

module  mux2( out,a,b,sel);          //模塊聲明
      output out;
      input a,b,sel;                    //端口聲明
      reg out;
      always @(a or b or sel) begin //用電平觸發(fā)的always塊來(lái)設(shè)計(jì)多路器的組合邏輯
            case( sel )                 //使用case語(yǔ)句檢查輸入信號(hào)sel的值
                1'b1: out = a;         //如果為1,輸出out為a
                1'b0: out = b;         //如果為0,輸出out為b
                default: out = 'bx;   //默認(rèn)狀態(tài)
            endcase
      end
endmodule

 

多路器設(shè)計(jì)方案三。

module mux3( out,a,b sel);                 //模塊聲明
      output out;
      input a, b, sel;                       //端口聲明
      reg out;
      always @( a or b or sel ) begin
           if( sel )                          //使用if_else語(yǔ)句檢查輸入信號(hào)sel的值
                out = a;                      //如果為1,輸出out為a
           else
                out = b;                      //如果為0,輸出out為b
      end
endmodule

 

例4.13:奇偶校驗(yàn)位生成器設(shè)計(jì)實(shí)例。

module parity( even_numbits,odd_numbits,input_bus);  //模塊聲明
      output even_numbits, odd_numbits;
      input [7:0] input_bus;                  //端口聲明
      assign odd_numbits = ^input_bus; //當(dāng)input_bus中1的個(gè)數(shù)為奇數(shù)時(shí),輸出為1
      assign even_numbits = ~odd_numbits;  //此時(shí)輸出even_numbits為0
endmodule

 

例4.14:三態(tài)輸出驅(qū)動(dòng)器設(shè)計(jì)實(shí)例(用連續(xù)賦值語(yǔ)句建立三態(tài)門模型)。
三態(tài)輸出驅(qū)動(dòng)器設(shè)計(jì)方案一。

module trist1( out,in,enable);            //模塊聲明
      output out;
      input in, enable;                     //端口聲明
      assign  out = enable? in: 'bz;      //使用assign語(yǔ)句判斷enable的值
endmodule

 

三態(tài)輸出驅(qū)動(dòng)器設(shè)計(jì)方案二。

module trist2( out,in,enable );    //模塊聲明
      output out;
      input in,enable;                //端口聲明
      bufif1 mybuf1(out, in, enable); //bufif1是一個(gè) Verilog門級(jí)原語(yǔ)(primitive)
                                         //通過(guò)實(shí)例化該原語(yǔ),實(shí)現(xiàn)三態(tài)門的調(diào)用
endmodule

 

例4.15:三態(tài)雙向驅(qū)動(dòng)器設(shè)計(jì)實(shí)例。

module bidir(tri_inout,out,in,en,b);         //模塊聲明
      inout tri_inout;
      output out;
      input in,en,b;                             //端口聲明
      assign tri_inout = en? in : 'bz;       //三態(tài)門的輸入為in
      assign out = tri_inout ^ b;             //三態(tài)門的輸出為b
endmodule


2.時(shí)序邏輯電路設(shè)計(jì)實(shí)例
例4.16:觸發(fā)器設(shè)計(jì)實(shí)例。

module dff( q,data,clk);                  //模塊聲明
      output q;
      input data,clk;                       //端口聲明
      reg q;
      always @( posedge clk ) begin      //邊緣檢測(cè)
            q = data;                        //通過(guò)always語(yǔ)句,實(shí)現(xiàn)觸發(fā)器
      end
endmodule

 

例4.17:電平敏感型鎖存器設(shè)計(jì)實(shí)例一(assign語(yǔ)句)。

module latch1( q,data,clk);                //模塊聲明
      output q;
      input data,clk;                        //端口聲明
      assign q = clk ? data : q;           //通過(guò)assign語(yǔ)句,實(shí)現(xiàn)的是一個(gè)鎖存器
endmodule

 

例4.18:帶置位和復(fù)位端的電平敏感型鎖存器設(shè)計(jì)實(shí)例二(assign語(yǔ)句)。

module latch2( q,data,clk,set,reset);   //模塊聲明
      output q;
      input data,clk,set,reset;           //端口聲明
      assign q= reset ? 0 : ( set? 1:(clk? data : q ) );
                                               //通過(guò)assign語(yǔ)句,實(shí)現(xiàn)的是一個(gè)鎖存器
                                               //其中,set為置位端,reset為復(fù)位端
                                               //在clk為高電平時(shí),鎖存data,否則保持q值
endmodule

 

例4.19:電平敏感型鎖存器設(shè)計(jì)實(shí)例三(always塊)。

module latch3( q, data, clk);           //模塊聲明
      output q;
      input data,clk;                      //端口聲明
      reg q;
      always @(clk or data) begin       //電平檢測(cè)
            if(clk)                         //clk為高電平時(shí),q鎖存data值
                  q = data;
      end
endmodule

 

  注意 有的綜合器會(huì)產(chǎn)生一個(gè)警告信息,提示將產(chǎn)生了一個(gè)電平敏感型鎖存器。因?yàn)榇死性O(shè)計(jì)的就是一個(gè)電平敏感型鎖存器,所以這個(gè)警告信息是沒(méi)有問(wèn)題的。

 

例4.20:移位寄存器設(shè)計(jì)實(shí)例。

module shifter( din,clk,clr,dout);         //模塊聲明
      input din,clk,clr;
      output [7:0] dout;                     //端口聲明
      reg [7:0] dout;
      always @(posedge clk) begin
            if(clr)                             //清零
                   dout = 8'b0;
            else begin
                   dout = dout<<1;             //左移一位
                   dout[0] = din;             //把輸入信號(hào)放入寄存器的最低位
            end
      end
endmodule


例4.21:8位計(jì)數(shù)器設(shè)計(jì)實(shí)例一。

module counter1( out, cout, data, load, cin, clk);     //模塊聲明
      output [7:0] out;
      output cout;
      input [7:0] data;
      input load, cin, clk;                //端口聲明
      reg [7:0] out;
      always @(posedge clk) begin         //邊緣檢測(cè)
            if( load )                        //加載信號(hào)檢測(cè)
                 out = data;
            else
                 out = out + cin;
            end
      assign cout= & out & cin;           //只有當(dāng)out[7:0]的所有各位都為1
                                               //并且進(jìn)位cin也為1時(shí)才能產(chǎn)生進(jìn)位cout
endmodule

 

例4.22:8位計(jì)數(shù)器設(shè)計(jì)實(shí)例二。

module counter2( out, cout, data, load, cin, clk);     //模塊聲明
      output [7:0] out;
      output cout;
      input [7:0] data;
      input load, cin, clk;                     //端口聲明
      reg [7:0] out;
      reg cout;
      reg [7:0] preout;                         //寄存器聲明
      always @(posedge clk) begin              //邊緣檢測(cè)
            out = preout;                         //觸發(fā)器
            end
      //計(jì)算計(jì)數(shù)器和進(jìn)位的下一個(gè)狀態(tài),為提高性能,load不應(yīng)影響進(jìn)位
      always @( out or data or load or cin ) begin
            {cout, preout} = out + cin;        //進(jìn)位操作
            if(load) preout = data;             //判斷加載信號(hào)
            end
endmodule

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉