数电第五周周结_by_yc

基本要点:
组合逻辑电路的行为特点、经典组合逻辑电路的设计、PPA优化

  • 组合逻辑电路设计要点:
      ①敏感变量列表应包含所有会影响输出的控制量;
      ②条件语句的完全描述,当电路中的条件语句未被完全描述,将会导致生成某一状态下对输出结果的锁存;
       - 在所有分支之前,添加赋值语句;
       - 在所有分支中对变量进行赋值。
      ③阻塞赋值:“=”,非阻塞赋值的“延时性”将会导致电路输出错误。若使用\({always@(*)}\)将会导致out_a和out_na的结果相同,这是由于将前述变量同样加入了敏感列表。\({\Rightarrow}\)鼓励多多使用\({always@(*)}\)

  • 组合电路中应避免产生latch!
      ①锁存器:电平触发的存储单元,当电平信号无效时,输出信号随输入信号变化,就像通过了缓冲器;当电平有效时,输出信号被锁存。
      ②latch危害:在实际电路中latch容易产生毛刺,导致下一级电路可能出现错误状态;生成latch需要更多的资源;锁存器的出现会使得静态时序分析变得更加复杂。
      ③避免产生latch的方法:
        A.if-else或case语句,结构保持完整;
        B.不要将赋值信号放在赋值源头或者条件判断中;
        C.敏感信号列表建议使用\({always@(*)}\)

  • 多路选择器:

//4选1多路选择器
module Multiplexer(
	input a, b, c, d,
	input s0, s1,
	output reg y);
	
	always@(*)	begin
		if({s1,s0}==2'b00)	y=a;
		else if({s1,s0}==2'b01)	y=b;
		else if({s1,s0}==2'b10)	y=c;
		else if({s1,s0}==2'b11)	y=d;
		else	y=1'bx;//省略将会带来latch
	end
	
endmodule

  • 比较器:
//2位比较器
module Comparator(
	input in0, in1,
	output reg gt, eq, lt);
	
	always@(*)	begin
		gt=0;
		eq=0;
		lt=0;
		if(in0>in1)	gt=1;
		if(in0==in1)	eq=1;
		if(in0<in1) lt=1;
		end

endmodule
  • 编码器和译码器:
//8-3编码器
module encoder(
	input [7:0] in,
	output reg [2:0] encode_out,
	output reg valid);
	
	always@(*)	begin
		valid=1;
		case(in)
			8'b00000001: encode_out = 3'b000;
			8'b00000010: encode_out = 3'b001;
			8'b00000100: encode_out = 3'b010;
			8'b00001000: encode_out = 3'b011;
			8'b00010000: encode_out = 3'b100;
			8'b00100000: encode_out = 3'b101;
			8'b01000000: encode_out = 3'b110;
			8'b10000000: encode_out = 3'b111;
			default	  : valid=0;
		endcase
	end
	
endmodule
//3-8译码器
module decoder(
	input [2:0] in,
	output reg [7:0] out);
	
	always@(*)	begin
		case(in)
			3'b000: out=8'b00000001;
			3'b001: out=8'b00000010;
			3'b010: out=8'b00000100;
			3'b011: out=8'b00001000;
			3'b100: out=8'b00010000;
			3'b101: out=8'b00100000;
			3'b110: out=8'b01000000;
			3'b111: out=8'b10000000;
		endcase
	end
	
endmodule
//8-3_priority_encoder
module priority_encoder(
	input [7:0] din,
	input EI,
	output reg [2:0] dout,
	output reg GS, EO);
	
	always@(*)	begin
		if(EI) begin dout=3'b111; GS=1; EO=1; end
		else if(din[7]==0) begin dout=3'b000; GS=0; EO=1; end
		else if(din[6]==0) begin dout=3'b001; GS=0; EO=1; end
		else if(din[5]==0) begin dout=3'b010; GS=0; EO=1; end
		else if(din[4]==0) begin dout=3'b011; GS=0; EO=1; end
		else if(din[3]==0) begin dout=3'b100; GS=0; EO=1; end
		else if(din[2]==0) begin dout=3'b101; GS=0; EO=1; end
		else if(din[1]==0) begin dout=3'b110; GS=0; EO=1; end
		else if(din[0]==0) begin dout=3'b111; GS=0; EO=1; end
		else begin dout=3'b111; GS=1; EO=0; end
	end
endmodule
  • 七段数码管:
//七段数码管
module hex_7seg_LED(
	input [3:0] hex,
	input dp,
	output reg [7:0] sseg);
	
	always@(*)	begin
		case(hex)
			4'h0:	sseg=7'b0000001;
			4'h1: sseg=7'b1001111;
			4'h2: sseg=7'b0010010;
			4'h3: sseg=7'b0000110;
			4'h4: sseg=7'b1001100;
			4'h5: sseg=7'b0100100;
			4'h6: sseg=7'b0100000;
			4'h7: sseg=7'b0001111;
			4'h8: sseg=7'b0000000;
			4'h9: sseg=7'b0000100;
			4'ha: sseg=7'b0001000;
			4'hb: sseg=7'b1100000;
			4'hc: sseg=7'b0110001;
			4'hd: sseg=7'b1000010;
			4'he: sseg=7'b0110000;
			4'hf: sseg=7'b0111000;
		endcase
		sseg[7]=dp;
	end
	
endmodule
  • PPA优化问题:PPA优化

  • 上机过程中出现的问题:
      ①定义寄存器时注意不要写成数组哈哈哈;
      ②for循环时♻️不要把起始和终止条件写反;
      ③使用for循环时最好将多语句块用begin...end包起来,因为for语句不会根据缩进来判断for循环是否结束。