数字 IC 总结

发布时间 2023-08-28 15:44:18作者: TTBond

数字 IC 知识总结

芯片衡量指标(PPA)

  • Performance(性能)
  • Power(功耗)
  • Area(面积)

吞吐率

  • 每秒传递的 bit 位

数字 IC 设计流程

前端(逻辑设计)

  • 需求分析:客户向fabless提出设计要求,fabless将其翻译为对芯片产品的技术需求。

  • 算法设计:使用高级编程语言如C++设计和优化芯片钟所使用的算法;使用建模仿真工具如MATLAB进行浮点和定点的仿真,进而对算法进行评估和优化。

  • 功能架构设计:根据分析的功能需求以及算法分析的结果,设计芯片架构。此外,架构师将系统功能进行分解和细化,形成SPEC规范,将设计参数化。
    其中,包括处理器架构的选择(ARM、RISC-V),总线接口的选择(APB、AHB、AXI),软硬件功能的划分以及性能参数(引脚选择、电压频率、工艺选择、功耗和温度范围)。
    在这一阶段,可以使用SystemC对芯片构架进行模拟和分析。

  • RTL设计(代码输入):使用Verilog HDL、VHDL等硬件描述语言将模块功能以代码来实现。

  • 功能仿真验证(前仿):对RTL级的代码进行验证,以验证设计功能的正确性是否满足SPEC中的要求。

  • 逻辑综合:基于特定的工艺库,设定电路的面积、时序等目标参数的约束条件,将设计的RTL级代码映射为门级网表netlist。逻辑综合需要基于特定的综合库,在不同的库中,门电路的基本标准单元(standard cell)的面积、时序参数是不一样的。

  • 门级验证(后仿):对综合后的门级网表进行验证,这一阶段通常会使用仿真、静态时序分析和形式验证等工具。

  • 静态时序分析(STA):在时序上对电路进行验证,检查电路是否存在建立时间(setup time)和保持时间(hold time)的违例。

  • 形式验证(Formality):从功能上对综合后的网表进行验证,将综合后的网表与验证后的RTL设计对比,检查其是否在功能上存在等价性,保证逻辑综合过程中没有改变RTL描述的电路功能。
    后端(物理设计)

后端设计

  • 可测性设计(DFT):在设计适当增加一些专门用于测试的电路,提高电路的可控制性和可观察性,从而降低电路的测试难度和复杂性,提高电路的测试效率,降低测试成本。

  • 布局规划(Floorplanning):放置芯片的宏单元模块,在总体上确定各种功能电路的摆放位置,如IP模块、RAM、I/O引脚等。其会影响芯片的最终面积。

  • 时钟树综合CTS(Clock Tree Synthesis):芯片中的时钟网络要驱动电路中所有的时序单元,所以时钟源端门单元带载很多,其负载延时很大并且不平衡,需要插入缓冲器减小负载和平衡延时。时钟网络及其上的缓冲器共同构成了时钟树。一般要反复几次才能做出一个比较理想的时钟树。

  • 布线(Place & Route):布线是指在满足工艺规则和布线层数限制、线宽、线间距限制和各线网电性能约束的条件下,根据电路的连接关系将各单元和I/O Pad用互连线连接起来,这些是在时序驱动(Timing driven)的条件下进行的,保证关键时序路径上的连线长度能够最小。

  • 寄生参数提取:由于导线本身存在的电阻,相邻导线之间的互感、耦合电容在芯片内部会产生信号噪声、串扰和反射。提取寄生参数进行再次分析验证,分析信号完整性问题。

  • 物理版图验证:对布线完成的版图进行功能和时序上的验证。

    • LVS(Layout Vs Schematic):与电路图一致性验证,版图和逻辑综合后的门级电路图对比验证。
    • DRC(Design Rule Checking):设计规则检查,检查连线间距,连线宽度。
  • ERC:电气规则检查,检查短路开路。
    实际的后端流程还包括电路功耗分析,以及随着制造工艺不断进步产生的DFM(可制造性问题)。

  • 流片(Tape out):在所有检查和验证都正确无误的情况下把最后的物理版图以GDS II的文件格式交给Foundry,在晶圆硅片上做出实际的电路,再进行封装和测试,就得到了可以使用的芯片。

数字 IC 各流程对应的各公司 EDA

流程 Synopsys Cadence Mentor
RTL 代码仿真 VCS、Verdi(收购) NC-Verilog、Verilog-XL Modelsim
综合 Design complier Genus Leonardo
STA (静态时序分析) Prime Time Tempus SST Velocity
Formality(形式验证) Formality LEC、FormalCheck FormalPro
DFT (可测实性设计) TestMax modus BSDArchit
PnR (布局布线--硬宏) ICC or ICC2 Innovus(新) 、 Encounter(旧)
CTS(时钟树综合) Clock Tree Compiler CT-Gen
DRC(设计规则检查) LVS (与电路图一致性验证) Hercules Dracula calibre
GDSII 文件

Cadence的优势在于模拟设计和数字后端。

Synopsys的优势在于数字前端、数字后端和PT signoff。

Mentor的优势是Calibre signoff和DFT。

任务和函数的区别

异步复位 同步释放

所谓异步复位同步释放(Synchronized Asynchronous Reset),就是在复位信号到来的时候不受时钟信号的同步,而是在复位信号释放的时候和时钟信号保持同步

电路目的:防止复位信号撤除时产生亚稳态事件。
异步复位:显而易见,reset_n异步复位后,rst_n将拉低,即实现异步复位。
同步释放:这个是关键,看如何实现同步释放,即当复位信号reset_n撤除时,由于双缓冲电路(双寄存器)的作用,rst_n复位信号不会随着reset_n的撤除而撤除。

异步复位同步释放的原理图和代码如下:

//Synchronized Asynchronous Reset
//异步复位、同步释放:只适用于没有PLL的系统复位信号的设置
module sync_async_reset(clock,reset_n,rst_n);
input clock, reset_n;
output rst_n;
 
reg rst_nr1, rst_nr2;
 
always @(posedge clock or negedge reset_n) begin
    if(!reset_n) begin
		rst_nr1 <= 1'b0;
        rst_nr2 <= 1'b0;		//异步复位
    end
    else begin
		rst_nr1 <= 1'b1;
		rst_nr2 <= rst_nr1;		//同步释放
	end
end

assign rst_n = rst_nr2;			//新的系统复位信号rst_n
//信号rst_n作为新的系统复位信号,后续可以用来直接“异步复位”
endmodule							// sync_async_reset

⚠️:既解决了同步复位的资源消耗问题,又解决了异步复位的亚稳态问题,其根本思想是异步信号同步化

跨时钟域(CDC: Clock Domain Crossing)

门控电路

门控时钟是低功耗技术的一种常规方法

![image-20230716104825457](/Users/tanglong/Library/Application Support/typora-user-images/image-20230716104825457.png)

二进制转格雷码

将二进制数右移移位,再异或上二进制数本身。

assign grey_code = data ^ (data >> 1) //二进制与二进制右移一位的二进制异或

计数器

加 flag 标志位

