《计算机组成与CPU设计实验》1 组合逻辑(一)

本篇内容来源于中国大学mooc《计算机组成与CPU设计实验》 (江苏大学)中的课程视频、PPT等相关资料。

本篇内容为《计算机组成与CPU设计实验》——三态门和多路器

参考视频:

计算机组成与CPU设计实验_江苏大学_中国大学MOOC(慕课) (icourse163.org)

逻辑电路的类型

组合逻辑Combinational Logic

  • 没有记忆
  • 输出由当前输入值决定时序逻辑

Sequential Logic

  • 有记忆
  • 输出不仅由当前输入值决定,还和以前的状态有关。

持续赋值语句 Continuous Assignment

assign 语句

assign  A = B;

//等号左边的值始终跟随右边改变

例子:使用Verilog描述与非门

《计算机组成与CPU设计实验》1 组合逻辑(一)_第1张图片

module nand(
	input  wire a,	//	wire可以省略
	input  wire b,
	output wire c
);
assign c = ~(a&b); //等号左边的值始终跟随右边改变
endmodule

 多个assign语句并行执行

 例子:使用Verilog描述下面电路

《计算机组成与CPU设计实验》1 组合逻辑(一)_第2张图片

module circuit(
	input   a,	
	input   b,
	output  c,
	output  c
	);
	assign c = ~(a&b);
	assign d = a^b ;
endmodule

 位运算符 Bitwise Operators

  • ~   按位取反
  • &  按位与
  • |   按位或
  •  ^ 按位异或

 举例:按位与

《计算机组成与CPU设计实验》1 组合逻辑(一)_第3张图片

 注意:逻辑运算符与位运算符的区别

逻辑运算符:

  • && 逻辑与
  • ||    逻辑或
  • !   逻辑非

 举例:逻辑与

a032db23ccac4cb7b4c8e93a0708546e.png

持续赋值语句(assign)例子 

三态门 Tri-state buffer

三态门是什么

        三态门的输出端除了0和1两种状态外,还有第三种状态,称为高阻态(z)。在这种状态下,输出端相当于断开。也称三态缓冲器。

三态门电路的逻辑符号

《计算机组成与CPU设计实验》1 组合逻辑(一)_第4张图片

 三态门真值表

《计算机组成与CPU设计实验》1 组合逻辑(一)_第5张图片

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

使用Verilog描述三态门

《计算机组成与CPU设计实验》1 组合逻辑(一)_第6张图片

module tribuffer(
	input   Din,	
	input   En,
	output  Dout,
	);
	assign Dout = En ? Din:1'bz;//z(或者Z)为高阻态
endmodule

//? :为条件运算符

三态门应用

         三态门的用途:输出到总线

        普通逻辑门的输出不能连到一起,三态门通过使能端控制同一时刻只有一个输出

《计算机组成与CPU设计实验》1 组合逻辑(一)_第7张图片

 多路选择器 Multiplexer (Mux)

二选一多路选择器

2 选 1多路器的逻辑电路 

《计算机组成与CPU设计实验》1 组合逻辑(一)_第8张图片

2 选 1多路器的逻辑符号

《计算机组成与CPU设计实验》1 组合逻辑(一)_第9张图片

2 选 1多路器真值表

《计算机组成与CPU设计实验》1 组合逻辑(一)_第10张图片

 使用Verilog描述2 选 1多路器

module mux2(
	input   A,
	input   B,
	input   S,
	output  Y
	);
	assign Y = S? B:A;
endmodule

四位加法器

《计算机组成与CPU设计实验》1 组合逻辑(一)_第11张图片

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块描述下面电路

《计算机组成与CPU设计实验》1 组合逻辑(一)_第12张图片

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就会发生改变 
    begin
       assign  c = ~(a&b);
       assign  d = a^b;
   end
 
endmodule

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)
    begin
       assign  c = ~(a&b);
       assign  d = a^b;
   end
 
endmodule

敏感列表不完整 

 组合逻辑的敏感列表应包含所有输入

问题:如果敏感列表不完整,会出现什么问题?

例子:与非门

与非门的输入a或者b变化,输出c也跟着变化

《计算机组成与CPU设计实验》1 组合逻辑(一)_第13张图片

如果敏感列表里面没有b。

下面代码的逻辑功能是,

  • 当a发生变化的时候,输出c更新,发生变化。
  •  当b发生变化的时候,输出c保持上一次的值,不发生变化。

所以当只有 b发生变化时不会影响输出。代码的逻辑功能和与非门的逻辑功能不一致。

module circuit(
	input  wire  a,	
	input  wire b,
	output  logic c ,
	);
 always(a)//敏感列表里面没有b
    begin
       assign  c = ~(a&b);
   end
 
endmodule

避免敏感列表不完整

使用always(*)

module circuit(
	input  wire  a,
	input  wire b,
	output  logic c 
	);
 always(*)
    begin
       assign  c = ~(a&b);
   end
 
endmodule

 强烈推荐always_comb    (systemVerilog)

module circuit(
	input  wire  a,
	input  wire b,
	output  logic c 
	);
 always_comb
       assign  c = ~(a&b);
endmodule

 分支语句

  • if...else
  • case

 if...else

例子:2选1多路选择器

《计算机组成与CPU设计实验》1 组合逻辑(一)_第14张图片

module mux2(
	input   A,
	input   B,
	input   S,
	output  Y
	);
//	assign Y = S? B:A;
    always_comb
      if(S==1)
            Y = B;
       else
            Y = A;
endmodule

 可用于比较的运算符

《计算机组成与CPU设计实验》1 组合逻辑(一)_第15张图片

《计算机组成与CPU设计实验》1 组合逻辑(一)_第16张图片

 case语句

例子:四选一多路选择器

《计算机组成与CPU设计实验》1 组合逻辑(一)_第17张图片

module mux4(
	input        In0,In1,In2,In3,
	input [1:0]  Sel,
	output  Out
	);
    always_comb
     case(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_comb
    if(Sel==00)
         Out = In0;
      else if(Sel==01)
         Out = In1;
      else if(Sel==10)
         Out = In2;
      else if(Sel==11)
         Out = In3;
       else
          Out = 1'bx;
endmodule

 if-else和case生成的多路选择器的区别

  •  if-else语句生成的电路是串行结构,case语句生成的是并行结构
  •  if-else语句生成的电路延迟大,case语句生成电路等延时

你可能感兴趣的:(Verilog,Verilog)