• Design Compiler工具学习笔记(6)




    目录

    引言

    知识储备

    实际操作

    设计源码

    仿真源码

    VCS执行仿真

    DC 综合

    TCL编程练习






    引言

    本篇继续学习 DC的基本使用。本篇主要学习 DC 综合之后的效果分析,重点在时序分析

    前文链接:

    Design Compiler工具学习笔记(1)

    Design Compiler工具学习笔记(2)

    Design Compiler工具学习笔记(3)

    Design Compiler工具学习笔记(4)

    Design Compiler工具学习笔记(5)



    知识储备

     小数点精度位数一般为 13 (-significant_digits)

     report_timing ::仅报告最差的路径时序;

    report_timing -max_paths 2 :报告出两条最差的路径,但是这两条路径的终点不同

    report_timing -nworst 2 -max_paths 2:报告出整个设计中最差的两条路径,可以是同一个终点

     建立时间违规必须全部修改,面积违规和保持时间违规可以保留。

    出现违规时可能的情况:输入/出延迟过大,约束过紧;设计的组合逻辑部分延迟过大。

     

     

     

     

     

     

     

     

     

     

     





    实际操作

    以单比特信号以握手方式完成时钟域跨越。

    设计源码

    1. // |===================================== TOP ==============================
    2. // |Author:Xu Y. B.
    3. // |Date:2022-11-23
    4. // |Description: TOP module
    5. // | about single bit signal CDC using handshake mode
    6. // | CDC:100MHz-->50MHz
    7. // |========================================================================
    8. module TOP (
    9. // ======================= module input ports specify ==================
    10. // time domain 100MHz
    11. input I_CLK_100M,
    12. input I_RSTN_100M,
    13. // time domain 200MHz
    14. input I_CLK_50M,
    15. input I_RSTN_50M,
    16. // operate enable
    17. input I_OPR_EN,//high,start 1 CDC test
    18. // ======================= module output ports specify ==================
    19. output reg O_CDC_DONE
    20. );
    21. // ======================= module local parameters =====================
    22. // ======================= module internal signals =====================
    23. // register input signal I_OPR_EN
    24. reg [1:0] R_I_OPR_EN;
    25. wire W_I_OPR_EN_PDG;
    26. reg R_CDC_QST_100M;
    27. reg [1:0] R_CDC_QST_50M;
    28. reg R_CDC_ACK_50M;
    29. reg [1:0] R_CDC_ACK_100M;
    30. // ======================= module design logic =========================
    31. always @ (posedge I_CLK_100M)
    32. begin:pro_opr_en_reg
    33. if(~I_RSTN_100M)
    34. begin
    35. R_I_OPR_EN <= 2'b00;
    36. end
    37. else
    38. begin
    39. R_I_OPR_EN[0] <= I_OPR_EN;
    40. R_I_OPR_EN[1] <= R_I_OPR_EN[0];
    41. end
    42. end
    43. assign W_I_OPR_EN_PDG = R_I_OPR_EN[0] & (~R_I_OPR_EN[1]);
    44. always @ (posedge I_CLK_100M)
    45. begin
    46. if(~I_RSTN_100M)
    47. begin
    48. R_CDC_QST_100M <= 0;
    49. end
    50. else
    51. begin
    52. if(W_I_OPR_EN_PDG)
    53. begin
    54. R_CDC_QST_100M <= 1;
    55. end
    56. else if(R_CDC_ACK_100M[1])
    57. begin
    58. R_CDC_QST_100M <= 0;
    59. end
    60. else
    61. begin
    62. R_CDC_QST_100M <= R_CDC_QST_100M;
    63. end
    64. end
    65. end
    66. always @ (posedge I_CLK_100M)
    67. begin
    68. if(~I_RSTN_100M)
    69. begin
    70. R_CDC_ACK_100M <=2'b0;
    71. end
    72. else
    73. begin
    74. R_CDC_ACK_100M[0] <= R_CDC_ACK_50M;
    75. R_CDC_ACK_100M[1] <= R_CDC_ACK_100M[0];
    76. end
    77. end
    78. // 50M
    79. always @ (posedge I_CLK_50M)
    80. begin
    81. if(~I_RSTN_50M)
    82. begin
    83. R_CDC_ACK_50M <= 0;
    84. end
    85. else
    86. begin
    87. if(R_CDC_QST_50M[1])
    88. begin
    89. R_CDC_ACK_50M <= 1;
    90. end
    91. else
    92. begin
    93. R_CDC_ACK_50M <= 0;
    94. end
    95. end
    96. end
    97. always @ (posedge I_CLK_50M)
    98. begin
    99. if(~I_RSTN_50M)
    100. begin
    101. R_CDC_QST_50M <= 2'b00;
    102. end
    103. else
    104. begin
    105. R_CDC_QST_50M[0] <= R_CDC_QST_100M;
    106. R_CDC_QST_50M[1] <= R_CDC_QST_50M[0];
    107. end
    108. end
    109. always @ (posedge I_CLK_100M)
    110. begin
    111. if(~I_RSTN_100M)
    112. begin
    113. O_CDC_DONE <= 0;
    114. end
    115. else
    116. begin
    117. if(R_CDC_ACK_100M)
    118. begin
    119. O_CDC_DONE <= 1;
    120. end
    121. else
    122. begin
    123. O_CDC_DONE <= 0;
    124. end
    125. end
    126. end
    127. endmodule

    仿真源码

    1. // |========================== Test Bench ===========================
    2. // |Author:Xu Y. B.
    3. // |Date:2022-11-23
    4. // |Description: TOP module
    5. // | about single bit signal CDC using handshake mode
    6. // | CDC:100MHz-->50MHz
    7. // | Test Bench
    8. // |==================================================================
    9. module TB ();
    10. // time domain 100MHz
    11. reg I_CLK_100M;
    12. reg I_RSTN_100M;
    13. // time domain 200MHz
    14. reg I_CLK_50M;
    15. reg I_RSTN_50M;
    16. // operate enable
    17. reg I_OPR_EN;//high,start 1 CDC test
    18. // ======================= module output ports specify ==================
    19. wire O_CDC_DONE;
    20. // ======================= generate clocks ==============================
    21. initial I_CLK_100M = 0;
    22. always #5 I_CLK_100M = ~I_CLK_100M;
    23. initial I_CLK_50M = 0;
    24. always #10 I_CLK_50M = ~I_CLK_50M;
    25. initial
    26. begin
    27. I_RSTN_100M = 0;
    28. I_RSTN_50M = 0;
    29. I_OPR_EN = 0;
    30. #20;
    31. I_RSTN_100M = 1;
    32. #40;
    33. I_RSTN_50M = 1;
    34. #20;
    35. I_OPR_EN = 1;
    36. @(negedge O_CDC_DONE)
    37. #50;
    38. $finish;
    39. end
    40. initial
    41. begin
    42. `ifdef VPD_TEST
    43. $vcdpluson();
    44. `endif
    45. end
    46. TOP INST_TOP
    47. (
    48. .I_CLK_100M (I_CLK_100M),
    49. .I_RSTN_100M (I_RSTN_100M),
    50. .I_CLK_50M (I_CLK_50M),
    51. .I_RSTN_50M (I_RSTN_50M),
    52. .I_OPR_EN (I_OPR_EN),
    53. .O_CDC_DONE (O_CDC_DONE)
    54. );
    55. endmodule

    VCS执行仿真

    makefile 文件:

    1. # =======================================================
    2. # ========================== MAKE FILE ==================
    3. # By:Xu Y. B.
    4. # Date:2022-11-23
    5. # Note:
    6. # reuse this makefile ,the followings should be changed:
    7. # -1- OUTPUT
    8. # -2- TB file add the following:
    9. # `ifdef VPD_TEST
    10. # $vcdpluson();
    11. # `endif
    12. # =======================================================
    13. .PHONY: com cov clean debug
    14. OUTPUT = SIMV_CDC_TEST
    15. VPD_SW_DEFINE = +define+VPD_TEST
    16. # code coverage command
    17. CM = -cm line+cond+fsm+branch+tgl
    18. CM_NAME = -cm_name $(OUTPUT)
    19. CM_DIR = -cm_dir ./$(OUTPUT).vdb
    20. # vpdfile name
    21. VPD_NAME = $(OUTPUT).vpd
    22. # compile command
    23. VCS = vcs -full64 -cpp g++-4.8 -cc gcc-4.8 -LDFLAGS -Wl,--no-as-needed \
    24. -simprofile \
    25. -sverilog +v2k -timescale=1ns/1ns \
    26. -debug_access+r \
    27. -Mupdate \
    28. +notimingcheck \
    29. +nospecify \
    30. +vcs+flush+all \
    31. $(VPD_SW_DEFINE) \
    32. -o $(OUTPUT) \
    33. -l compile.log
    34. # $(CM) \
    35. # $(CM_NAME) \
    36. # $(CM_DIR)
    37. # -cm_hier ./vcs_cov.cfg
    38. # simulation command
    39. SIM = ./$(OUTPUT) \
    40. -l $(OUTPUT).log \
    41. $(CM) $(CM_NAME) $(CM_DIR) \
    42. $(VPD_NAME) \
    43. # start complie
    44. com:
    45. find -name "*.v" >filelist.f
    46. $(VCS) -f filelist.f
    47. # start simulation
    48. sim:
    49. $(SIM)
    50. mv vcdplus.vpd $(VPD_NAME)
    51. # show the coverage
    52. cov:
    53. dve -full64 -covdir *.vdb &
    54. debug:
    55. dve -full64 -vpd $(OUTPUT).vpd &
    56. # start clean
    57. clean:
    58. rm -rf ./csrc *.daidir *.log *.vpd *.vdb simv* *.key *race.out* *.so.* *profile* *.f

    DC 综合

    脚本:

    供参考~~~~~~~~~~

    1. # |===========================================================
    2. # | Author : Xu Y. B.
    3. # | Date : 2022-11-21
    4. # | Description : tcl script for top design
    5. # |===========================================================
    6. # |===========================================================
    7. # |STEP 1: Read & elaborate the RTL design file list & check
    8. # |===========================================================
    9. set TOP_MODULE CDC_TOP
    10. analyze -format verilog [list CDC_TOP.v ]
    11. elaborate $TOP_MODULE -architecture verilog
    12. current_design $TOP_MODULE
    13. if {[link] == 0} {
    14. echo "Your Link has errors !";
    15. exit;
    16. }
    17. if {[check_design] == 0} {
    18. echo "Your check design has errors !";
    19. exit;
    20. }
    21. # |===========================================================
    22. # |STEP 2: reset design
    23. # |===========================================================
    24. reset_design
    25. # |===========================================================
    26. # |STEP 3: Write unmapped ddc file
    27. # |===========================================================
    28. uniquify
    29. set uniquify_naming_style "%s_%d"
    30. write -f ddc -hierarchy -output ${UNMAPPED_PATH}/${TOP_MODULE}.ddc
    31. # |===========================================================
    32. # |STEP 4: define clocks
    33. # |===========================================================
    34. # -------------------------- CLK 100MHz ----------------------
    35. set CLK_NAME I_CLK_100M
    36. set CLK_PERIOD 10
    37. set CLK_SKEW [expr {$CLK_PERIOD*0.05}]
    38. set CLK_TRANS [expr {$CLK_PERIOD*0.01}]
    39. set CLK_SRC_LATENCY [expr {$CLK_PERIOD*0.1 }]
    40. set CLK_LATENCY [expr {$CLK_PERIOD*0.1 }]
    41. create_clock -period $CLK_PERIOD [get_ports $CLK_NAME]
    42. set_ideal_network [get_ports $CLK_NAME]
    43. set_dont_touch_network [get_ports $CLK_NAME]
    44. set_drive 0 [get_ports $CLK_NAME]
    45. set_clock_uncertainty -setup $CLK_SKEW [get_clocks $CLK_NAME]
    46. set_clock_transition -max $CLK_TRANS [get_clocks $CLK_NAME]
    47. set_clock_latency -source -max $CLK_SRC_LATENCY [get_clocks $CLK_NAME]
    48. set_clock_latency -max $CLK_LATENCY [get_clocks $CLK_NAME]
    49. # --------------------------- CLK 50MHz ----------------------
    50. set CLK_NAME_2 I_CLK_50M
    51. set CLK_PERIOD_2 20
    52. set CLK_SKEW_2 [expr {$CLK_PERIOD_2*0.05}]
    53. set CLK_TRANS_2 [expr {$CLK_PERIOD_2*0.01}]
    54. set CLK_SRC_LATENCY_2 [expr {$CLK_PERIOD_2*0.1 }]
    55. set CLK_LATENCY_2 [expr {$CLK_PERIOD_2*0.1 }]
    56. create_clock -period $CLK_PERIOD_2 [get_ports $CLK_NAME_2]
    57. set_ideal_network [get_ports $CLK_NAME_2]
    58. set_dont_touch_network [get_ports $CLK_NAME_2]
    59. set_drive 0 [get_ports $CLK_NAME_2]
    60. set_clock_uncertainty -setup $CLK_SKEW_2 [get_clocks $CLK_NAME_2]
    61. set_clock_transition -max $CLK_TRANS_2 [get_clocks $CLK_NAME_2]
    62. set_clock_latency -source -max $CLK_SRC_LATENCY_2 [get_clocks $CLK_NAME_2]
    63. set_clock_latency -max $CLK_LATENCY_2 [get_clocks $CLK_NAME_2]
    64. # |===========================================================
    65. # |STEP 5: define reset
    66. # |===========================================================
    67. # ------------------------- RST 1 ----------------------------
    68. set RST_NAME I_RSTN_100M
    69. set_ideal_network [get_ports $RST_NAME]
    70. set_dont_touch_network [get_ports $RST_NAME]
    71. set_drive 0 [get_ports $RST_NAME]
    72. # ------------------------- RST 2 ----------------------------
    73. set RST_NAME_2 I_RSTN_50M
    74. set_ideal_network [get_ports $RST_NAME_2]
    75. set_dont_touch_network [get_ports $RST_NAME_2]
    76. set_drive 0 [get_ports $RST_NAME_2]
    77. # |===========================================================
    78. # |STEP 6: set input delay using timing budget
    79. # |Assume a weak cell to drive the input pins
    80. # |===========================================================
    81. set LIB_NAME typical
    82. set WIRE_LOAD_MODEL smic18_wl10
    83. set DRIVE_CELL INVX1
    84. set DRIVE_CELL_2 INVX4
    85. set DRIVE_CELL_3 INVX8
    86. set DRIVE_PIN Y
    87. set OPERATE_CONDITION typical
    88. set INPUT_RST [get_ports I_RSTN_100M]
    89. set INPUT_RST_2 [get_ports I_RSTN_50M]
    90. set INPUT_DELAY [expr {$CLK_PERIOD*0.6}]
    91. set INPUT_DELAY_2 [expr {$CLK_PERIOD_2*0.6}]
    92. # CLK 1
    93. set_input_delay $INPUT_DELAY -clock $CLK_NAME [get_ports I_OPR_EN]
    94. set_input_delay $INPUT_DELAY -clock $CLK_NAME ${INPUT_RST}
    95. # CLK 2
    96. set_input_delay $INPUT_DELAY_2 -clock $CLK_NAME_2 ${INPUT_RST_2}
    97. # DRIVE CELL
    98. set_driving_cell -lib_cell ${DRIVE_CELL} -pin ${DRIVE_PIN} ${INPUT_RST}
    99. set_driving_cell -lib_cell ${DRIVE_CELL_2} -pin ${DRIVE_PIN} ${INPUT_RST_2}
    100. set_driving_cell -lib_cell ${DRIVE_CELL_3} -pin ${DRIVE_PIN} [get_ports I_OPR_EN]
    101. # |===========================================================
    102. # |STEP 7: set output delay
    103. # |===========================================================
    104. set OUTPUT_DELAY [expr {$CLK_PERIOD*0.6}]
    105. set MAX_LOAD [expr {[load_of $LIB_NAME/INVX4/A] * 10}]
    106. set_output_delay $OUTPUT_DELAY -clock $CLK_NAME [all_outputs]
    107. set_load [expr {$MAX_LOAD * 3}] [all_outputs]
    108. set_isolate_ports -type buffer [all_outputs]
    109. # |===========================================================
    110. # |STEP 8: set max delay for comb logic
    111. # |===========================================================
    112. # set_input_delay [expr $CLK_PERIOD * 0.1] -clock $CLK_NAME -add_delay [get_ports I_1]
    113. # set_output_delay [expr $CLK_PERIOD * 0.1] -clock $CLK_NAME -add_delay [get_ports O_1]
    114. # |===========================================================
    115. # |STEP 9: set operating condition & wire load model
    116. # |===========================================================
    117. set_operating_conditions -max $OPERATE_CONDITION \
    118. -max_library $LIB_NAME
    119. set auto_wire_load_selection false
    120. set_wire_load_mode top
    121. set_wire_load_model -name $WIRE_LOAD_MODEL \
    122. -library $LIB_NAME
    123. # |===========================================================
    124. # |STEP 10: set area constraint (Let DC try its best)
    125. # |===========================================================
    126. set_max_area 1000
    127. # |===========================================================
    128. # |STEP 11: set DRC constraint
    129. # |===========================================================
    130. # set MAX_CAPACITANCE [expr {[load_of $LIB_NAME/NAND4X2/Y] * 5}]
    131. # set_max_capacitance $MAX_CAPACITANCE $ALL_INPUT_EXCEPT_CLK
    132. # |===========================================================
    133. # |STEP 12: set group path
    134. # |Avoid getting stack on one path
    135. # |===========================================================
    136. # group_path -name $CLK_NAME -weight 5 \
    137. # -critical_range [expr {$CLK_PERIOD * 0.1}]
    138. # group_path -name INPUTS -from [all_inputs] \
    139. # -critical_range [expr {$CLK_PERIOD * 0.1}]
    140. # group_path -name OUTPUTS -to [all_outputs] \
    141. # -critical_range [expr {$CLK_PERIOD * 0.1}]
    142. # group_path -name COMBS -from [all_inputs] \
    143. # -to [all_outputs] \
    144. # -critical_range [expr {$CLK_PERIOD * 0.1}]
    145. # report_path_group
    146. # |===========================================================
    147. # |STEP 13: Elimate the multiple-port inter-connect &
    148. # | define name style
    149. # |===========================================================
    150. # set_app_var verilogout_no_tri true
    151. # set_app_var verilogout_show_unconnected_pins true
    152. # set_app_var bus_naming_style {%s[%d]}
    153. # simplify_constants -boundary_optimization
    154. # set_boundary_optimization [current_design] true
    155. # set_fix_multiple_port_nets -all -buffer_constants
    156. # |===========================================================
    157. # |STEP 14: timing exception define
    158. # |===========================================================
    159. # set_false_path -from [get_clocks I_CLK_100M] -to [get_clocks I_CLK_100M]
    160. # set ALL_CLKS [all_clocks]
    161. # foreach_in_collection CUR_CLK $ALL_CLKS
    162. # {
    163. # set OTHER_CLKS [remove_from_collection [all_clocks] $CUR_CLK]
    164. # set_false_path -from $CUR_CLK $OTHER_CLKS
    165. # }
    166. # set_false_path -from [get_clocks I_CLK_100M] -to [get_clocks I_CLK_100M]
    167. # set_false_path -from [get_clocks I_CLK_100M] -to [get_clocks I_CLK_100M]
    168. # set_disable_timing TOP/U1 -from a -to y
    169. # set_case_analysis 0 [get_ports sel_i]
    170. # set_multicycle_path -setup 6 -from FFA/CP -through ADD/out -to FFB/D
    171. # set_multicycle_path -hold 5 -from FFA/CP -through ADD/out -to FFB/D
    172. # set_multicycle_path -setup 2 -to FFB/D
    173. # set_multicycle_path -hold 1 -to FFB/D
    174. # |===========================================================
    175. # |STEP 15: compile flow
    176. # |===========================================================
    177. # ungroup -flatten -all
    178. # 1st-pass compile
    179. # compile -map_effort high -area_effort high
    180. # compile -map_effort high -area_effort high -boundary_optimization
    181. compile
    182. # simplify_constants -boundary_optimization
    183. # set_fix_multiple_port_nets -all -buffer_constants
    184. # compile -map_effort high -area_effort high -incremental_mapping -scan
    185. # 2nd-pass compile
    186. # compile -map_effort high -area_effort high -incremental_mapping -boundary_optimization
    187. # compile_ultra -incr
    188. # |===========================================================
    189. # |STEP 16: write post-process files
    190. # |===========================================================
    191. # change_names -rules verilog -hierarchy
    192. # remove-unconnected_ports [get_cells -hier *] -blast_buses
    193. # Write the mapped files
    194. write -f ddc -hierarchy -output $MAPPED_PATH/${TOP_MODULE}.ddc
    195. # write -f verilog -hierarchy -output $MAPPED_PATH/${TOP_MODULE}.v
    196. # write_sdc -version 1.7 $MAPPED_PATH/${TOP_MODULE}.sdc
    197. # write_sdf -version 2.1 $MAPPED_PATH/${TOP_MODULE}.sdf
    198. # |===========================================================
    199. # |STEP 17: generate report files
    200. # |===========================================================

    在完成编译之后可以用本篇的PPT里面介绍的 时序报告指令进行时序分析。此处不再赘述。

    TCL编程练习

    1. # |================================= Tcl coding practice ===========================
    2. # |Coded by:Xu Y. B.
    3. # |Date:2022-11-25
    4. # |Description:basic Tcl syntax
    5. # |=================================================================================
    6. # ******** example :define your variable
    7. set FILE_NAME Sample_Test
    8. set VAR_1 0
    9. # ******** example :if-else
    10. if {$VAR_1 == 0} {
    11. echo "Your variable VAR_1 is 0"
    12. } else {
    13. echo "Your variable VAR_1 is not 0"
    14. }
    15. # ******** example :switch
    16. switch -regexp $FILE_NAME {
    17. "Sample_Test" {
    18. echo "The File is Right"
    19. }
    20. "Test" {
    21. echo "The File is others"
    22. }
    23. default {
    24. echo "The File is nothing !"
    25. }
    26. }
    27. # ********* example :while
    28. set i 1
    29. while {$i <= 10} {
    30. echo "i = $i";
    31. incr i 1;
    32. }
    33. # ********* example :for
    34. for {set i_a 0} {$i_a <= 20} {incr i_a 2} {
    35. if {$i_a == 4 || $i_a == 18} {
    36. continue;
    37. # break;
    38. }
    39. echo "i_a = $i_a";
    40. }
    41. # ********* example :foreach
    42. # example 1
    43. set MY_LIST [list "Xu Y. B." "is" 23 "years" "old"]
    44. foreach MY_LIST $MY_LIST {
    45. switch -regexp $MY_LIST {
    46. "Xu Y. B." {
    47. echo "$MY_LIST is a name"
    48. }
    49. 23 {
    50. echo "$MY_LIST is a number"
    51. }
    52. default {
    53. echo "$MY_LIST"
    54. }
    55. }
    56. }
    57. # example 2
    58. set log_file_cnt 0
    59. set v_file_cnt 0
    60. set tcl_file_cnt 0
    61. set my_file_list [glob *.log *.v *.tcl]
    62. foreach f_name $my_file_list {
    63. set f_ext [file extension $f_name]
    64. switch $f_ext {
    65. ".log" {
    66. incr log_file_cnt
    67. }
    68. ".v" {
    69. incr v_file_cnt
    70. }
    71. ".tcl" {
    72. incr tcl_file_cnt
    73. }
    74. }
    75. }
    76. echo "The current folder contains totally .log file number is $log_file_cnt";
    77. echo "The current folder contains totally .v file number is $v_file_cnt"
    78. echo "The current folder contains totally .tcl file number is $tcl_file_cnt"
    79. # ********** example :Write something to a file
    80. set TEXT_W "Xu Y. B. is my name"
    81. set FILE_ID_W [open TEST.txt w+]
    82. puts $FILE_ID_W $TEXT_W
    83. flush $FILE_ID_W
    84. close $FILE_ID_W
    85. # ********** example :Read something from a file
    86. set TEXT_R ""
    87. set FILE_ID_R [open TEST.txt r]
    88. gets $FILE_ID_R TEXT_R
    89. echo "\" $TEXT_R \"is read from file id $FILE_ID_R"
    90. close $FILE_ID_R
    91. # ********** example :proc
    92. # example 1:
    93. set NAME "Xu Y. B."
    94. proc my_print_var {var_name} \
    95. {
    96. global NAME
    97. echo "var_name is \" $var_name \""
    98. echo "var_name is \" $NAME \""
    99. }
    100. my_print_var NAME
    101. # example 2:
    102. proc min {a b c d} \
    103. {
    104. if {$a >= $b} {
    105. set y $b;
    106. } else {
    107. set y $a;
    108. }
    109. if {$c >= $d} {
    110. set z $d;
    111. } else {
    112. set z $c;
    113. }
    114. if {$y >= $z} {
    115. set w $z;
    116. } else {
    117. set w $y
    118. }
    119. return $w;
    120. }
    121. # min 11 21 3 4
    122. # example 3 :
    123. proc sum {args} \
    124. {
    125. set num_list $args
    126. set sum 0
    127. foreach num $num_list {
    128. set sum [expr ($sum + $num)]
    129. }
    130. return $sum
    131. }
    132. # sum 1 2 3 4
    133. # example 4 :
    134. # array set PORTS [list I_CLK 3 I_RSTN 4 I_DATA 5 O_DATA 6]
    135. set PORTS {I_CLK 12 I_RSTN 4 I_DATA 5 O_DATA 6}
    136. proc inc_port {port_num_list} \
    137. {
    138. array set PORTS_1 $port_num_list
    139. set port_list [array names PORTS_1]
    140. foreach port $port_list {
    141. incr PORTS_1($port) 20
    142. }
    143. return [array get PORTS_1]
    144. }
    145. # inc_port $PORTS
    146. # example 5 :
    147. # create a link to the variable outside
    148. set NUMBER 0
    149. proc incr_ten {num} {
    150. upvar $num local_var
    151. incr local_var 10
    152. }
    153. incr_ten $NUMBER

  • 相关阅读:
    Codeforces Round #817 (Div. 4)(6/7)
    【C】指针进阶(下)
    SwiftUI 视图“毁坏性”和“非毁坏性”刷新的应用场景
    备忘录模式
    windows10下whisper的安装使用和CUDA的配置
    高等数学啃书汇总重难点(七)微分方程
    第八章 排序 十、基数排序
    Linux—磁盘管理
    前端框架Vue语法部分(一)
    达人评测 i7 12800hx和i9 12900h选哪个好
  • 原文地址:https://blog.csdn.net/qq_43045275/article/details/128007054