簡單組合邏輯電路的verilog實現(包括三態門、3-8譯碼器、8-3優先編碼器、8bit奇偶校驗器)


 

2013-06-14 15:20:28

簡單組合邏輯電路的verilog實現,包括三態門、3-8譯碼器、8-3優先編碼器、8bit奇偶校驗器,測試功能正確、可綜合。


 

小結:

  • assign與always都可實現組合邏輯,有什么區別?

組合邏輯用數據流描述(一般將用assign描述的稱為數據流描述)或者RTL描述(一般將用always描述的稱為數據流描述)都可以實現;

當組合邏輯較為簡單時(如用一句話就可以實現的求反、求和assign sum = a + b; assign dout = ~din;等),用assign比較方便;

若組合邏輯比較復雜,則用always比較合適。

  • 組合邏輯用always實現時,敏感列表一定要寫全;
  • 寫代碼時,腦子里要有硬件的的概念,這是與C語言等軟件語言的重要區別之一;
  • 為防止鎖存器,對if語句要加上else,對case語句,要加上default

如下面的就會產生鎖存器:

 1 always@(din)
 2     begin
 3         if(din[7] == 1'b1) dout = 3'b111;
 4         else if(din[6] == 1'b1) dout = 3'b110;
 5         else if(din[5] == 1'b1) dout = 3'b101;
 6         else if(din[4] == 1'b1) dout = 3'b100;
 7         else if(din[3] == 1'b1) dout = 3'b011;
 8         else if(din[2] == 1'b1) dout = 3'b010;
 9         else if(din[1] == 1'b1) dout = 3'b001;
10         else if(din[0] == 1'b1) dout = 3'b000;
11         else dout = dout; 
12     end

改為如下,則不會有鎖存器:

 1 always@(din)
 2     begin
 3         if(din[7] == 1'b1) dout = 3'b111;
 4         else if(din[6] == 1'b1) dout = 3'b110;
 5         else if(din[5] == 1'b1) dout = 3'b101;
 6         else if(din[4] == 1'b1) dout = 3'b100;
 7         else if(din[3] == 1'b1) dout = 3'b011;
 8         else if(din[2] == 1'b1) dout = 3'b010;
 9         else if(din[1] == 1'b1) dout = 3'b001;
10         else dout = 3'b000;  //防止產生鎖存器,將上面兩行換為這一行
11     end

 


 

簡單門電路的門級、數據流、RTL描述


實現組合邏輯:f = ~(ab)|(bcd)

代碼:

 1 odule simple_gate(
 2                             a,
 3                             b,
 4                             c,
 5                             d,
 6                             f
 7                                  );
 8      
 9 input a;
10 input b;     
11 input c;
12 input d;
13 
14 output f;
15 /*
16 //門級描述
17 nand (f1,a,b);
18 and (f2,b,c,d);
19 
20 or(f,f1,f2);
21 
22 //數據流描述
23 assign f = ~(a & b) | (b & c & d);
24 */
25 //RTL描述
26 reg f;
27 always@(a,b,c,d)
28     begin
29         f = ~(a & b) | (b & c & d);
30     end
31 
32 endmodule

 

門級描述綜合后得到的RTL級電路:

 

數據流描述綜合后得到的RTL級電路:

 

RTL描述綜合后得到的RTL級電路與數據流描述綜合后得到的RTL級電路完全相同。


三態門的門級、數據流、RTL描述:

代碼:

 1 module tri_gate(
 2                     din,
 3                     en,
 4                     dout
 5                          );
 6 
 7 
 8 input din;
 9 input en;
10 
11 output dout;
12 
13 //門級描述
14 //bufif1 (dout,din,en);
15 
16 //數據流描述
17 //assign dout = en ? din : 1'bz;
18 
19 //RTL描述
20 reg dout;
21 
22 always@(din,en)
23     if(en)
24         dout = din;
25     else
26         dout = 1'bz;
27 
28 endmodule

 

門級描述綜合,RTL圖:

數據流描述綜合,RTL圖與門級的完全相同。

 

RTL描述綜合,RTL圖同樣與門級的完全相同。


3-8譯碼器的verilog實現

RTL描述,用case語句或if...if 語句實現,如下:

 1 module decode_3to8(
 2                         din,
 3                         dout
 4                              );
 5 
 6 input [2:0] din;
 7 output [7:0] dout;
 8 
 9 reg [7:0] dout;
10 
11 //case語句實現
12 always@(din)
13     case(din)
14         3'b000 : dout = 8'b0000_0001;
15         3'b001 : dout = 8'b0000_0010;
16         3'b010 : dout = 8'b0000_0100;
17         3'b011 : dout = 8'b0000_1000;
18         3'b100 : dout = 8'b0001_0000;
19         3'b101 : dout = 8'b0010_0000;
20         3'b110 : dout = 8'b0100_0000;
21         3'b111 : dout = 8'b1000_0000;
22     endcase
23 /*    
24 //if...if語句實現
25 always@(din)
26     begin    
27             if (din == 3'b000)  dout = 8'b0000_0001;
28             if (din == 3'b001)  dout = 8'b0000_0010;
29             if (din == 3'b010)  dout = 8'b0000_0100;
30             if (din == 3'b011)  dout = 8'b0000_1000;
31             if (din == 3'b100)  dout = 8'b0001_0000;
32             if (din == 3'b101)  dout = 8'b0010_0000;
33             if (din == 3'b110)  dout = 8'b0100_0000;
34             if (din == 3'b111)  dout = 8'b1000_0000;
35     end
36 */    
37 endmodule

 

用case語句或if語句時:

 綜合選項中Decoder Extraction設為YES,自動綜合為用器件本身的硬件譯碼器實現,如下:

若綜合選項Decoder Extraction設為NO,用case語句或if語句,綜合RTL圖為:

是用8bitROM實現的 


 8-3優先編碼器的verilog實現

RTL描述,用if...else的特點實現優先編碼,如下:

 1 module encoder_8to3(
 2                             din,
 3                             dout
 4                                  );
 5 
 6 input [7:0] din;
 7 output [2:0] dout;
 8 
 9 reg [2:0] dout;
10 
11 //if語句中僅僅判斷1個bit即可
12 always@(din)
13     begin
14         if(din[7] == 1'b1) dout = 3'b111;
15         else if(din[6] == 1'b1) dout = 3'b110;
16         else if(din[5] == 1'b1) dout = 3'b101;
17         else if(din[4] == 1'b1) dout = 3'b100;
18         else if(din[3] == 1'b1) dout = 3'b011;
19         else if(din[2] == 1'b1) dout = 3'b010;
20         else if(din[1] == 1'b1) dout = 3'b001;
21         //else if(din[0] == 1'b1) dout = 3'b000;
22         //else dout = dout; 
23         else dout = 3'b000;  //防止產生鎖存器,將上面兩行換為這一行
24     end
25 
26 /*
27 //if語句中僅僅判斷1個bit即可,這種是錯誤的
28 always@(din)
29     begin
30         if(din == 8'b1000_0000) dout = 3'b111;
31         else if(din == 8'b0100_0000) dout = 3'b110;
32         else if(din == 8'b0010_0000) dout = 3'b101;
33         else if(din == 8'b0001_0000) dout = 3'b100;
34         else if(din == 8'b0000_1000) dout = 3'b011;
35         else if(din == 8'b0000_0100) dout = 3'b010;
36         else if(din == 8'b0000_0010) dout = 3'b001;
37         else if(din == 8'b0000_0001) dout = 3'b000;
38     end
39 */
40 endmodule

 

綜合選項中Priority Encoder Extraction為YES,但是綜合結果並沒有使用優先編碼器,原因未知。

改變代碼,去掉鎖存器:

//else if(din[0] == 1'b1) dout = 3'b000;
 //else dout = dout;
  else dout = 3'b000;  //防止產生鎖存器,將上面兩行換為這一行

綜合結果,可以看到,沒有鎖存器了:


 奇偶校驗器的verilog實現

數據流描述:

 1 module odd_even_check(
 2                             din,
 3                             dout_even,
 4                             dout_odd
 5                                  );
 6 
 7 input [7:0] din;
 8 output dout_even;
 9 output dout_odd;
10 
11 assign dout_odd = ^din;        //奇校驗位
12 assign dout_even = ~dout_odd;    //偶校驗位
13 
14 endmodule

綜合RTL圖:


 4選1數據選擇器

可以用case或者if語句實現:

 

 1 module mux(
 2                 din1,
 3                 din2,
 4                 din3,
 5                 din4,
 6                 sel,
 7                 dout
 8                      );
 9      
10 input din1;
11 input din2;
12 input din3;
13 input din4;
14 input [1:0] sel;
15 
16 output dout;
17 
18 reg dout;
19 /*
20 //用case語句實現
21 always@(din1,din2,din3,din4,sel)
22     begin
23         case(sel)
24             2'b00 : dout = din1;
25             2'b01 : dout = din2;
26             2'b10 : dout = din3;
27             default : dout = din4;    
28         endcase
29     end     
30 */
31 
32 //用if語句實現
33 always@(din1,din2,din3,din4,sel)
34     begin
35         if(sel == 2'b00) dout = din1;
36         else if(sel == 2'b01) dout = din2;
37         else if(sel == 2'b10) dout = din3;
38         else dout = din4;
39     end
40 
41 endmodule

 

case語句與if語句描述綜合結果完全相同,如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM