《计算机组成与CPU设计实验》1 组合逻辑(一)
本篇内容来源于中国大学mooc《计算机组成与CPU设计实验》 (江苏大学)中的课程视频、PPT等相关资料。
本篇内容为《计算机组成与CPU设计实验》——三态门和多路器
参考视频:
计算机组成与CPU设计实验_江苏大学_中国大学MOOC(慕课) (icourse163.org)
逻辑电路的类型
组合逻辑Combinational Logic
- 没有记忆
- 输出由当前输入值决定时序逻辑
Sequential Logic
- 有记忆
- 输出不仅由当前输入值决定,还和以前的状态有关。
持续赋值语句 Continuous Assignment
assign 语句
assign A = B;//等号左边的值始终跟随右边改变
例子:使用Verilog描述与非门

module nand(input wire a, // wire可以省略input wire b,output wire c
);
assign c = ~(a&b); //等号左边的值始终跟随右边改变
endmodule
多个assign语句并行执行
例子:使用Verilog描述下面电路

module circuit(input a, input b,output c,output c);assign c = ~(a&b);assign d = a^b ;
endmodule
位运算符 Bitwise Operators
- ~ 按位取反
- & 按位与
- | 按位或
- ^ 按位异或
举例:按位与

注意:逻辑运算符与位运算符的区别
逻辑运算符:
- && 逻辑与
- || 逻辑或
- ! 逻辑非
举例:逻辑与

持续赋值语句(assign)例子
三态门 Tri-state buffer
三态门是什么
三态门的输出端除了0和1两种状态外,还有第三种状态,称为高阻态(z)。在这种状态下,输出端相当于断开。也称三态缓冲器。
三态门电路的逻辑符号

三态门真值表

三态门使能端EN=1时,才有有效输出
使用Verilog描述三态门

module tribuffer(input Din, input En,output Dout,);assign Dout = En ? Din:1'bz;//z(或者Z)为高阻态
endmodule//? :为条件运算符
三态门应用
三态门的用途:输出到总线
普通逻辑门的输出不能连到一起,三态门通过使能端控制同一时刻只有一个输出

多路选择器 Multiplexer (Mux)
二选一多路选择器
2 选 1多路器的逻辑电路

2 选 1多路器的逻辑符号

2 选 1多路器真值表

使用Verilog描述2 选 1多路器
module mux2(input A,input B,input S,output Y);assign Y = S? B:A;
endmodule
四位加法器

module ADDER(input [3:0] a, input [3:0] b,input CI,output [3:0] S ,output CO);
//方法1:wire[4:0] ADD;assign ADD = a+b+CI;assign S = ADD[3:0];assign CO = ADD[4];//方法2:直接使用拼接运算符
assign {CO,S[3:0]} = a+b+CI;endmodule
拼接运算符
将若干个信号的某些位拼接起来,如:
{CO, S[3:0]}
拼接的每个部分必须有确定的位宽完整域选择可以省略,如:
{CO,S} //{CO, S[3:0]},省略S的位宽
常数必须显式指定位宽,例:
{1'b0,S}
复制拼接
{3{a}}//等价于{a, a, a}
{2{a,b}}//等价于 {{a,b}, {a,b}}//等价于 {a,b,a,b}
always过程语句
过程赋值 Procedural Assignment
过程块中的输出变量必须声明为reg,但并不意味着它是寄存器。
例子:使用always块描述下面电路

module circuit(input wire a,input wire b,output reg c ,output reg d);
//always(敏感列表(Sensitivity list))always(a or b)//或者always(*) 如果a或者b信号发生变化,输出的值c、d就会发生改变 beginassign c = ~(a&b);assign d = a^b;endendmodule
logic类型代替reg类型
推荐使用SystemVerilog新的logic类型
为什么建议使用logic类型
reg容易被误解为“寄存器”,大部分场合logic类型可取代wire类型和reg类型
module circuit(input wire a,input wire b,output logic c ,output logic d);always(a or b)beginassign c = ~(a&b);assign d = a^b;endendmodule
敏感列表不完整
组合逻辑的敏感列表应包含所有输入
问题:如果敏感列表不完整,会出现什么问题?
例子:与非门
与非门的输入a或者b变化,输出c也跟着变化

如果敏感列表里面没有b。
下面代码的逻辑功能是,
- 当a发生变化的时候,输出c更新,发生变化。
- 当b发生变化的时候,输出c保持上一次的值,不发生变化。
所以当只有 b发生变化时不会影响输出。代码的逻辑功能和与非门的逻辑功能不一致。
module circuit(input wire a, input wire b,output logic c ,);always(a)//敏感列表里面没有bbeginassign c = ~(a&b);endendmodule
避免敏感列表不完整
使用always(*)
module circuit(input wire a,input wire b,output logic c );always(*)beginassign c = ~(a&b);endendmodule
强烈推荐always_comb (systemVerilog)
module circuit(input wire a,input wire b,output logic c );always_combassign c = ~(a&b);
endmodule
分支语句
- if...else
- case
if...else
例子:2选1多路选择器

module mux2(input A,input B,input S,output Y);
// assign Y = S? B:A;always_combif(S==1)Y = B;elseY = A;
endmodule
可用于比较的运算符


case语句
例子:四选一多路选择器

module mux4(input In0,In1,In2,In3,input [1:0] Sel,output Out);always_combcase(Sel)2'b00: Out = In0;2'b01: Out = In1;2'b10: Out = In2;2'b11: Out = In3;default:Out = 1'bx;endcase
endmodule
//Verilog的逻辑值有高电平1、低电平0,高阻态z、不确定值x,四个逻辑值
//所以对于两位的Sel有2^4=16种逻辑值。
//对于其他不需要的逻辑值,需要使用default。否则会综合后的电路会出现latch,
//即,取到其他逻辑值,数据不发生变化来保存
使用if-else语句写4-1多路选择器
module mux4(input In0,In1,In2,In3,input [1:0] Sel,output Out);always_combif(Sel==00)Out = In0;else if(Sel==01)Out = In1;else if(Sel==10)Out = In2;else if(Sel==11)Out = In3;elseOut = 1'bx;
endmodule
if-else和case生成的多路选择器的区别
- if-else语句生成的电路是串行结构,case语句生成的是并行结构
- if-else语句生成的电路延迟大,case语句生成电路等延时
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
