天天看点

Verilog学习笔记(05)

文章目录

    • 6. 组合逻辑电路
      • 1. 数据比较器
      • 2. 数据选择器
      • 3. 数据分配器
      • 4. 数据编码器
      • 5. 数据译码器
      • 6. 数据校验器

参考:Verilog数字VLSI设计教程

硬件描述语言Verilog

Verilog HDL数字设计与综合

Verilog HDL 数字集成电路高级程序设计

6. 组合逻辑电路

当一个数字电路中的输出信号完全是由输入信号所决定时,这样的电路称之为组合电路

组合电路基本设计方式

Verilog学习笔记(05)

1. 数据比较器

1位数据比较器

Verilog学习笔记(05)
Verilog学习笔记(05)

Verilog设计代码如下:

module comp_1b(a,b,agb,aeb,alb);
input a,b;
output agb,aeb,alb;
wire agb,aeb,alb;
assign agb=a&(~b);
assign aeb=a^~b;
assign alb=(~a)&b;
endmodule
           

测试环境如下:

module comp_1b_tb;
  reg a,b;
  wire agb,aeb,alb;
  comp_1b U1(.a(a),.b(b),.agb(agb),.aeb(aeb),.alb(alb));
  initial 
  begin 
    a=1'b1;b=1'b1;
    #100 a=1'b0;
    #100 a=1'b1;b=1'b0;
    #100 a=1'b0;
    #100 b=1'b1;
    #200 $finish;
  end
endmodule
           

设计一个8位数据比较器

Verilog学习笔记(05)
module  comp_8b(a,b,agb,aeb,alb);
  parameter w=8;
  input [w-1:0]a,b;
  output agb,aeb,alb;
  reg agb,aeb,alb;
  always@(a or b)
  if(a>b) {agb,aeb,alb}=3'b100;
  else if(a<b) {agb,aeb,alb}=3'b001;
  else {agb,aeb,alb}=3'b010;
endmodule
           
module comp_8b_tb;
  reg [7:0]a,b;
  wire agb,aeb,alb;
  comp_8b U3(.a(a),.b(b),.agb(agb),.aeb(aeb),.alb(alb));
  initial
  begin
        a=8'b00110101;b=8'b00110100;
    #100 a=8'b00110011;b=8'b00110011;
    #100 a=8'b00110011;b=8'b10110011;
    #100 a=8'b11110011;b=8'b01110011; 
    #100 a=8'b01100110;b=8'b01100110;
    #100 a=8'b00110000;b=8'b11000011;
    #100 a=8'b00111111;b=8'b00000000;
    #200 $finish;
  end
endmodule
           

2. 数据选择器

设计一个MUX2to1

Verilog学习笔记(05)
module mux2to1(d_in,d_out,sel);
  input [1:0]d_in;
  input sel;
  output d_out;
  wire d_out;
  assign d_out=sel?d_in[1]:d_in[0];
endmodule
           

或者

module mux2to1_1(d_in,d_out,sel);
  input [1:0]d_in;
  input sel;
  output d_out;
  reg d_out;
  always @(d_in or sel)
  begin
    if(sel) d_out=d_in[1];
    else    d_out=d_in[0];
  end
endmodule
           
module mux2to1_tb;
  reg[1:0]d_in;
  reg sel;
  wire d_out;
  mux2to1 U2(.d_in(d_in),.d_out(d_out),.sel(sel));
   initial
   begin
     d_in=2'b10;sel=1'b0;
     #100 sel=1'b1;
     #100 d_in=2'b11;
     #100 sel=1'b0;
     #100 d_in=2'b01;
     #100 sel=1'b1;
     #100 d_in=00;
     #100 sel=1'b0;
     #200 $finish;
   end
 endmodule
           

设计一个MUX4to1

