====== IC Compilerによる8ビットカウンタのレイアウト奮闘記 ======
利用したVerilog-HDLファイルは,異常なまでに単純である.
module COUNTER8( CLK, RST_N, COUNTER_OUT );
input CLK, RST_N;
output [ 7: 0] COUNTER_OUT;
reg [ 7: 0] COUNTER_OUT;
always @ ( posedge CLK or negedge RST_N ) begin
if( RST_N == 1'b0 ) begin
COUNTER_OUT <= 8'h0;
end else begin
COUNTER_OUT <= COUNTER_OUT + 8'h1;
end
end
endmodule // COUNTER8
* 以下,ふんがさんの作成したフローをベースに,多少(プロジェクト名の部分とかを変えて)利用した結果を示す.
* ちなみに,マクロの作成である.念のため.
===== セットアップ =====
* COUNTER8.tcl
lappend serach_path ./
探索パス追加.
source ./scripts/set_sz.tcl
set mw_logic0_net VSS
set mw_logic1_net VDD
ここら辺はそのまま,因みに,set_sz.tclを汎用的にするために多少改良.
==== set_sz.tcl ====
set LIB_DIR "/home/vdec/lib/fujitsu65/cs202_sc_io_lib/db"
set IO_LIB_DIR "/home/vdec/lib/fujitsu65/cs202_sc_io_lib/db"
set DW_DIR "/home/vdec/synopsys/syn-2007.12-SP3/libraries/syn"
set std_max_libs {cs202sz_uc_core_s_p125_105v.db cs202sz_uc_nscan_s_p125_105v.db}
set std_typ_libs {cs202sz_uc_core_t_p25_12v.db cs202sz_uc_nscan_t_p25_12v.db }
set std_min_libs {cs202sz_uc_core_f_m40_13v.db cs202sz_uc_nscan_f_m40_13v.db }
set search_path [concat "./ddc" "./../design" "." $LIB_DIR $IO_LIB_DIR $DW_DIR $search_path]
set link_path "*"
set iob_min_libs {cs202_io_f_m40_m_13v_36v.db }
set iob_typ_libs {cs202_io_t_p25_m_12v_33v.db }
set iob_max_libs {cs202_io_s_p125_m_105v_30v.db}
set LIB_MAX_FILE [concat $std_max_libs $iob_max_libs ]
set LIB_TYP_FILE [concat $std_typ_libs $iob_typ_libs ]
set LIB_MIN_FILE [concat $std_min_libs $iob_min_libs ]
set DW_FILE "dw_foundation.sldb"
set link_library [concat $LIB_MAX_FILE $LIB_TYP_FILE $LIB_MIN_FILE $DW_FILE {*}]
set target_library [concat $LIB_MAX_FILE $LIB_TYP_FILE $LIB_MIN_FILE ]
# set design-specefic variables
# added by Masayuki KIMURA
set design_name "COUNTER8"
set cells_name "COUNTER8"
set tech_file "./lib/f65.tf"
set ref_libs { "CS202SZ" "CS202IO" }
set vnet_files "./vnet/${design_name}.vnet"
set max_tluplus_file "./lib/tlu_plus_mfe.worst"
set min_tluplus_file "./lib/tlu_plus_mfe.best"
set itf_tech_map_file "./lib/tlu2mw.map"
set core_width 15
set core_height 15
set core_to_top 0.9
set core_to_left 0.9
set core_to_right 0.9
set core_to_bottom 0.9
define_name_rules verilog -allowed "A-Z0-9_"
* これは何?名前付けルールの設定?
===== ライブラリの作成/オープン =====
* COUNTER8.tcl
COUNTER8ライブラリを作成する.すでに作成済みで,途中経過のやつを開くのであれば,コメントアウトしている奴を使う.
create_mw_lib ${design_name} -technology ${tech_file} -mw_reference_library ${ref_libs} -open
# open_mw_lib ${design_name}
===== デザインのインポート =====
* COUNTER8.tcl
vnetファイルを取り込む.トップモジュールとしてCOUNTER8を設定.
import_designs ${vnet_files} -format verilog -top ${design_name}
{{:tapeout_enter:counter8:icc_design_import.jpg|}}
===== TLUファイル,ITFファイル,MAPファイルの設定 =====
* COUNTER8.tcl
set_tlu_plus_files -max_tluplus ${max_tluplus_file} \
-min_tluplus ${min_tluplus_file} \
-tech2itf_map ${itf_tech_map_file}
===== PG接続 =====
* COUNTER8.tcl
PowerとGourndを接続する.詳しいことはまだ調べてない.
derive_pg_connection -power_net {VDD} \
-ground_net {VSS} -power_pin {VDD} -ground_pin {VSS}
derive_pg_connection -tie -power_net VDD \
-ground_net VSS
derive_pg_connection -tie -power_net VDD \
-ground_net VSS
* なんで2回もやるんでしょう?
===== SDC読み込み =====
* COUNTER8.tcl
* SDCは,Design Compilerが出力したもの.Synopsys Design Format.クロック,遅延などの制約情報である.
* COUNTER8.sdc
###################################################################
# Created by write_sdc on Fri Apr 30 20:44:34 2010
###################################################################
set sdc_version 1.7
set_units -time ps -resistance Ohm -capacitance pF -voltage V -current mA
set_operating_conditions -max DEFAULT -max_library cs202sz_uc_core_s_p125_105v\
-min DEFAULT -min_library cs202sz_uc_core_f_m40_13v
set_max_area 0
set_max_fanout 10 [current_design]
set_load -pin_load 0 [get_ports {COUNTER_OUT[7]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[6]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[5]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[4]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[3]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[2]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[1]}]
set_load -pin_load 0 [get_ports {COUNTER_OUT[0]}]
set_ideal_network [get_ports CLK]
create_clock [get_ports CLK] -name CLK_OBJ -period 20 -waveform {0 10}
set_clock_latency -max 1 [get_clocks CLK_OBJ]
set_clock_latency -min 0 [get_clocks CLK_OBJ]
set_clock_uncertainty 1 [get_clocks CLK_OBJ]
set_clock_transition -rise 0 [get_clocks CLK_OBJ]
set_clock_transition -fall 0 [get_clocks CLK_OBJ]
set_input_delay -clock CLK_OBJ 8 [get_ports RST_N]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[7]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[6]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[5]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[4]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[3]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[2]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[1]}]
set_output_delay -clock CLK_OBJ 8 [get_ports {COUNTER_OUT[0]}]
read_sdc ./sdc/${design_name}.sdc
===== IO Constraintsの読み込み =====
* IO Constraintsは,マクロのどの位置にピンを配置するかを指定する.
* これはtdfというファイルから行う.
* COUNTER8.tdf 見た目が単純なので,すぐに分かると思う >> 初心者の方
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; ./tdf/COUNTER8.tdf
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; TOTAL : 10
;; NORTH : 0
;; SOUTH : 0
;; EAST : 8
;; WEST : 2
;;;;;;;; WEST (2) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pin "CLK" "MET2" 0.1 0.1 "RIGHT" 1
pin "RST_N" "MET2" 0.1 0.1 "RIGHT" 2
;;;;;;;; EAST (8) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pin "COUNTER_OUT[0]" "MET2" 0.1 0.1 "LEFT" 1
pin "COUNTER_OUT[1]" "MET2" 0.1 0.1 "LEFT" 2
pin "COUNTER_OUT[2]" "MET2" 0.1 0.1 "LEFT" 3
pin "COUNTER_OUT[3]" "MET2" 0.1 0.1 "LEFT" 4
pin "COUNTER_OUT[4]" "MET2" 0.1 0.1 "LEFT" 5
pin "COUNTER_OUT[5]" "MET2" 0.1 0.1 "LEFT" 6
pin "COUNTER_OUT[6]" "MET2" 0.1 0.1 "LEFT" 7
pin "COUNTER_OUT[7]" "MET2" 0.1 0.1 "LEFT" 8
read_io_constraints ./tdf/${design_name}.tdf
===== フロアプラン =====
* COUNTER8.fp
* マクロの大きさ,どこにどのピンを配置する,などの情報を元に,マクロをセットアップする.Place & Routeは,フロアプランしたマクロ内に行われる.
* これはふんがさんのフローに書いてあった命令をただ実行しただけだが,あとで調べる.
initialize_floorplan -control_type width_and_height \
-core_width ${core_width} -core_height ${core_height} \
-start_first_row -bottom_io2core ${core_to_bottom} -top_io2core ${core_to_top} \
-left_io2core ${core_to_left} -right_io2core ${core_to_right}
* フロアプランの結果
{{:tapeout_enter:counter8:icc_floorplan.jpg|}}
フロアプラン内に,tdfで指定したように,右側にCLK, RESET,左側に出力のピンが設定されている.
===== ストラップの作成 =====
* COUNTER8.strap
* ストラップは,立て方向に張るVDD, VSSのこと.
create_power_straps -direction vertical -start_at 3.6 -num_placement_strap 7 -increment_x_or_y 14.4 \
-nets {VDD VSS} -layer MET6 -width 1.8 -step 14.4 \
-extend_low_ends force_to_boundary_and_generate_pins -extend_high_ends force_to_boundary_and_generate_pins
* ちっちゃすぎて,ほとんど意味をなしていないwww
* ストラップを張った後の結果.
{{:tapeout_enter:counter8:icc_strap.jpg|}}
===== タップセルの挿入 =====
* COUNTER8.tcl
* タップセルYUZTAPを挿入する.
* タップセルとはなんの事やら分からないが,CMOS VLSI Designを読んだ感じだと,プロセスの関係上必ず入れなければならないもの?よくわからん。
add_tap_cell_array -master_cell_name ${tap_cell} -distance 36.0 \
-skip_fixed_cells false -no_tap_cell_under_layer {M1 M2} \
-left_macro_blockage_extra_tap must_insert \
-right_macro_blockage_extra_tap must_insert \
-left_boundary_extra_tap must_insert \
-right_boundary_extra_tap must_insert \
-connect_power_name {VDD} -connect_ground_name {VSS}
* タップセルを挿入した直後のレイアウト
{{:tapeout_enter:counter8:icc_insert_tap.jpg|}}
===== 配置 =====
* COUNTER8.tcl
* 配置処理である.
place_opt
* 配置結果
{{:tapeout_enter:counter8:icc_place.jpg|}}
* もう一度PG_connection
derive_pg_connection -power_net VDD \
-ground_net VSS -power_pin VDD -ground_pin VSS
derive_pg_connection -tie -power_net VDD \
-ground_net VSS
===== レールの作成 =====
* これがいわゆるレール張りである
* strapが立て方向なら,railは横方向.
* VDD, GNDの交互に張り,Cellを逆転して配置する
preroute_standard_cells -connect horizontal \
-extend_to_boundaries_and_generate_pins -port_filter_mode off \
-cell_master_filter_mode off -cell_instance_filter_mode off \
-voltage_area_filter_mode off
{{:tapeout_enter:counter8:icc_preroute.jpg|}}