上回书说到数字系统中的一种系统——组合逻辑电路(输入和输出之间没有反馈延迟通路;没有含有记忆功能的元件)。现在先把上篇文章的遗留问题——全加器和半加器的仿真。
首先是半加器的仿真,它能产生本位和(Sum)以及向高位的进位(Carry),但不考虑低位来的进位。半加器由一个异或门和一个与门构成。异或门用于产生本位和,与门用于产生向高位的进位。所以说在Modelsim的逻辑就能写成sum=a^b;carry=a & b;
来看看全部的代码:
主要的程序文件half_adder.v:
module half_adder(
input wire a,b,
output wire sum,carry
);
assign sum = a ^ b; //本位
assign carry = a & b; //借位
endmodule
其次是测试文件half_adder_tb.v:
`timescale 1ns/1ns
module half_adder_tb;
reg a,b;
wire sum,carry;
half_adder U(.a(a),.b(b),.sum(sum),.carry(carry));
initial begin
#20 a=0;b=0;
#20 a=0;b=1;
#20 a=1;b=0;
#20 a=1;b=1;
#20 $stop;
end
endmodule
看看仿真图,大家可以对比真值表记忆理解。
半加器的真值表:
输入 A | 输入 B | 和(Sum) | 借位(Carry) |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
接下来是全加器,全加器通常由两个半加器和一个或门构成。其中一个半加器用于计算两个加数的和,另一个半加器用于计算这个和与低位进位的和,或门用于产生向高位的进位。所以我们要有一个半加器ha1计算a和b的半加和s1与进位c1,有一个半加器计算s1和cin的半加和sum与进位c2。最终的进位输出count是通过将c1和c2进行或运算得到。
来看看全部的代码:
主要的程序文件adder.v:
module adder(
input wire a,b,cin,
output sum,cout
);
wire s1, c1, c2;
half_adder ha1(
.a(a),
.b(b),
.sum(s1),
.carry(c1)
);
half_adder ha2(
.a(s1),
.b(cin),
.sum(sum),
.carry(c2)
);
assign cout = c1 | c2;
endmodule
其次是测试文件half_adder_tb.v:
`timescale 1ns/1ns
module adder_tb;
reg a,b,cin;
wire sum,cout;
adder U(.a(a),.b(b),.cin(cin),.sum(sum),.cout(cout));
initial begin
#20 a = 0; b = 0; cin = 0;
#20 a = 0; b = 0; cin = 1;
#20 a = 0; b = 1; cin = 0;
#20 a = 0; b = 1; cin = 1;
#20 a = 1; b = 0; cin = 0;
#20 a = 1; b = 0; cin = 1;
#20 a = 1; b = 1; cin = 0;
#20 a = 1; b = 1; cin = 1;
#20 $stop;
end
endmodule
大家这里是不是会有一个疑问:半加器的模块怎么去调用?其实并不复杂,只要将全加器和半加器放在同一个工程下面就行了。
看看仿真图,大家可以对比真值表记忆理解。
全加器的真值表:
输入 A | 输入 B | 低位进位 Cin | 和(Sum) | 进位 Cout |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
好了,昨天疑问解决的差不多了。进入今天的主题——组合逻辑电路的其他内容。
首先是组合逻辑电路中的竞争冒险。大家再看组合逻辑电路的时候,可以看到正常的组合逻辑电路有很多的支路,信号会经过不同逻辑门,如果考虑延时时间的话,因为信号通过不同路径到达同一逻辑门的时间存在差异,这就是产生竞争冒险的原因。由于输入信号的变化导致多个输入信号通过不同的路径和不同的延迟时间到达逻辑门时,就可能出现竞争。如果这种竞争导致输出在短时间内出现不符合预期的尖峰脉冲,就产生了冒险。那如何消除减少竞争冒险呢?1、发现并消去互补相乘项。2、增加乘积项以避免互补项相加。3、输出端并联电容器,起到滤波的作用,电容对窄脉冲起到平波的作用,使得输出端不会出现逻辑错误。
接着,来看看组合逻辑电路的另一种应用——编码器和译码器。编码器,顾名思义,我们把有编码功能的器件称为编码器。它有n位二进制码输出,与2^n个输出。而译码是编码的过程,将具有特定含义二进制码转换成对应的输出信号。把具有译码功能的器件叫做译码器。输入与输出端口数和编码器相反。它的逻辑表达式:(Yi)'=(mi)'。还有一种应用——数据选择器(MUX),通过选择,把多路数据中的某一路数据传送到公共数据线上,类似于多个输入的单刀多掷开关。它的表达式是Y=∑mi*Di。至于各器件的详细使能引脚、复位引脚、置位引脚这里就不做过多的说明了。
来看看译码器和数据选择器的Multisim的仿真。
译码器的仿真——晶体管的显示,
在使能端正常的情况下,我们将按钮拨到0011的位置的时候,数码管上显示的是3。
数据选择器的仿真——八选一数据选择器。
我们选择的数据选择的是CBA:100,是第四位。我们输出电平与D4有关。当它置高电平是,Y引脚上面的灯亮。反之,输出低电平,~w引脚上的灯亮。
好了,至此数字电子技术中的组合逻辑电路就差不多总结完了。明天,谈谈时序逻辑电路。
预知后事如何,且听下回分解。OVO.........