tcl里如何定义函数(二):任意个数参数
专栏:iLoveIC Sept. 6, 2025, 6:42 p.m. 8 阅读
本文介绍tcl里函数传入任意个数参数的方法

我们知道dc里,命令read_file的输入参数相当灵活,有yes/no型的(如-autoread、-rtl),也有指定类别传参数的(如-format、-define、-top),还有直接传的(如file_list)。

dc_shell> read_file -help
Usage: read_file
    [-autoread]
    [-format format_name]
    [-define macro_names]
    [-rtl]
    [-top top]
    ...
    [file_list]

那么我们tcl里怎么定义一个函数支持同样的参数输入呢?要实现这个功能,就要说到一个特殊参数args,这个args是把所有的参数拼成一个列表传入。

下面是一个仿写的例子,定义了特殊参数args,用for循环把这个参数列表逐个打印出来。

proc read_file {args} {
    set num [llength $args]
    for {set i 0} {$i < $num} {incr i} {
	 set arg [lindex $args $i]
        puts "$i: $arg"
    }
}
read_file -autoread -format verilog -define A=1 -rtl -top digital_top {../rtl/a.v ../rtl/b.v ../rtl/c.v}
# 输出log
0: -autoread
1: -format
2: verilog
3: -define
4: A=1
5: -rtl
6: -top
7: digital_top
8: ../rtl/a.v ../rtl/b.v ../rtl/c.v

虽然打印出来了,但还是显得有些乱,并没有按含义进行处理。所以我们需要在函数里进一步解析参数,最终存放到一个字典里。解析过程如下:

proc read_file {args} {
    set options {}
    set file_list ""
    set num [llength $args]
    for {set i 0} {$i < $num} {incr i} {
        set arg [lindex $args $i]
        if {$arg == "-autoread"} {
            dict append options "autoread" true
        } elseif {$arg == "-format"} {
            dict append options "format" [lindex $args [expr $i + 1]]
            incr i
        } elseif {$arg == "-define"} {
            dict append options "define" [lindex $args [expr $i + 1]]
            incr i
        } elseif {$arg == "-rtl"} {
            dict append options "rtl" true
        } elseif {$arg == "-top"} {
            dict append options "top" [lindex $args [expr $i + 1]]
            incr i
        } else {
            lappend file_list $arg
        }
    }
    
    foreach key [dict keys $options] {
        set val [dict get $options $key]
        puts "$key: $val"
    }
    puts $file_list
}
read_file -autoread -format verilog -define A=1 -rtl -top digital_top {../rtl/a.v ../rtl/b.v ../rtl/c.v}
# 输出log
autoread: true
format: verilog
define: A=1
rtl: true
top: digital_top
{../rtl/a.v ../rtl/b.v ../rtl/c.v}

这样模仿的read_file参数定义就实现了。在使用时,可以用dict exists $dictname keyname判断参数是否存在,再做进一步处理。这种定义函数参数的方法比较灵活,也不用太关注参数的顺序。

 

感谢阅读,更多文章点击这里:【专栏:iLoveIC】
最新20篇 开设专栏