Verilog学习笔记(05)
Verilog学习笔记(05)
Verilog学习笔记(05)
module mux4to1_2(d_in,d_out,sel);
  input [3:0]d_in;
  input [1:0]sel;
  output d_out;
  wire d_out;
  wire [1:0]w1;
  assign  w1=sel[0]?{d_in[3],d_in[1]}:{d_in[2],d_in[0]};  
  assign d_out=sel[1]?w1[1]:w1[0];  
 endmodule
           
module mux4to1_2_tb;
   reg [3:0]d_in;
   reg [1:0]sel;
   wire d_out;
   mux4to1_2 U1(.d_in(d_in),.d_out(d_out),.sel(sel));
   initial
   begin
     d_in=4'b1010;sel=2'b00;
     #100 sel=2'b01;
     #100 sel=2'b11;
     #100 sel=2'b10;
     #100 d_in=4'b1100;
     #100 sel=2'b11;
     #100 sel=2'b00;
     #100 sel=2'b01;
     #200 $finish;
   end
 endmodule
           

3. 数据分配器

设计一个1-4数据分配器

Verilog学习笔记(05)
Verilog学习笔记(05)
module dmux_4(en,din,dout,sel); 
  input en,din; 
  input [1:0]sel; 
  output[3:0]dout; 
  reg[3:0]dout; 
  always@(en or sel or din) 
  if(!en) dout=4'b0; 
  else 
  case(sel) 
    2'b00:dout[0]=din; 
    2'b01:dout[1]=din; 
    2'b10:dout[2]=din; 
    2'b11:dout[3]=din; 
  endcase 
endmodule
           
module dmux_4_tb;
  reg en,din;
  reg[1:0]sel;
  wire[3:0]dout;
  dmux_4 U1(.din(din),.en(en),.sel(sel),.dout(dout));
  initial
  begin
    en=1'b0;din=1'b1;sel=2'b00;
    #100 en=1'b1;
    #100 sel=2'b01;
    #100 sel=2'b11;
    #100 din=1'b0;sel=2'b01;
    #100 din=1'b1;
    #100 sel=2'b11;
    #200 $finish;
  end
endmodule
           

4. 数据编码器

BCD编码器

Verilog学习笔记(05)
Verilog学习笔记(05)
module BCD8421(d_in,d_out);
  input [8:0]d_in;
  output [3:0]d_out;
  reg [3:0]d_out;
  always@(d_in)
  case(d_in)
    9'b000000000:d_out=4'b0000;
    9'b000000001:d_out=4'b0001;
    9'b000000010:d_out=4'b0010;
    9'b000000100:d_out=4'b0011;
    9'b000001000:d_out=4'b0100;
    9'b000010000:d_out=4'b0101;
    9'b000100000:d_out=4'b0110;
    9'b001000000:d_out=4'b0111;
    9'b010000000:d_out=4'b1000;
    9'b100000000:d_out=4'b1001;
    default d_out= 4'b0000;
  endcase
endmodule
           
module BCD8421_tb;
  reg[8:0]d_in;
  wire[3:0]d_out;
  BCD8421 U0(.d_in(d_in),.d_out(d_out));
  initial
  begin
    d_in=9'b010000000;
    #100 d_in=9'b000000001;
    #100 d_in=9'b000000010;
    #100 d_in=9'b000000100;
    #100 d_in=9'b000001000;
    #100 d_in=9'b000010000;
    #100 d_in=9'b100001000;
    #100 d_in=9'b000100000;
    #100 d_in=9'b001000000;
    #100 d_in=9'b000000000;
    #100 d_in=9'b100000000;
    #200 $finish;
  end
endmodule
           

8-3编码器

Verilog学习笔记(05)
Verilog学习笔记(05)
module code8_3(din,dout);
  input [7:0]din;
  output [2:0]dout;
  reg [3:0]dout;
  always@(din)
  case(din)
    8'b00000001:dout=3'b000;
    8'b00000010:dout=3'b001;
    8'b00000100:dout=3'b010;
    8'b00001000:dout=3'b011;
    8'b00010000:dout=3'b100;
    8'b00100000:dout=3'b101;
    8'b01000000:dout=3'b110;
    8'b10000000:dout=3'b111;
    default:dout=3'b000;
