自动综合IC设计流程教程张建良shandy98@mails.tsinghua.edu.cn2005年春季一、自动综合流程概述下图是一个比较完整的自动综合IC设计流程:系统功能定义算法选择、优化和验证结构级设计自动综合,导出RTL网表和延时信息文件(sdf)前仿真RTL仿真自动布局布线DRC/LVS验证寄生参数提取,导出延时信息文件(sdf)后仿真验证通过?是是否功能正确?是否时序符合?否时序符合?否是Tapeout合并单元库版图,导出gdsII验证通过?是修正错误NCVerilog/modelsimDesignCompilerSiliconEnsembleVirtuosoicfbAssura/Diva/Dracula/Calibre图中用不同颜色标出了设计的各个阶段采用的工具软件,主要有:zNCVerilog/Modelsim:NCVerilog是Cadence公司的chip级仿真软件,Modelsim是MentorGraphic公司推出的工业界应用广泛的仿真软件,都可以进行verilog/VHDL的仿真zDesignCompiler:synopsys公司的综合软件zSiliconEnsemble:cadence公司的自动布局布线工具zVirtuoso:cadence公司的版图编辑软件zIcfb:cadence公司的芯片设计集成环境zAssura/Diva/Dracula/Calibre:Assura/Diva/Dracula是cadence公司的DRC/LVS版图验证和寄生参数提取软件,Calibre是MentorGraphic公司的DRC/LVS版图验证和寄生参数提取软件如何获取帮助:1.synopsys的帮助文档可以用命令:sold打开2.cadence的帮助文档可以用命令:cdsdoc打开,由于路径设置的问题,可能需要从菜单启动netscape浏览器3.一般图形界面中都有“帮助”按钮,可以获得帮助信息4.SMTHBBSÆIM/METECH5.google二、一个加法器的设计实例下面以一个32位无符号整数乘法器的设计为例,介绍自动综合的设计流程。所使用的库为SMIC0.18umCMOS标准单元Logic工艺库。2.1系统功能定义(SPEC)设计的第一步是确定用户需求,定义系统功能。本设计中,要求:1.设计一个32位无符号整数乘法器,采用SMIC0.18umCMOS标准单元Logic工艺库2.输入端口定义在后面给出3.速度尽可能快,面积不限,功耗不限4.工作方式在后面给出MultipliercsrwaddrdataclkresetFinish图2.1系统端口定义表2.1系统端口定义端口方向说明csI片选信号,低电平有效。信号有效时才可以对乘法器执行读写操作rwI读写信号,低电平为读操作,高电平为写操作addrI4位地址总线,用于选择内部寄存器clkI时钟输入resetI复位信号,低电平有效dataI/O32位数据总线finishO完成指示信号,低电平有效乘法器内部包含多个寄存器用于存储当前状态、操作数、运算结果等,列表说明如下:表2.2系统寄存器定义寄存器地址允许操作说明M0,M10x1,0x2R/W乘数和被乘数,均为32位P00x3R乘积低32位寄存器P10x4R乘积高32位寄存器STATUS0x5R/W32位状态寄存器,详细定义见后面所有寄存器在reset为低电平时清零。STATUS寄存器定义:b31-b1b0RUN未定义,读出为0写入1表示开始运算,读出0表示运算完成工作流程:1.reset=02.reset=1,cs=0,rw=1,addr=0x1,data=M03.reset=1,cs=0,rw=1,addr=0x2,data=M14.reset=1,cs=0,rw=1,addr=0x5,data=0x15.reset=1,cs=0,rw=0,addr=0x5直到读到data[0]=0为止或等待Finish信号为低电平6.reset=1,cs=0,rw=0,addr=0x3得到data为乘积的低32位7.reset=1,cs=0,rw=0,addr=0x4得到data为乘积的高32位8.返回2继续做下一次运算注意:本设计中认为输入输出信号均与时钟信号同步,在实际的芯片设计中经常遇到片内时钟与片外时钟不同步(例如使用PLL等)的情况,这时候需要考虑输入信号的亚稳态问题。2.2算法选择、优化和验证确定了系统功能定义后需要选择合适的算法实现,由于本设计对于面积、功耗等没有特别的要求,且无符号整数乘法运算可以直接综合得到,本设计中不采用特殊设计的乘法算法,由综合器自动生成,可省略这一步的工作。2.3结构级设计与前仿真确定了算法之后,通过对算法的细致分析,可以划分系统结构,确定实现方案。通常把系统划分为控制通路和数据通路两大部分,本设计中也采用这样的划分模式,把控制逻辑划分为控制通路,乘法运算作为数据通路。图2.2系统划分基于系统划分可以划出系统的详细框图(略),并采用Verilog描述://--------------------------------------------------------------------------------------//mul32:32x32intergermultiplier//port:dir:function//cs:I:chipselect,activelow//clk:I:clock//reset:I:reset,activelow//rw:I:read(0)/write(1)//addr:I:addressbus//datain:I:datain//dataout:O:dataout//finish:O:finishindicatormodulemul32(cs,clk,reset,rw,addr,datain,dataout,finish);inputcs,clk,reset,rw;input[3:0]addr;input[31:0]datain;output[31:0]dataout;outputfinish;wire[31:0]M0;wire[31:0]M1;wire[63:0]P;datapathudatapath(M0,M1,P);controlucontrol(cs,clk,reset,rw,addr,datain,dataout,finish,M0,M1,P);endmodule//--------------------------------------------------------------------------------------//datapath//port:dir:function//M0:I:multiplicand//M1:I:multiplier//P:O:productormoduledatapath(M0,M1,P);input[31:0]M0;input[31:0]M1;output[63:0]P;assignP=M0*M1;endmodule//--------------------------------------------------------------------------------------//controller//port:dir:function//cs:I:chipselect,activelow//clk:I:clock//reset:I:reset,activelow//rw:I:read(0)/write(1)//addr:I:addressbus//datain:I:datain//dataout:O:dataout//finish:O:finishindicator//M0:I:multiplicand//M1:I:multiplier//P:O:productormodulecontrol(cs,clk,reset,rw,addr,datain,dataout,finish,M0,M1,P);inputcs,clk,reset,rw;input[3:0]addr;input[31:0]datain;output[31:0]dataout;outputfinish;output[31:0]M0;output[31:0]M1;input[63:0]P;reg[31:0]M0;reg[31:0]M1;reg[31:0]P0;reg[31:0]P1;regfinish;reg[31:0]dataout;//always@(csorrworaddrorP0orP1orfinish)always@(posedgeclk)beginif(~cs&&~rw)begincase(addr)4'h3:dataout=P0;4'h4:dataout=P1;4'h5:dataout=finish;default:dataout=0;endcaseendelsebegindataout=0;endendalways@(posedgeclkornegedgereset)beginif(~reset)beginM0=0;M1=0;{P1,P0}=0;finish=1;endelsebeginif(~finish){P1,P0}=P;finish=1;if(~cs&&rw)begincase(addr)4'h1:M0=datain;4'h2:M1=datain;4'h5:finish=datain[0];endcaseendendendendmodule//--------------------------------------------------------------------------------------需要注意的是,对于设计中使用的双向端口可以先按照单向端口设计,再通过外层加一个模块把单向端口转换成双向端口://--------------------------------------------------------------------------------------`includemul32.v`includecontrol.v`includedatapath.v//top:topmodulewithpads//port:dir:function//cs:I:chipselect,activelow//clk:I:clock//reset:I:reset,activelow//rw:I:read(0)/write(1)//addr:I:addressbus//data:I/O:databus//finish:O:finishindicatormoduletop(cs,clk,reset,rw,addr,data,finish);inputcs,clk,reset,rw;input[3:0]addr;inout[31:0]data;outputfinish;wirecs_core,clk_core,reset_core,rw_core;wire[3:0]addr_core;wire[31:0]datain_core,dataout_core;wirefinish_core;`ifdefDONT_USE_PAD//don'tusepad,payattentiontotheinoutbusassigncs_core=cs;assignclk_core=clk;assignreset_core=reset;assignrw_core=rw;assignaddr_core=addr;assignfinish_core=finish;assigndata=(!rw)?dataout_core:32'hzzzzzzzz;assigndatain_core=data;`else//wecanusePADsfromiolibPIUPAD0(.PAD(cs),.C(cs_core));PIUPAD1(.PAD(clk),.C(clk_