reg [2:0] cnt ;
reg  cnt_flag ;
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		cnt <= 'd0;
		cnt_flag <= 'd0 ;
	end
	else if (cnt == 3'd6) begin
		cnt <= 'd0 ;
		cnt_flag <= 'b1 ;
	end
	else begin
		cnt <= cnt + 'd1 ;
		cnt_flag <= 'd0 ;
	end
end

不加 flag 标志位

reg [2:0] cnt ;
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		cnt <= 'd0;
	else if (cnt == 'd6)
		cnt <= 'd0 ;
	else 
		cnt <= cnt + 'd1 ;
end

检测边沿

reg [1:0] b;
always@(posedge clk or negedge rst_n)
  if(!rst_n)
		b<=0;
	else
		b<={b[0],a};

assign  rise=(b===2'b01);  //上升沿
assign  down=(b===2'b10);	 //下降沿

序列检测

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,

  output reg match
);

reg [7:0]    seq    ;
always@(posedge clk or negedge rst_n)  begin
	if(!rst_n)    begin
		seq <= 0 ;
		match <= 0 ;
	end
	else begin
    seq <= {seq[7:0],a};   //重点是这个
	end
end
  
always@(posedge clk )    begin
	if(seq == 8'b01110001)    
		match <= 1 ;
	else
		match <= 0 ;
end
endmodule

二段式状态机

//*************code***********//

parameter S0 = 5'b00001 ;
parameter S1 = 5'b10000 ;
parameter S2 = 5'b01000 ;
parameter S3 = 5'b00100 ;
parameter S4 = 5'b00010 ;

reg [4:0] Cur_state ;
reg [4:0] Nxt_state ;

//第一段式
always@(posedge clk or negedge rst)  begin
	if(!rst)
		Cur_state <= S0 ;
	else
		Cur_state <= Nxt_state ;
end

//第二段式
always@(*) begin
	if(!rst) begin
		flag = 0;
		Nxt_state = S0 ;
	end
	else	
		case(Cur_state)
		S0:if(data == 0) begin
			flag = 0;
			Nxt_state = S0 ;
		end 
		else begin
			flag = 0;
			Nxt_state = S1 ;
		end

		S1:if(data == 0) begin
			flag = 0;
			Nxt_state = S1 ;
		end 
		else begin
			flag = 0;
			Nxt_state = S2 ;
		end

		S2:if(data == 0) begin
			flag = 0;
			Nxt_state = S2 ;
		end 
		else begin
			flag = 0;
			Nxt_state = S3 ;
		end

		S3:if(data == 0) begin
			flag = 0;
			Nxt_state = S3 ;
		end 
		else begin
			flag = 0;
			Nxt_state = S4 ;
		end

		S4:if(data == 0) begin
			flag = 1;
			Nxt_state = S0 ;
		end 
		else begin
			flag = 1;
			Nxt_state = S1 ;
		end
		default: Nxt_state = S0 ;
		endcase
end
//*************code***********//

分频

1、奇数 50%占空比。对下降沿和上升沿都计数

//*************code***********//
parameter N = 7 ;
reg [2:0] cnt;
reg clk7;
always@(posedge clk or negedge clk or negedge rst)
	if(!rst)
		cnt <= 3'b0;
	else if(cnt == N-1)
		cnt <= 'b0;
	else
		cnt <= cnt + 1'b1;
     
always@(posedge clk or negedge clk or negedge rst)
	if(!rst)
		clk7 <= 1'b0;
	else if(cnt == N-1)
		clk7 <= ~clk7;
    
assign clk_out7 =clk7;

最大公约数 (GCD)

1、辗转相除法

⚠️:求最大公约数:辗转相除法(35:14)-->(21:14)-->(7:14)-->(7:7)

if(A_r > B_r) begin
	A_r <= A_r - B_r;
	B_r <= B_r;
end
else if(A_r < B_r) begin  //A_r < B_r
	B_r <= B_r - A_r;
	A_r <= A_r;
else 
  GCD <= A_r ;
end

最小公倍数

⚠️:最小公倍数=A*B / 最大公约数

模逆

扩展欧几里得(Extended Euclidean algorithm) 又称辗转相除法

扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数)

设exgcd(a,n)为扩展欧几里得算法的函数,则可得到ax+ny=g,g是a,n的最大公因数。

ax+by=gcd(a,b) 贝祖等式

当gcd(a,b) = 1 , 模逆才存在

//运算原理
1、实例 两个贝祖等式
	a*x1 + b*y1 = u
	a*x2 + b*y2 = v
2、{x1, y1, x2, y2} = 4'b1001;
3 判断 模数 b 是否为 0 进入死循环
	a%b = a - [a/b]*b
	x1 = x2;
	x2 = x1 - [a/b]*y2;
	y1 = y2;
	y2 = y1 - [a/b]*y2;
  a <= b ;
  b <= a%b ; 
  
4、b == 0 
	输出gcd(a,b) = a, x1 为 a 的模逆
模逆流程图

⚠️原理:a mod b = a - [a/b]*b;a<-b ; b <- a%b;

乘法器

流水线型
integer i ;
reg [7:0] temp[3:0];
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		for(i=0;i<4;i=i+1)
			temp[i] = 0;
	end
	else begin
		temp[0] <= b[0] ? {{4{1'b0}},a} : 8'd0 ;
		temp[1] <= b[1] ? {{3{1'b0}},a,{1{1'b0}}} : 8'd0 ;
		temp[2] <= b[2] ? {{2{1'b0}},a,{2{1'b0}}} : 8'd0 ;
		temp[3] <= b[3] ? {{1{1'b0}},a,{3{1'b0}}} : 8'd0 ;
	end
end

always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		c <= 0;
	else
		c <= {temp[0] + temp[1] + temp[2] + temp[3]};
end
组合逻辑型
wire [23:0] temp[7:0];

assign		temp[0] = (b[0])? {{8{1'b0}},a,{8{1'b0}}}:24'd0;
assign  	temp[1] = (b[1])? {{7{1'b0}},a,{9{1'b0}}}:24'd0;
assign		temp[2] = (b[2])? {{6{1'b0}},a,{10{1'b0}}}:24'd0;
assign		temp[3] = (b[3])? {{5{1'b0}},a,{11{1'b0}}}:24'd0;
assign		temp[4] = (b[4])? {{4{1'b0}},a,{12{1'b0}}}:24'd0;
assign		temp[5] = (b[5])? {{3{1'b0}},a,{13{1'b0}}}:24'd0;
assign		temp[6] = (b[6])? {{2{1'b0}},a,{14{1'b0}}}:24'd0;
assign		temp[7] = (b[7])? {{1{1'b0}},a,{15{1'b0}}}:24'd0;

assign Data_out_reg = temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];

乘法器

max min

always@() begin
  else if(cnt == 'd0 && InEN)
    max_reg <= r;
  else if(cnt == 'd1) begin
    if(InData >= max_reg) begin
      max_reg <= InData ;
      min_reg <= max_reg ;
    end
    else begin
      min_reg <= InData ;
      max_reg <= max_reg ;
    end
  end
  else begin
      max_reg <= max_reg ;
      min_reg <= min_reg ;
  end
end
**************************
always@() begin
  else if(cnt == 'd2) begin
    if(InData >= max_reg)
      max <= InData ;
    else if(InData <= min_reg)
      min <= InData ;
    else begin
      max <= max_reg ;
      min <= min_reg ;
    end
  end
end