在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 硬件描述語言Verilog HDL設(shè)計進(jìn)階之: 邏輯綜合的原則以及可綜合的代碼設(shè)計風(fēng)格

            硬件描述語言Verilog HDL設(shè)計進(jìn)階之: 邏輯綜合的原則以及可綜合的代碼設(shè)計風(fēng)格

            作者: 時間:2017-06-05 來源:網(wǎng)絡(luò) 收藏

            本文引用地址:http://www.biyoush.com/article/201706/348830.htm

            4.5 的原則以及可綜合的代碼設(shè)計風(fēng)格


            4.5.1 always塊語言指導(dǎo)原則
            使用always塊進(jìn)行可綜合的代碼設(shè)計時需要注意以下幾個問題。


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


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


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


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


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

            integer[msb>:lsb>]identifier>。

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


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


            用always塊設(shè)計純組合邏輯電路時,在生成組合邏輯的always塊中,參與賦值的所有信號都必須有明確的值,即在賦值表達(dá)式右端參與賦值的信號都必需在always @(敏感電平列表)中列出。
            如果在賦值表達(dá)式右端引用了敏感電平列表中沒有列出的信號,那么在綜合時,將會為該信號產(chǎn)生一個隱含的透明鎖存器。這是因為該信號的變化不會立刻引起所賦值的變化,而必須等到敏感電平列表中某一個信號變化時,它的作用才顯現(xiàn)出來。


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

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

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


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


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

            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è)計實例(利用電平敏感的always塊來設(shè)計組合邏輯)。

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

            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ù)運算
            minus: out = a - b;
            band: out = a b; //位運算
            bor: out = a | b;
            unegate: out = ~a; //單目運算
            default: out = 8hx;
            endcase
            end
            endmodule

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

            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); //信號重組
            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; //使用臨時變量tmp保存x的值
            x = y;
            y = tmp;
            end
            endtask
            endmodule

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

            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è)計實例(利用賦值語句設(shè)計組合邏輯)。

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

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

            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有變化時,觸發(fā)
            integer i; //變量聲明
            out = 0;
            none_on = 1; //初始化
            for( i=0; i8; i=i+1 ) begin //for循環(huán)語句
            if( in[i] ) begin //將in中值為1的位編碼
            out = i;
            none_on = 0;
            end
            end
            end
            endmodule

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

            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語句實現(xiàn)輸出向量賦值
            h ? 4b0111 : g ? 4b0110 : f ? 4b0101:
            e ? 4b0100 : d ? 4b0011 : c ? 4b0010 :
            b ? 4b0001 : a ? 4b0000 : 4b1000;
            assign none_on = outvec[3]; //使用assign語句進(jìn)行編碼
            assign out2 = outvec[2];
            assign out1 = outvec[1];
            assign out0 = outvec[0];
            endmodule

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

            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=4b0111; //使用if_else語句實現(xiàn)向量賦值
            else if(g) outvec=4b0110; //共9個分支,其中向量的低3位有8種編碼方式
            else if(f) outvec=4b0101;
            else if(e) outvec=4b0100;
            else if(d) outvec=4b0011;
            else if(c) outvec=4b0010;
            else if(b) outvec=4b0001;
            else if(a) outvec=4b0000;
            else outvec=4b1000;
            end
            endmodule

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


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

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

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

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

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

            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語句檢查輸入信號sel的值
            out = a; //如果為1,輸出out為a
            else
            out = b; //如果為0,輸出out為b
            end
            endmodule

            例4.13:奇偶校驗位生成器設(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的個數(shù)為奇數(shù)時,輸出為1
            assign even_numbits = ~odd_numbits; //此時輸出even_numbits為0
            endmodule

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

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

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

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

            例4.15:三態(tài)雙向驅(qū)動器設(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è)計實例
            例4.16:觸發(fā)器設(shè)計實例。

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

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

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

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

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

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

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

            注意 有的綜合器會產(chǎn)生一個警告信息,提示將產(chǎn)生了一個電平敏感型鎖存器。因為此例中設(shè)計的就是一個電平敏感型鎖存器,所以這個警告信息是沒有問題的。

            例4.20:移位寄存器設(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 = 8b0;
            else begin
            dout = dout1; //左移一位
            dout[0] = din; //把輸入信號放入寄存器的最低位
            end
            end
            endmodule


            例4.21:8位計數(shù)器設(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 //邊緣檢測
            if( load ) //加載信號檢測
            out = data;
            else
            out = out + cin;
            end
            assign cout= out cin; //只有當(dāng)out[7:0]的所有各位都為1
            //并且進(jìn)位cin也為1時才能產(chǎn)生進(jìn)位cout
            endmodule

            例4.22:8位計數(shù)器設(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 //邊緣檢測
            out = preout; //觸發(fā)器
            end
            //計算計數(shù)器和進(jìn)位的下一個狀態(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; //判斷加載信號
            end
            endmodule



            關(guān)鍵詞: VerilogHDL 邏輯綜合 FPGA

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