1、auto compile自动综合IC设计流程教程张建良 shandy982005年春季 一、自动综合流程概述下图是一个比较完整的自动综合IC设计流程:图中用不同颜色标出了设计的各个阶段采用的工具软件,主要有: NC Verilog/Modelsim : NC Verilog是Cadence公司的chip级仿真软件,Modelsim是Mentor Graphic公司推出的工业界应用广泛的仿真软件,都可以进行verilog/VHDL的仿真 Design Compiler : synopsys公司的综合软件 Silicon Ensemble : cadence公司的自动布局布线工具 Virtuoso
2、 : cadence公司的版图编辑软件 Icfb : cadence公司的芯片设计集成环境 Assura/Diva/Dracula/Calibre :Assura/Diva/Dracula是cadence公司的DRC/LVS版图验证和寄生参数提取软件,Calibre是Mentor Graphic公司的DRC/LVS版图验证和寄生参数提取软件如何获取帮助:1synopsys的帮助文档可以用命令:sold 打开2cadence的帮助文档可以用命令:cdsdoc 打开,由于路径设置的问题,可能需要从菜单启动netscape浏览器3一般图形界面中都有“帮助”按钮,可以获得帮助信息4SMTH BBS I
3、M/METECH5google二、一个加法器的设计实例下面以一个32位无符号整数乘法器的设计为例,介绍自动综合的设计流程。所使用的库为SMIC 0.18um CMOS标准单元Logic工艺库。2.1 系统功能定义(SPEC) 设计的第一步是确定用户需求,定义系统功能。本设计中,要求:1 设计一个32位无符号整数乘法器,采用SMIC 0.18um CMOS标准单元Logic工艺库2 输入端口定义在后面给出3 速度尽可能快,面积不限,功耗不限4 工作方式在后面给出图2.1 系统端口定义表2.1 系统端口定义端口方向说明csI片选信号,低电平有效。信号有效时才可以对乘法器执行读写操作rwI读写信号,
4、低电平为读操作,高电平为写操作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表示开始运算,读
5、出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 直到读到data0 = 0为止 或 等待Finish信号为低电平6 reset = 1, cs = 0, rw = 0, addr = 0x3 得到data为乘积的低32
6、位7 reset = 1, cs = 0, rw = 0, addr = 0x4 得到data为乘积的高32位8 返回2继续做下一次运算注意:本设计中认为输入输出信号均与时钟信号同步,在实际的芯片设计中经常遇到片内时钟与片外时钟不同步(例如使用PLL等)的情况,这时候需要考虑输入信号的亚稳态问题。2.2 算法选择、优化和验证 确定了系统功能定义后需要选择合适的算法实现,由于本设计对于面积、功耗等没有特别的要求,且无符号整数乘法运算可以直接综合得到,本设计中不采用特殊设计的乘法算法,由综合器自动生成,可省略这一步的工作。2.3 结构级设计与前仿真 确定了算法之后,通过对算法的细致分析,可以划分系
7、统结构,确定实现方案。通常把系统划分为控制通路和数据通路两大部分,本设计中也采用这样的划分模式,把控制逻辑划分为控制通路,乘法运算作为数据通路。图2.2 系统划分基于系统划分可以划出系统的详细框图(略),并采用Verilog描述:/-/ mul32 : 32 x 32 interger multiplier/ port: dir : function/ cs : I : chip select, active low/ clk : I : clock/ reset : I : reset, active low/ rw : I : read(0) /write(1)/ addr: I : ad
8、dress bus/ datain: I : data in/ dataout:O : dataout/ finish: O : finish indicatormodule mul32( cs, clk, reset, rw, addr, datain, dataout, finish); input cs, clk, reset, rw; input 3:0 addr; input 31:0 datain; output 31:0 dataout; output finish; wire 31:0 M0; wire 31:0 M1; wire 63:0 P; datapath udatap
9、ath(M0, M1, P); control ucontrol(cs, clk, reset, rw, addr, datain, dataout, finish, M0, M1, P); endmodule/-/ datapath/ port: dir : function/ M0 : I : multiplicand/ M1 : I : multiplier/ P : O : productormodule datapath( M0, M1, P); input 31:0 M0; input 31:0 M1; output 63:0 P; assign P = M0 * M1; endm
10、odule/-/ controller/ port: dir : function/ cs : I : chip select, active low/ clk : I : clock/ reset : I : reset, active low/ rw : I : read(0) /write(1)/ addr: I : address bus/ datain: I : data in/ dataout:O : dataout/ finish: O : finish indicator/ M0 : I : multiplicand/ M1 : I : multiplier/ P : O :
11、productormodule control( cs, clk, reset, rw, addr, datain, dataout, finish, M0, M1, P); input cs, clk, reset, rw; input 3:0 addr; input 31:0 datain; output 31:0 dataout; output finish; 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; reg finish; reg 3
12、1:0 dataout; / always (cs or rw or addr or P0 or P1 or finish) always (posedge clk) begin if(cs & rw) begin case(addr) 4h3: dataout = P0; 4h4: dataout = P1; 4h5: dataout = finish; default: dataout = 0; endcase end else begin dataout = 0; end end always (posedge clk or negedge reset) begin if(reset)
13、begin M0 = 0; M1 = 0; P1, P0 = 0; finish = 1; end else begin if(finish) P1, P0 = P; finish = 1; if(cs & rw) begin case(addr) 4h1: M0 = datain; 4h2: M1 = datain; 4h5: finish = datain0; endcase end end end endmodule/- 需要注意的是,对于设计中使用的双向端口可以先按照单向端口设计,再通过外层加一个模块把单向端口转换成双向端口:/-include mul32.vinclude contr
14、ol.vinclude datapath.v/ top : top module with pads/ port: dir : function/ cs : I : chip select, active low/ clk : I : clock/ reset : I : reset, active low/ rw : I : read(0) /write(1)/ addr: I : address bus/ data: I/O : data bus/ finish: O : finish indicatormodule top( cs, clk, reset, rw, addr, data,
15、 finish); input cs, clk, reset, rw; input 3:0 addr; inout 31:0 data; output finish; wire cs_core, clk_core, reset_core, rw_core; wire 3:0 addr_core; wire 31:0 datain_core, dataout_core; wire finish_core; ifdef DONT_USE_PAD /dont use pad, pay attention to the inout bus assign cs_core = cs; assign clk
16、_core = clk; assign reset_core = reset; assign rw_core = rw; assign addr_core = addr; assign finish_core = finish; assign data = (!rw) ? dataout_core : 32hzzzzzzzz; assign datain_core = data; else /we can use PADs from io lib PI UPAD0( .PAD(cs), .C(cs_core) ); PI UPAD1( .PAD(clk), .C(clk_core) ); PI
17、 UPAD2( .PAD(reset), .C(reset_core) ); PI UPAD3( .PAD(rw), .C(rw_core) ); PI UPAD4( .PAD(addr3), .C(addr_core3) ); PI UPAD5( .PAD(addr2), .C(addr_core2) ); PI UPAD6( .PAD(addr1), .C(addr_core1) ); PI UPAD7( .PAD(addr0), .C(addr_core0) ); PO8 UPAD8( .PAD(finish), .I(finish_core) ); PB8 UPAD9( .PAD(da
18、ta31), .OEN(rw_core), .I(dataout_core31), .C(datain_core31) ); PB8 UPAD10( .PAD(data30), .OEN(rw_core), .I(dataout_core30), .C(datain_core30) ); PB8 UPAD11( .PAD(data29), .OEN(rw_core), .I(dataout_core29), .C(datain_core29) ); PB8 UPAD12( .PAD(data28), .OEN(rw_core), .I(dataout_core28), .C(datain_co
19、re28) ); PB8 UPAD13( .PAD(data27), .OEN(rw_core), .I(dataout_core27), .C(datain_core27) ); PB8 UPAD14( .PAD(data26), .OEN(rw_core), .I(dataout_core26), .C(datain_core26) ); PB8 UPAD15( .PAD(data25), .OEN(rw_core), .I(dataout_core25), .C(datain_core25) ); PB8 UPAD16( .PAD(data24), .OEN(rw_core), .I(d
20、ataout_core24), .C(datain_core24) ); PB8 UPAD17( .PAD(data23), .OEN(rw_core), .I(dataout_core23), .C(datain_core23) ); PB8 UPAD18( .PAD(data22), .OEN(rw_core), .I(dataout_core22), .C(datain_core22) ); PB8 UPAD19( .PAD(data21), .OEN(rw_core), .I(dataout_core21), .C(datain_core21) ); PB8 UPAD20( .PAD(
21、data20), .OEN(rw_core), .I(dataout_core20), .C(datain_core20) ); PB8 UPAD21( .PAD(data19), .OEN(rw_core), .I(dataout_core19), .C(datain_core19) ); PB8 UPAD22( .PAD(data18), .OEN(rw_core), .I(dataout_core18), .C(datain_core18) ); PB8 UPAD23( .PAD(data17), .OEN(rw_core), .I(dataout_core17), .C(datain_
22、core17) ); PB8 UPAD24( .PAD(data16), .OEN(rw_core), .I(dataout_core16), .C(datain_core16) ); PB8 UPAD25( .PAD(data15), .OEN(rw_core), .I(dataout_core15), .C(datain_core15) ); PB8 UPAD26( .PAD(data14), .OEN(rw_core), .I(dataout_core14), .C(datain_core14) ); PB8 UPAD27( .PAD(data13), .OEN(rw_core), .I
23、(dataout_core13), .C(datain_core13) ); PB8 UPAD28( .PAD(data12), .OEN(rw_core), .I(dataout_core12), .C(datain_core12) ); PB8 UPAD29( .PAD(data11), .OEN(rw_core), .I(dataout_core11), .C(datain_core11) ); PB8 UPAD30( .PAD(data10), .OEN(rw_core), .I(dataout_core10), .C(datain_core10) ); PB8 UPAD31( .PA
24、D(data9), .OEN(rw_core), .I(dataout_core9), .C(datain_core9) ); PB8 UPAD32( .PAD(data8), .OEN(rw_core), .I(dataout_core8), .C(datain_core8) ); PB8 UPAD33( .PAD(data7), .OEN(rw_core), .I(dataout_core7), .C(datain_core7) ); PB8 UPAD34( .PAD(data6), .OEN(rw_core), .I(dataout_core6), .C(datain_core6) );
25、 PB8 UPAD35( .PAD(data5), .OEN(rw_core), .I(dataout_core5), .C(datain_core5) ); PB8 UPAD36( .PAD(data4), .OEN(rw_core), .I(dataout_core4), .C(datain_core4) ); PB8 UPAD37( .PAD(data3), .OEN(rw_core), .I(dataout_core3), .C(datain_core3) ); PB8 UPAD38( .PAD(data2), .OEN(rw_core), .I(dataout_core2), .C(
26、datain_core2) ); PB8 UPAD39( .PAD(data1), .OEN(rw_core), .I(dataout_core1), .C(datain_core1) ); PB8 UPAD40( .PAD(data0), .OEN(rw_core), .I(dataout_core0), .C(datain_core0) ); endif mul32 umul32(cs_core, clk_core, reset_core, rw_core, addr_core, datain_core, dataout_core, finish_core); endmodule/- 为了
27、处理反标时序信息时总线端口会被打散成单个位信号的问题(参见后面的反标部分),在外层加了一个“包裹”模块。/-ifdef POST_SIMinclude top_post.velse include top.vendif/ top_wrap : top wrap module/ port: dir : function/ cs : I : chip select, active low/ clk : I : clock/ reset : I : reset, active low/ rw : I : read(0) /write(1)/ addr: I : address bus/ data: I/O : data bus/ finish: O : finish indicatormodule top_wrap(cs, clk, reset, rw, addr, data, finish); input cs, clk, reset, rw; input 3:0 addr; inout 31:0 data; output finish; ifdef POST_SIMelse top u0(
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1