从零学verilog系列(4)组合逻辑电路设计方法

 

目录

1.组合电路设计方法

1.1真值表方式(本质是最小项表达式)

1.2逻辑表达式方式

1.3结构描述方式

1.4抽象描述方式(从电路功能出发)

2组合电路设计项目

2.1数字加法器

半加器(1位加法器)

全加器

串行进位加法器(行波进位加法器)

超前进位加法器

2.2数据比较器

2.3数据选择器(MUX)

2.4数字编码器

2.4.1 BCD编码器

2.4.2 8线—3线编码器

2.4.3 8线—3线优先编码器

2.4.4 余3编码

2.5数字译码器

2.6数字校验器

组合电路特点:电路中任意时刻的稳态输出仅仅取决于该时刻的输入,而与电路原来的状态无关。(该电路无记忆功能,只有输入到输出的通路,无从输出到输入的回路)

1.组合电路设计方法

       设计一个3个裁判的表决电路,当两个或两个以上裁判同意时,判决器输出1,否则输出0.下面用四种方式分别设计。

1.1真值表方式(本质是最小项表达式)

//A    B    C    OUT
  0    0    0    0
  0    0    1    0
  0    1    0    0
  0    1    1    1
  1    0    0    0
  1    0    1    1
  1    1    0    1
  1    1    1    1
module voter(A,B,C,out);
input    A,B,C;
output   out;
reg  out;
always@(*)
    begin
        case({A,B,C})
            3'b000:out <= 0;
            3'b001:out <= 0;
            3'b010:out <= 0;
            3'b011:out <= 1;
            3'b100:out <= 0;
            3'b101:out <= 1;
            3'b110:out <= 1;
            3'b111:out <= 1;
        endcase
    end
endmodule                     

1.2逻辑表达式方式

将真值表用卡诺图来表示,然后化解电路得到逻辑函数表达式  out = AB+BC+AC

nodule voter(A,B,C,out);
input      A,B,C;
output     out;
assign out = (A&B)|(B&C)|(A&C)
endmodule

1.3结构描述方式

从逻辑表达式out=AB+BC+AB可获得其基本的电路结构图,根据结构图门级建模即可。

module voter(A,B,C,out);
input  A,B,C;
output out;
wire w1,w2,w3;
and U1(w1,A,B);
and U2(w2,B,C);
and U3(w3,A,C);
or  U4(out,w1,w2,w3);
endmodule

1.4抽象描述方式(从电路功能出发)

module voter(A,B,C,out);
input A,B,C;
output out;
wire [1:0] sum;
assign sum = A+B+C;
always@(sum)
    begin
        if(sum>1)
            out = 1;
        else
            out = 0;
    end
endmodule

2组合电路设计项目

2.1数字加法器

半加器(1位加法器):如果不考虑有来自地位的进位将两个1位二进制数相加,称为半加,实现半加运算的电路称为半加器。

全加器:再将两个多位二进制相加时,除了最低位以外,每一位都应考虑来自低位的进位,即:将两个对应位的加数和来自低位的进位3个数相加,所用的电路称为全加电路。

串行进位加法器(行波进位加法器):使用全加器,依次将低位加法器的进位输出端co接到高位全加器的进位输入端,因每一位的相加结果都必须等到低一位的进位来到之后才能建立,因此这种结构的电路称为~

超前进位加法器:引入生成信号和传播信号,高位的运算不需要等待低位运算完成

这一级进位输入信号Ci+1与上一级的两个加数Ai Bi、上一级的进位输入信号的关系:

第一行包含了所有可能出现进位的情况,第二行为化解之后的结果。

超前进位加法器是一种高速加法器,可提高运算速度,缩短延时   。

//2输入8bit加法器
module eight_bits_fulladder(sum,cout,a,b,c,cin);
input    [7:0] a,b,cin;
output   [7:0] sum;
output         cout;
assign {cout,sum} = a+b+cin;
endmodule

//4bit超前进位加法器  
module fastAdder_4(sum,c_out,a,b,c_in); 
input[3:0] a,b,c_in; 
output[3:0] sum,c_out; 

wire[3:0] g,p; 
wire[4:0] c; 