endcase
endmodule
           
module code8_3_tb;
  reg[7:0]din;
  wire[2:0]dout;
  code8_3 U1(.din(din),.dout(dout));
  initial
  begin
    din=8'b00001000;
    #100 din=8'b00000001;
    #100 din=8'b01000000;
    #100 din=8'b00000000;
    #100 din=8'b00010000;
    #100 din=8'b00000000;
    #100 din=8'b00100000;
    #100 din=8'b01000000;
    #100 din=8'b10000000;
    #100 din=8'b11000000;
    #200 $finish;
  end
endmodule
           

8-3优先编码器

Verilog学习笔记(05)
Verilog学习笔记(05)
module code8_3_p(din,dout,en,ys,yex);
  input [7:0]din;
  input en;
  output ys,yex;
  output [2:0]dout;
  reg [2:0]dout;
  reg ys,yex;
  always@(din or en)
  if(en) {dout,ys,yex}={3'b111,1'b1,1'b1};
else begin
  casex(din)
  8'b0???????:{dout,ys,yex}={3'b000,1'b1,1'b0};
  8'b10??????:{dout,ys,yex}={3'b001,1'b1,1'b0};
  8'b110?????:{dout,ys,yex}={3'b010,1'b1,1'b0};
  8'b1110????:{dout,ys,yex}={3'b011,1'b1,1'b0};
  8'b11110???:{dout,ys,yex}={3'b100,1'b1,1'b0};
  8'b111110??:{dout,ys,yex}={3'b101,1'b1,1'b0};
  8'b1111110?:{dout,ys,yex}={3'b110,1'b1,1'b0};
  8'b11111110:{dout,ys,yex}={3'b111,1'b1,1'b0};
  8'b11111111:{dout,ys,yex}={3'b111,1'b0,1'b1};
endcase
end
endmodule
           
module code8_3_p_tb;
  reg[7:0]din;
  reg en;
  wire ys,yex;
  wire[2:0]dout;
  code8_3_p U2(.din(din),.dout(dout),.en(en),.ys(ys),.yex(yex));
  initial
  begin
    din=8'b00001100;en=1'b1;
    #100 en=1'b0;din=8'b10000001;
    #100 din=8'b11000010;
    #100 din=8'b11000100;
    #100 din=8'b11101000;
    #100 din=8'b11110000;
    #100 din=8'b11111010;
    #100 din=8'b11111100;
    #100 din=8'b11111110;
    #100 din=8'b11111111;
    #200 $finish;
  end
endmodule
           

余3编码器

Verilog学习笔记(05)
module code_yu3(d_in,d_out);
  input [3:0]d_in;
  output [3:0]d_out;
  assign d_out=d_in+4'b0011;
endmodule
           
module code_yu3_tb;
  reg[3:0]d_in;
  wire[3:0]d_out;
  code_yu3 U4(.d_in(d_in),.d_out(d_out));
  initial
  begin
    d_in=4'b0001;
    #100 d_in=4'b0101;
    #100 d_in=4'b0100;
    #100 d_in=4'b1001;
    #100 d_in=4'b0111;
    #100 d_in=4'b0000;
    #200 $finish;
  end
endmodule
           

5. 数据译码器

3-8译码器

Verilog学习笔记(05)
Verilog学习笔记(05)
Verilog学习笔记(05)
module decode3_8(en,din,dout);
  input [2:0]din;
  input en;
  output [7:0]dout;
  reg [7:0]dout;
  always@(en or din)
  if(!en) dout=8'b0;
  else case(din)
    3'b000:dout=8'b00000001;
    3'b001:dout=8'b00000010;
    3'b010:dout=8'b00000100;
    3'b011:dout=8'b00001000;
    3'b100:dout=8'b00010000;
    3'b101:dout=8'b00100000;
    3'b110:dout=8'b01000000;
    3'b111:dout=8'b10000000;
  endcase
endmodule
           
module decode3_8_tb;
  reg[2:0]din;
  reg en;
  wire[7:0]dout;
  decode3_8 U2(.din(din),.en(en),.dout(dout));
  initial
  begin
    en=1'b1;din=3'b000;
    #100 din=3'b001;
    #100 din=3'b011;
    #100 din=3'b110;
    #100 en=1'b0;din=3'b111;
    #100 en=1'b1;
    #100 din=3'b010;
    #100 din=3'b100;
    #200 $finish;
  end
endmodule
           

8421BCD转二进制译码

Verilog学习笔记(05)
Verilog学习笔记(05)
module decode_BCD(d_in,d_out);
  input [3:0]d_in;
  output [9:0]d_out;
  reg [9:0]d_out;
  always@(d_in)
  begin
    case(d_in)
      4'b0000:d_out=10'b0000000001;
      4'b0001:d_out=10'b0000000010;
      4'b0010:d_out=10'b0000000100;
      4'b0011:d_out=10'b0000001000;
      4'b0100:d_out=10'b0000010000;
      4'b0101:d_out=10'b0000100000;
      4'b0110:d_out=10'b0001000000;
      4'b0111:d_out=10'b0010000000;
      4'b1000:d_out=10'b0100000000;
      4'b1001:d_out=10'b1000000000;
      default:d_out=10'b0;
    endcase
  end
endmodule
           
module decode_BCD_tb;
  reg[3:0]d_in;
  wire[9:0]d_out;
  decode_BCD U3(.d_in(d_in),.d_out(d_out));
  initial
  begin
    d_in=4'b0000;
    #100 d_in=4'b0001;
    #100 d_in=4'b0101;
    #100 d_in=4'b0011;
    #100 d_in=4'b0110;
    #100 d_in=4'b1000;
    #100 d_in=4'b0111;
    #100 d_in=4'b1001;
    #200 $finish;
  end
endmodule
           

8421BCD到七段数码管

Verilog学习笔记(05)
Verilog学习笔记(05)
module BCD_decode(sign,d_in,d_out);
  input [3:0]d_in;
  input sign;
  output [6:0]d_out;
  reg [6:0]d_out;
  always@(sign or d_in)
  begin
    case(d_in)
      4'b0000:d_out=7'b1111110;
      4'b0001:d_out=7'b0110000;
      4'b0010:d_out=7'b1101101;
      4'b0011:d_out=7'b1111001;
      4'b0100:d_out=7'b0110011;
      4'b0101:d_out=7'b1011011;
      4'b0110:d_out=7'b1011111;
      4'b0111:d_out=7'b1110000;
      4'b1000:d_out=7'b1111111;
      4'b1001:d_out=7'b1110011;
      default:d_out=7'b1000111;
  endcase
  if(sign)  d_out=~d_out;
  else d_out=d_out;
end
endmodule
           
module BCD_decode_tb;
  reg[3:0]d_in;
  reg sign;
  wire[6:0]d_out;
  BCD_decode U3(.d_in(d_in),.sign(sign),.d_out(d_out));
  initial
  begin
    d_in=4'b0010;sign=1'b0;
    #100 d_in=4'b1001;
    #100 d_in=4'b0101;
    #100 d_in=4'b0110;sign=1'b1;
    #100 d_in=4'b1000;
    #100 d_in=4'b0111;
    #100 d_in=4'b1001;
    #100 d_in=4'b1100;
    #200 $finish;
  end
endmodule
           

6. 数据校验器

奇偶校验器

Verilog学习笔记(05)
module checker(din,odd,even);
  parameter w=8;
  input [w-1:0]din;
  output odd,even;
  assign odd=^din;
  assign even=!odd;
endmodule
           
module checker_tb;
  reg [7:0]din;
  wire odd,even;
  checker U1(.din(din),.odd(odd),.even(even));
  initial
  begin
    din=8'b00110101;
    #100 din=8'b00110111;
    #100 din=8'b11011011;
    #100 din=8'b00000111;
    #100 din=8'b01110110;
    #200 $finish;
  end 
endmodule