博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单组合逻辑电路的verilog实现(包括三态门、3-8译码器、8-3优先编码器、8bit奇偶校验器)...
阅读量:7069 次
发布时间:2019-06-28

本文共 6416 字,大约阅读时间需要 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     begin29         f = ~(a & b) | (b & c & d);30     end31 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     else26         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     endcase23 /*    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     end36 */    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     begin14         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     end25 26 /*27 //if语句中仅仅判断1个bit即可,这种是错误的28 always@(din)29     begin30         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     end39 */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     begin23         case(sel)24             2'b00 : dout = din1;25             2'b01 : dout = din2;26             2'b10 : dout = din3;27             default : dout = din4;    28         endcase29     end     30 */31 32 //用if语句实现33 always@(din1,din2,din3,din4,sel)34     begin35         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     end40 41 endmodule

 

case语句与if语句描述综合结果完全相同,如下:

转载地址:http://chqll.baihongyu.com/

你可能感兴趣的文章