assign p=a^b;  	 //传播信号
assign g=a&b;    //生成信号
assign c[0]=c_in; 
assign c[1]=g[0]|(p[0]&c[0]);                         //推导公式 
assign c[2]=g[1]|(p[1]&(g[0]|(p[0]&c[0]))); 
assign c[3]=g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0]))))); 
assign c[4]=g[3]|(p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))))));
assign sum = p^c[3:0]; 
assign c_out=c[4]; 
endmodule

2.2数据比较器

数据比较器分为两类:一是等值比较器,只能检测两个数是否一致:二是量值比较强,能比较两个数的大小。

//8bit数据比较强
module comp_8bit(a,b,agb,aeb,a1b);
input    [7:0]    a,b;
output   agb,aeb,a1b;
reg    agb,aeb,a1b;  //agb代表a>b,aeb代表a=b;
always@(a or b)
    begin
        if(a>b)
            {agb,aeb,a1b} = 3'b100;
        else if(a<b)
            {agb,aeb,a1b} = 3'b001;
        else
            {agb,aeb,a1b} = 3'b010;
    end
endmodule

2.3数据选择器(MUX)

常用条件运算符、if_else、case语句等方式实现其功能。

//以4选1选择器为例,用2选1选择器构成的4选1选择器
//有4个数据输入端,2个选择输入端,一个数据输出端。真值表如图:
sel[1]     sel[0]     d_out
0            0        d_in[0]
0            1        d-in[1]
1            0        d_in[2]
1            1        d_in[3]
//条件运算符实现
module mux4to1(d_in,sel,d_out);
input    [3:0] d_in;
input    [1:0] sel;
output         d_out;
wire     [1:0] w1; //sel[0]选择之后的结果
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

//if_else语句实现
module mux4to1(d_in,sel,d_out);
input    [3:0] d_in;
input    [1:0] sel;
output         d_out;
reg            d_out;
always@(*)
    begin
        if(sel[1]==1)
            begin
                if(sel[0]==1)
                    d_out=d_in[3];
                else
                    d_out=d_in[2]; 
            end
        else
            begin
                if(sel[0]==1)
                     d_out=d_in[1];
                else
                     d_out=d_in[0];
            end
    end
endmodule

//case语句实现
module mux4to1(d_in,sel,d_out);
input    [3:0] d_in;
input    [1:0] sel;
output         d_out;
reg            d_out;
always@(*)
    begin
        case(sel)
            2'b00:d_out <= d_in[0];
            2'b01:d_out <= d_in[1];
            2'b10:d_out <= d_in[2];
            2'b11:d_out <= d_in[3];
        endcase
    end
endmodule

2.4数字编码器(用n位二进制码来表示m个特定信息,2的n次方>=m

用二进制代码表示有关的信号称为编码,所用电路称为数据编码器。

2.4.1 BCD编码器:用一组二进制数来表示一个给定的十进制数(也称10线—4线编码器)

//8421BCD编码器代码如下:

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

2.4.2 8线—3线编码器

其特点为任何时刻只允许输入一个有效信号,若出现两个或两个以上有效信号,电路就会中断。

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

2.4.3 8线—3线优先编码器

普通编码器的缺点是:在任何时刻只能有一个输入有效,若不是的话输出会出错,有一定局限性。

为了克服这种缺点,采用优先编码器,其是当多个输入端同时有信号时,电路只对其中优先级别最高的输入信号进行编码。

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

2.4.4 余3编码


十进制  8421BCD码  余3码
0     0000     0011
1     0001     0100
2     0010     0101
3     0011     0110
4     0100     0111
5     0101     1000
6     0110     1001
7     0111     1010
8     1000     1011
9     1001     1100


module code_yu3(d_in,d_out);
input [3:0]d_in;
output [3:0]d_out;
assign d_out=d_in+4'b0011;  //842`BCD码加4'b0011就是当前所表达十进制数所对应的余3码
endmodule

2.5数字译码器(功能是将n个输入码进行翻译,转换为2的n次方个输出信号)

译码器就是对编码器的反操作,这里就不多赘述了。

举例3线—8线译码器如下:

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

2.6数字校验器

        数字信息在传输和存储过程中,由于噪声和外界干扰因素会出错,可用奇偶校验器检查数据是否出错,但无法确定错误发生在哪。功能为检测数据中包含1的个数是奇数还是偶数。

module checker(din,odd,even);
parameter w=8;
input [w-1:0]din;
output odd,even;
assign odd=^din;   //偶校验,归约运算符的运用
assign even=!odd;  //奇校验,也可写为  assign even = ~(^din);
endmodule

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值