简单组合逻辑电路的verilog实现(包括三态门、3-8译码器、8-3优先编码器、8bit奇偶校验器)

时间:2024-02-20 12:08:21

 

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语句描述综合结果完全相同,如下: